Skip to content

Commit

Permalink
Allow skipped columns and empty columns for iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov committed Apr 7, 2024
1 parent 6da3491 commit 499972a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 10 deletions.
20 changes: 12 additions & 8 deletions src/QueryBuilder/AbstractDMLQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ public function batchInsert(string $table, array $columns, iterable $rows, array
return '';
}

while ($rows instanceof IteratorAggregate) {
$rows = $rows->getIterator();
}

if ($rows instanceof Iterator && !$rows->valid()) {
return '';
}

$columns = $this->extractColumnNames($rows, $columns);
$values = $this->prepareBatchInsertValues($table, $rows, $columns, $params);

Expand Down Expand Up @@ -149,11 +157,12 @@ protected function prepareBatchInsertValues(string $table, iterable $rows, array
/** @var string[] $columnNames */
$columnNames = array_values($columns);
$columnKeys = array_combine($columnNames, $columnNames);
$columnNulls = array_fill_keys($columnNames, 'NULL');
$columnSchemas = $this->schema->getTableSchema($table)?->getColumns() ?? [];

foreach ($rows as $row) {
$i = 0;
$placeholders = $columnKeys;
$placeholders = $columnNulls;

/** @var int|string $key */
foreach ($row as $key => $value) {
Expand Down Expand Up @@ -181,27 +190,22 @@ protected function prepareBatchInsertValues(string $table, iterable $rows, array
/**
* Extract column names from columns and rows.
*
* @param iterable $rows The rows to be batch inserted into the table.
* @param array[]|Iterator $rows The rows to be batch inserted into the table.
* @param string[] $columns The column names.
*
* @return string[] The column names.
*/
protected function extractColumnNames(iterable $rows, array $columns): array
protected function extractColumnNames(array|Iterator $rows, array $columns): array
{
$columns = $this->getNormalizeColumnNames('', $columns);

if (!empty($columns)) {
return $columns;
}

while ($rows instanceof IteratorAggregate && !$rows instanceof Iterator) {
$rows = $rows->getIterator();
}

if ($rows instanceof Iterator) {
$row = $rows->current();
} else {
/** @var array[] $rows */
$row = reset($rows);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Common/CommonCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ public function testAddUnique(string $name, string $tableName, array|string $col
public function testBatchInsert(
string $table,
array $columns,
array $values,
iterable $values,
string $expected,
array $expectedParams = [],
int $insertedRow = 1
Expand Down
26 changes: 25 additions & 1 deletion tests/Provider/CommandProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace Yiisoft\Db\Tests\Provider;

use ArrayIterator;
use IteratorAggregate;
use Traversable;
use Yiisoft\Db\Command\DataType;
use Yiisoft\Db\Command\Param;
use Yiisoft\Db\Expression\Expression;
Expand Down Expand Up @@ -462,7 +464,7 @@ public static function batchInsert(): array
':qp3' => true,
],
],
'empty columns and Traversable' => [
'empty columns and a Traversable value' => [
'type',
[],
'values' => [new ArrayIterator(['int_col' => '1.0', 'float_col' => '2', 'char_col' => 10, 'bool_col' => 1])],
Expand All @@ -479,6 +481,28 @@ public static function batchInsert(): array
':qp3' => true,
],
],
'empty columns and Traversable values' => [
'type',
[],
'values' => new class implements IteratorAggregate {
public function getIterator(): Traversable
{
yield ['int_col' => '1.0', 'float_col' => '2', 'char_col' => 10, 'bool_col' => 1];
}
},
'expected' => DbHelper::replaceQuotes(
<<<SQL
INSERT INTO [[type]] ([[int_col]], [[float_col]], [[char_col]], [[bool_col]]) VALUES (:qp0, :qp1, :qp2, :qp3)
SQL,
static::$driverName,
),
'expectedParams' => [
':qp0' => 1,
':qp1' => 2.0,
':qp2' => '10',
':qp3' => true,
],
],
];
}

Expand Down
12 changes: 12 additions & 0 deletions tests/Provider/QueryBuilderProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,18 @@ public static function batchInsert(): array
':qp3' => 1,
],
],
'skipped columns' => [
'customer',
['email', 'name', 'address'],
'values' => [['email' => 'hello@localhost', 'address' => 'Earth, Solar System']],
'expected' => DbHelper::replaceQuotes(
<<<SQL
INSERT INTO [[customer]] ([[email]], [[name]], [[address]]) VALUES (:qp0, NULL, :qp1)
SQL,
static::$driverName,
),
'expectedParams' => [':qp0' => 'hello@localhost', ':qp1' => 'Earth, Solar System'],
],
];
}

Expand Down

0 comments on commit 499972a

Please sign in to comment.