diff --git a/src/QueryBuilder/AbstractDMLQueryBuilder.php b/src/QueryBuilder/AbstractDMLQueryBuilder.php index 40809c8ae..a8d0a7916 100644 --- a/src/QueryBuilder/AbstractDMLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDMLQueryBuilder.php @@ -22,6 +22,7 @@ use function array_combine; use function array_diff; +use function array_fill_keys; use function array_filter; use function array_key_exists; use function array_keys; @@ -63,15 +64,11 @@ public function __construct( public function batchInsert(string $table, array $columns, iterable $rows, array &$params = []): string { - if (empty($rows)) { - return ''; - } - - while ($rows instanceof IteratorAggregate) { - $rows = $rows->getIterator(); + if (!is_array($rows)) { + $rows = $this->prepareTraversable($rows); } - if ($rows instanceof Iterator && !$rows->valid()) { + if (empty($rows)) { return ''; } @@ -139,6 +136,26 @@ public function upsert( throw new NotSupportedException(__METHOD__ . ' is not supported by this DBMS.'); } + /** + * Prepare traversable for batch insert. + * + * @param Traversable $rows The rows to be batch inserted into the table. + * + * @return Iterator|array The prepared rows. + */ + protected function prepareTraversable(Traversable $rows): Iterator|array + { + while ($rows instanceof IteratorAggregate) { + $rows = $rows->getIterator(); + } + + if ($rows instanceof Iterator && !$rows->valid()) { + return []; + } + + return $rows; + } + /** * Prepare values for batch insert. * @@ -156,17 +173,16 @@ protected function prepareBatchInsertValues(string $table, iterable $rows, array $values = []; /** @var string[] $columnNames */ $columnNames = array_values($columns); - $columnKeys = array_combine($columnNames, $columnNames); - $columnNulls = array_fill_keys($columnNames, 'NULL'); + $columnKeys = array_fill_keys($columnNames, false); $columnSchemas = $this->schema->getTableSchema($table)?->getColumns() ?? []; foreach ($rows as $row) { $i = 0; - $placeholders = $columnNulls; + $placeholders = $columnKeys; /** @var int|string $key */ foreach ($row as $key => $value) { - $columnName = $columns[$key] ?? $columnKeys[$key] ?? $columnNames[$i] ?? $i; + $columnName = $columns[$key] ?? (isset($columnKeys[$key]) ? $key : $columnNames[$i] ?? $i); if (isset($columnSchemas[$columnName])) { $value = $columnSchemas[$columnName]->dbTypecast($value); diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 2300425dd..f8f0b5356 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -255,18 +255,6 @@ public static function batchInsert(): array ':qp3' => 1, ], ], - 'skipped columns' => [ - 'customer', - ['email', 'name', 'address'], - 'values' => [['email' => 'hello@localhost', 'address' => 'Earth, Solar System']], - 'expected' => DbHelper::replaceQuotes( - << [':qp0' => 'hello@localhost', ':qp1' => 'Earth, Solar System'], - ], ]; }