diff --git a/src/DataService.php b/src/DataService.php index 2561ea0..c9b9629 100644 --- a/src/DataService.php +++ b/src/DataService.php @@ -239,76 +239,107 @@ class DataService return ['deleted' => $stmt->rowCount()]; } - public function insertMultipleRows(string $schema, string $table, array $rows, array $columns): array - { - if (empty($rows)) { - return ['inserted' => 0, 'errors' => 0, 'message' => 'No rows provided']; +public function insertMultipleRows(string $schema, string $table, array $rows, array $columns): array +{ + if (empty($rows)) { + return ['inserted' => 0, 'errors' => 0, 'message' => 'No rows provided']; + } + + $inserted = 0; + $errors = 0; + $errorMessages = []; + + // ✅ Собираем информацию о всех столбцах таблицы + $validColumns = []; + foreach ($columns as $c) { + $name = $c['COLUMN_NAME']; + $extra = $c['EXTRA'] ?? ''; + + // Пропускаем только auto_increment поля + if (!str_contains($extra, 'auto_increment')) { + $validColumns[$name] = [ + 'nullable' => $c['IS_NULLABLE'] ?? false, + 'has_default' => !empty($c['COLUMN_DEFAULT']) || $c['COLUMN_DEFAULT'] === '0', + 'default' => $c['COLUMN_DEFAULT'] ?? null + ]; } + } - $inserted = 0; - $errors = 0; - $errorMessages = []; + $this->pdo->beginTransaction(); - $validColumns = []; - foreach ($columns as $c) { - $name = $c['COLUMN_NAME']; - $extra = $c['EXTRA'] ?? ''; - - if (!str_contains($extra, 'auto_increment')) { - $validColumns[] = $name; - } - } + try { + foreach ($rows as $index => $row) { + try { + $insertCols = []; + $placeholders = []; + $params = []; - $this->pdo->beginTransaction(); - - try { - foreach ($rows as $index => $row) { - try { - $insertCols = []; - $placeholders = []; - $params = []; - - foreach ($validColumns as $name) { - if (array_key_exists($name, $row)) { - $insertCols[] = "`$name`"; - $placeholders[] = ":$name"; - $params[":$name"] = $row[$name]; + // ✅ Перебираем ВСЕ столбцы таблицы (кроме auto_increment) + foreach ($validColumns as $name => $info) { + $value = null; + + // Если столбец есть в CSV строке + if (array_key_exists($name, $row)) { + $value = $row[$name]; + + // ✅ Обрабатываем "NULL" как NULL + if (in_array($value, ['NULL', 'null', ''], true)) { + $value = null; + } + } else { + // ✅ Столбца нет в CSV - устанавливаем NULL или пропускаем + // Если поле имеет значение по умолчанию - пропускаем (БД сама подставит) + if ($info['has_default']) { + continue; + } + // Если поле nullable - ставим NULL + if ($info['nullable']) { + $value = null; + } else { + // Поле обязательное и нет дефолта - ошибка + throw new \PDOException("Missing required field: $name"); } } - - if (empty($insertCols)) { - continue; - } - - $sql = sprintf( - "INSERT INTO `%s`.`%s` (%s) VALUES (%s)", - $schema, $table, - implode(',', $insertCols), - implode(',', $placeholders) - ); - $stmt = $this->pdo->prepare($sql); - $stmt->execute($params); - $inserted++; - } catch (\PDOException $e) { - $errors++; - $errorMessages[] = "Строка " . ($index + 1) . ": " . $this->formatPDOError($e, $schema, $table); + $insertCols[] = "`$name`"; + $placeholders[] = ":$name"; + $params[":$name"] = $value; } - } - $this->pdo->commit(); - } catch (\Exception $e) { - $this->pdo->rollBack(); - throw new \RuntimeException('Import failed: ' . $e->getMessage()); + if (empty($insertCols)) { + continue; + } + + $sql = sprintf( + "INSERT INTO `%s`.`%s` (%s) VALUES (%s)", + $schema, $table, + implode(',', $insertCols), + implode(',', $placeholders) + ); + + $stmt = $this->pdo->prepare($sql); + $stmt->execute($params); + $inserted++; + } catch (\PDOException $e) { + $errors++; + $errorMessages[] = "Строка " . ($index + 1) . ": " . $this->formatPDOError($e, $schema, $table); + } } - return [ - 'inserted' => $inserted, - 'errors' => $errors, - 'errorMessages' => $errorMessages - ]; + $this->pdo->commit(); + } catch (\Exception $e) { + $this->pdo->rollBack(); + throw new \RuntimeException('Import failed: ' . $e->getMessage()); } + return [ + 'inserted' => $inserted, + 'errors' => $errors, + 'errorMessages' => $errorMessages + ]; +} + + public function exportCSV( string $schema, string $table,