From 5f42388ca67ff5f55905e6335134f67829ecf33a Mon Sep 17 00:00:00 2001 From: Tigrov Date: Thu, 4 Jan 2024 06:34:41 +0700 Subject: [PATCH 1/7] Update tests according to main PR --- tests/Support/Fixture/oci.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Support/Fixture/oci.sql b/tests/Support/Fixture/oci.sql index 06409e6..9c9bc25 100644 --- a/tests/Support/Fixture/oci.sql +++ b/tests/Support/Fixture/oci.sql @@ -163,16 +163,16 @@ CREATE TABLE "negative_default_values" ( CREATE TABLE "type" ( "int_col" integer NOT NULL, + "float_col" double precision NOT NULL, + "char_col" char(100) NOT NULL, + "blob_col" blob DEFAULT NULL, "int_col2" integer DEFAULT 1, "tinyint_col" number(3) DEFAULT 1, "smallint_col" smallint DEFAULT 1, - "char_col" char(100) NOT NULL, "char_col2" varchar2(100) DEFAULT 'some''thing', "char_col3" varchar2(4000), "nvarchar_col" nvarchar2(100) DEFAULT '', - "float_col" double precision NOT NULL, "float_col2" double precision DEFAULT 1.23, - "blob_col" blob DEFAULT NULL, "numeric_col" decimal(5,2) DEFAULT 33.22, "timestamp_col" timestamp DEFAULT to_timestamp('2002-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') NOT NULL, "time_col" interval day (0) to second(0) DEFAULT INTERVAL '0 10:33:21' DAY(0) TO SECOND(0), From 1e4a62d2e9878b90921ec992a7b06daa96dff632 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Thu, 4 Jan 2024 07:05:18 +0700 Subject: [PATCH 2/7] Update `batchInsert()`` according to main PR --- src/DMLQueryBuilder.php | 45 ++++++++++------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index 4df2fe5..9f8c1ba 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -35,47 +35,24 @@ public function batchInsert(string $table, array $columns, iterable $rows, array return ''; } - $values = []; - $columns = $this->getNormalizeColumnNames('', $columns); - $columnNames = array_values($columns); - $columnKeys = array_fill_keys($columnNames, false); $columnSchemas = $this->schema->getTableSchema($table)?->getColumns() ?? []; - - foreach ($rows as $row) { - $i = 0; - $placeholders = $columnKeys; - - foreach ($row as $key => $value) { - /** @psalm-suppress MixedArrayTypeCoercion */ - $columnName = $columns[$key] ?? (isset($columnKeys[$key]) ? $key : $columnNames[$i] ?? $i); - /** @psalm-suppress MixedArrayTypeCoercion */ - if (isset($columnSchemas[$columnName])) { - $value = $columnSchemas[$columnName]->dbTypecast($value); - } - - if ($value instanceof ExpressionInterface) { - $placeholders[$columnName] = $this->queryBuilder->buildExpression($value, $params); - } else { - $placeholders[$columnName] = $this->queryBuilder->bindParam($value, $params); - } - - ++$i; - } - - $values[] = '(' . implode(', ', $placeholders) . ')'; - } + $columns = $this->extractColumnNames($columns, $columnSchemas, $rows); + $values = $this->prepareBatchInsertValues($columns, $columnSchemas, $rows, $params); if (empty($values)) { return ''; } - $columnNames = array_map( - [$this->quoter, 'quoteColumnName'], - $columnNames, - ); + $tableAndColumns = ' INTO ' . $this->quoter->quoteTableName($table); + + if (count($columns) > 0) { + $quotedColumnNames = array_map( + [$this->quoter, 'quoteColumnName'], + $columns, + ); - $tableAndColumns = ' INTO ' . $this->quoter->quoteTableName($table) - . ' (' . implode(', ', $columnNames) . ') VALUES '; + $tableAndColumns .= ' (' . implode(', ', $quotedColumnNames) . ') VALUES '; + } return 'INSERT ALL ' . $tableAndColumns . implode($tableAndColumns, $values) . ' SELECT 1 FROM SYS.DUAL'; } From 25bb9a86215382707395ebb8faf13b41b04e26e3 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Thu, 4 Jan 2024 00:05:41 +0000 Subject: [PATCH 3/7] Apply fixes from StyleCI --- src/DMLQueryBuilder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index 9f8c1ba..1918ef1 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -10,7 +10,6 @@ use Yiisoft\Db\Exception\InvalidConfigException; use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Expression\Expression; -use Yiisoft\Db\Expression\ExpressionInterface; use Yiisoft\Db\Query\QueryInterface; use Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder; From c0aabf396894ff280ec8a05069282fde6249a351 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Thu, 4 Jan 2024 08:01:13 +0700 Subject: [PATCH 4/7] Fix test issues --- src/DMLQueryBuilder.php | 6 ++++-- tests/Provider/CommandProvider.php | 14 +++++++++++++- tests/Provider/QueryBuilderProvider.php | 3 ++- tests/Support/Fixture/oci.sql | 4 ++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index 1918ef1..79e74a9 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -50,10 +50,12 @@ public function batchInsert(string $table, array $columns, iterable $rows, array $columns, ); - $tableAndColumns .= ' (' . implode(', ', $quotedColumnNames) . ') VALUES '; + $tableAndColumns .= ' (' . implode(', ', $quotedColumnNames) . ')'; } - return 'INSERT ALL ' . $tableAndColumns . implode($tableAndColumns, $values) . ' SELECT 1 FROM SYS.DUAL'; + $tableAndColumns .= ' VALUES '; + + return 'INSERT ALL' . $tableAndColumns . implode($tableAndColumns, $values) . ' SELECT 1 FROM SYS.DUAL'; } /** diff --git a/tests/Provider/CommandProvider.php b/tests/Provider/CommandProvider.php index d97a322..fc5f76a 100644 --- a/tests/Provider/CommandProvider.php +++ b/tests/Provider/CommandProvider.php @@ -25,7 +25,7 @@ public static function batchInsert(): array $batchInsert = parent::batchInsert(); $batchInsert['multirow']['expected'] = << [ ':qp0' => '1', ], + 'empty columns and associative values' => [ + ':qp3' => '1', + ], + 'empty columns and objects' => [ + ':qp3' => '1', + ], + 'empty columns and Traversable' => [ + ':qp3' => '1', + ], + 'empty columns and indexed values' => [ + ':qp3' => '1', + ], ]; foreach ($replaceParams as $key => $expectedParams) { diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 9a38538..94e7332 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -51,11 +51,12 @@ public static function batchInsert(): array DbHelper::changeSqlForOracleBatchInsert($batchInsert['bool-false, bool2-null']['expected']); $batchInsert['wrong']['expected'] = << Date: Sat, 6 Jan 2024 19:34:10 +0700 Subject: [PATCH 5/7] Improve --- src/DMLQueryBuilder.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index 79e74a9..7950dc3 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -34,9 +34,8 @@ public function batchInsert(string $table, array $columns, iterable $rows, array return ''; } - $columnSchemas = $this->schema->getTableSchema($table)?->getColumns() ?? []; - $columns = $this->extractColumnNames($columns, $columnSchemas, $rows); - $values = $this->prepareBatchInsertValues($columns, $columnSchemas, $rows, $params); + $columns = $this->extractColumnNames($table, $rows, $columns); + $values = $this->prepareBatchInsertValues($table, $rows, $columns, $params); if (empty($values)) { return ''; @@ -45,10 +44,7 @@ public function batchInsert(string $table, array $columns, iterable $rows, array $tableAndColumns = ' INTO ' . $this->quoter->quoteTableName($table); if (count($columns) > 0) { - $quotedColumnNames = array_map( - [$this->quoter, 'quoteColumnName'], - $columns, - ); + $quotedColumnNames = array_map([$this->quoter, 'quoteColumnName'], $columns); $tableAndColumns .= ' (' . implode(', ', $quotedColumnNames) . ')'; } From 0793d12fe21f08324e5433eb6b633dfbc4847c4b Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sun, 7 Jan 2024 15:47:36 +0700 Subject: [PATCH 6/7] Remove type casting for values without column names --- src/DMLQueryBuilder.php | 2 +- tests/Provider/CommandProvider.php | 3 --- tests/Support/Fixture/oci.sql | 6 +++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index 7950dc3..077954c 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -34,7 +34,7 @@ public function batchInsert(string $table, array $columns, iterable $rows, array return ''; } - $columns = $this->extractColumnNames($table, $rows, $columns); + $columns = $this->extractColumnNames($rows, $columns); $values = $this->prepareBatchInsertValues($table, $rows, $columns, $params); if (empty($values)) { diff --git a/tests/Provider/CommandProvider.php b/tests/Provider/CommandProvider.php index fc5f76a..2b44353 100644 --- a/tests/Provider/CommandProvider.php +++ b/tests/Provider/CommandProvider.php @@ -64,9 +64,6 @@ public static function batchInsert(): array 'empty columns and Traversable' => [ ':qp3' => '1', ], - 'empty columns and indexed values' => [ - ':qp3' => '1', - ], ]; foreach ($replaceParams as $key => $expectedParams) { diff --git a/tests/Support/Fixture/oci.sql b/tests/Support/Fixture/oci.sql index 2c50c2d..06409e6 100644 --- a/tests/Support/Fixture/oci.sql +++ b/tests/Support/Fixture/oci.sql @@ -163,21 +163,21 @@ CREATE TABLE "negative_default_values" ( CREATE TABLE "type" ( "int_col" integer NOT NULL, - "float_col" double precision NOT NULL, - "char_col" char(100) NOT NULL, - "bool_col" char NOT NULL check ("bool_col" in (0,1)), "int_col2" integer DEFAULT 1, "tinyint_col" number(3) DEFAULT 1, "smallint_col" smallint DEFAULT 1, + "char_col" char(100) NOT NULL, "char_col2" varchar2(100) DEFAULT 'some''thing', "char_col3" varchar2(4000), "nvarchar_col" nvarchar2(100) DEFAULT '', + "float_col" double precision NOT NULL, "float_col2" double precision DEFAULT 1.23, "blob_col" blob DEFAULT NULL, "numeric_col" decimal(5,2) DEFAULT 33.22, "timestamp_col" timestamp DEFAULT to_timestamp('2002-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') NOT NULL, "time_col" interval day (0) to second(0) DEFAULT INTERVAL '0 10:33:21' DAY(0) TO SECOND(0), "interval_day_col" interval day (1) to second(0) DEFAULT INTERVAL '2 04:56:12' DAY(1) TO SECOND(0), + "bool_col" char NOT NULL check ("bool_col" in (0,1)), "bool_col2" char DEFAULT 1 check("bool_col2" in (0,1)), "ts_default" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, "bit_col" number(3) DEFAULT 130 NOT NULL From 15497bb976da9976ac685c1595fe610b465d213c Mon Sep 17 00:00:00 2001 From: Tigrov Date: Mon, 8 Jan 2024 18:00:06 +0700 Subject: [PATCH 7/7] Add line to CHANGELOG.md [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffe011f..cff751e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Enh #248: Change property `Schema::$typeMap` to constant `Schema::TYPE_MAP` (@Tigrov) - Bug #250: Fix `Command::insertWithReturningPks()` method for table without primary keys (@Tigrov) +- Enh #251: Allow to use `DMLQueryBuilderInterface::batchInsert()` method with empty columns (@Tigrov) ## 1.2.0 November 12, 2023