From c846471a9c6980e9d5ddc2c1a828d30972910e1d Mon Sep 17 00:00:00 2001 From: Rustam Date: Mon, 18 Aug 2025 14:43:29 +0500 Subject: [PATCH 01/16] Add ability to pass `FROM` clause to `UPDATE` command --- src/Command/AbstractCommand.php | 9 +++++++- src/Command/CommandInterface.php | 8 ++++++- src/Debug/CommandInterfaceProxy.php | 9 +++++++- src/QueryBuilder/AbstractDMLQueryBuilder.php | 23 +++++++++++++++++-- src/QueryBuilder/AbstractQueryBuilder.php | 9 ++++++-- src/QueryBuilder/DMLQueryBuilderInterface.php | 9 +++++++- 6 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/Command/AbstractCommand.php b/src/Command/AbstractCommand.php index b7d10967d..72eeb2ae7 100644 --- a/src/Command/AbstractCommand.php +++ b/src/Command/AbstractCommand.php @@ -8,6 +8,7 @@ use Throwable; use Yiisoft\Db\Connection\ConnectionInterface; use Yiisoft\Db\Exception\Exception; +use Yiisoft\Db\Expression\ExpressionInterface; use Yiisoft\Db\Expression\Param; use Yiisoft\Db\Query\DataReaderInterface; use Yiisoft\Db\Query\QueryInterface; @@ -510,7 +511,13 @@ public function truncateTable(string $table): static return $this->setSql($sql); } - public function update(string $table, array $columns, array|string $condition = '', array $params = []): static + public function update( + string $table, + array $columns, + array|string $condition = '', + array $params = [], + array|ExpressionInterface|string|null $from = null + ): static { $sql = $this->getQueryBuilder()->update($table, $columns, $condition, $params); return $this->setSql($sql)->bindValues($params); diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index bc622ff46..870ee5b07 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -840,7 +840,13 @@ public function truncateTable(string $table): static; * * Note: The method will quote the `table` and `columns` parameter before using it in the generated SQL. */ - public function update(string $table, array $columns, array|string $condition = '', array $params = []): static; + public function update( + string $table, + array $columns, + array|string $condition = '', + array $params = [], + array|ExpressionInterface|string|null $from = null + ): static; /** * Creates a command to insert rows into a database table if they don't already exist (matching unique constraints) diff --git a/src/Debug/CommandInterfaceProxy.php b/src/Debug/CommandInterfaceProxy.php index 2062aab35..eead70d40 100644 --- a/src/Debug/CommandInterfaceProxy.php +++ b/src/Debug/CommandInterfaceProxy.php @@ -7,6 +7,7 @@ use Closure; use Throwable; use Yiisoft\Db\Command\CommandInterface; +use Yiisoft\Db\Expression\ExpressionInterface; use Yiisoft\Db\Query\DataReaderInterface; use Yiisoft\Db\Query\QueryInterface; use Yiisoft\Db\Schema\Column\ColumnInterface; @@ -481,7 +482,13 @@ public function truncateTable(string $table): static /** * @psalm-suppress MixedArgument */ - public function update(string $table, array $columns, array|string $condition = '', array $params = []): static + public function update( + string $table, + array $columns, + array|string $condition = '', + array $params = [], + array|ExpressionInterface|string|null $from = null + ): static { return new self($this->decorated->{__FUNCTION__}(...func_get_args()), $this->collector); } diff --git a/src/QueryBuilder/AbstractDMLQueryBuilder.php b/src/QueryBuilder/AbstractDMLQueryBuilder.php index 65f292fbc..d36be9fda 100644 --- a/src/QueryBuilder/AbstractDMLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDMLQueryBuilder.php @@ -8,6 +8,7 @@ use IteratorAggregate; use Traversable; use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Constant\GettypeResult; use Yiisoft\Db\Constraint\Index; use Yiisoft\Db\Exception\Exception; use InvalidArgumentException; @@ -134,12 +135,21 @@ public function resetSequence(string $table, int|string|null $value = null): str throw new NotSupportedException(__METHOD__ . '() is not supported by this DBMS.'); } - public function update(string $table, array $columns, array|string $condition, array &$params = []): string - { + public function update( + string $table, + array $columns, + array|string $condition, + array &$params = [], + array|ExpressionInterface|string|null $from = null + ): string { $updates = $this->prepareUpdateSets($table, $columns, $params); $sql = 'UPDATE ' . $this->quoter->quoteTableName($table) . ' SET ' . implode(', ', $updates); $where = $this->queryBuilder->buildWhere($condition, $params); + if ($from !== null) { + $fromClause = $this->queryBuilder->buildFrom($this->prepareFromTables($from), $params); + $sql .= $fromClause === '' ? '' : ' ' . $fromClause; + } return $where === '' ? $sql : $sql . ' ' . $where; } @@ -445,6 +455,15 @@ protected function prepareUpsertColumns( return [$uniqueNames, $insertNames, null]; } + protected function prepareFromTables(array|ExpressionInterface|string $from): array + { + return match (gettype($from)) { + GettypeResult::ARRAY => $from, + GettypeResult::STRING => preg_split('/\s*,\s*/', trim($from), -1, PREG_SPLIT_NO_EMPTY), + default => [$from], + }; + } + /** * Returns all column names belonging to constraints enforcing uniqueness (`PRIMARY KEY`, `UNIQUE INDEX`, etc.) * for the named table removing constraints which didn't cover the specified column list. diff --git a/src/QueryBuilder/AbstractQueryBuilder.php b/src/QueryBuilder/AbstractQueryBuilder.php index 143bd98e9..2b16727b4 100644 --- a/src/QueryBuilder/AbstractQueryBuilder.php +++ b/src/QueryBuilder/AbstractQueryBuilder.php @@ -574,8 +574,13 @@ public function truncateTable(string $table): string return $this->ddlBuilder->truncateTable($table); } - public function update(string $table, array $columns, array|string $condition, array &$params = []): string - { + public function update( + string $table, + array $columns, + array|string $condition, + array &$params = [], + array|ExpressionInterface|string|null $from = null + ): string { return $this->dmlBuilder->update($table, $columns, $condition, $params); } diff --git a/src/QueryBuilder/DMLQueryBuilderInterface.php b/src/QueryBuilder/DMLQueryBuilderInterface.php index 87faf58ea..9052ef5df 100644 --- a/src/QueryBuilder/DMLQueryBuilderInterface.php +++ b/src/QueryBuilder/DMLQueryBuilderInterface.php @@ -10,6 +10,7 @@ use InvalidArgumentException; use Yiisoft\Db\Exception\InvalidConfigException; use Yiisoft\Db\Exception\NotSupportedException; +use Yiisoft\Db\Expression\ExpressionInterface; use Yiisoft\Db\Query\QueryInterface; /** @@ -191,7 +192,13 @@ public function resetSequence(string $table, int|string|null $value = null): str * * Note: The method will escape the table and column names. */ - public function update(string $table, array $columns, array|string $condition, array &$params = []): string; + public function update( + string $table, + array $columns, + array|string $condition, + array &$params = [], + array|ExpressionInterface|string|null $from = null + ): string; /** * Creates an SQL statement to insert rows into a database table if they don't already exist (matching unique From 30e118377776a628a5387de79579e26eee5a9549 Mon Sep 17 00:00:00 2001 From: Rustam Date: Wed, 20 Aug 2025 12:04:53 +0500 Subject: [PATCH 02/16] Fix parameters order, add test cases --- src/Command/AbstractCommand.php | 6 +- src/Command/CommandInterface.php | 5 +- src/Debug/CommandInterfaceProxy.php | 3 +- src/QueryBuilder/AbstractDMLQueryBuilder.php | 4 +- src/QueryBuilder/AbstractQueryBuilder.php | 6 +- src/QueryBuilder/DMLQueryBuilderInterface.php | 4 +- tests/AbstractQueryBuilderTest.php | 3 +- tests/Db/QueryBuilder/QueryBuilderTest.php | 3 +- tests/Provider/QueryBuilderProvider.php | 105 ++++++++++++++++++ 9 files changed, 121 insertions(+), 18 deletions(-) diff --git a/src/Command/AbstractCommand.php b/src/Command/AbstractCommand.php index 72eeb2ae7..8b196b342 100644 --- a/src/Command/AbstractCommand.php +++ b/src/Command/AbstractCommand.php @@ -514,12 +514,12 @@ public function truncateTable(string $table): static public function update( string $table, array $columns, - array|string $condition = '', - array $params = [], + array|ExpressionInterface|string $condition = '', array|ExpressionInterface|string|null $from = null ): static { - $sql = $this->getQueryBuilder()->update($table, $columns, $condition, $params); + $params = []; + $sql = $this->getQueryBuilder()->update($table, $columns, $condition, $from, $params); return $this->setSql($sql)->bindValues($params); } diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index 870ee5b07..9213f5152 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -831,20 +831,17 @@ public function truncateTable(string $table): static; * @param array $columns The column data (name => value) to update. * @param array|string $condition The condition to put in the WHERE part. Please refer to * {@see QueryInterface::where()} on how to specify condition. - * @param array $params The parameters to bind to the command. * * @throws Exception * @throws InvalidArgumentException * - * @psalm-param ParamsType $params * * Note: The method will quote the `table` and `columns` parameter before using it in the generated SQL. */ public function update( string $table, array $columns, - array|string $condition = '', - array $params = [], + array|ExpressionInterface|string $condition = '', array|ExpressionInterface|string|null $from = null ): static; diff --git a/src/Debug/CommandInterfaceProxy.php b/src/Debug/CommandInterfaceProxy.php index eead70d40..28df1632b 100644 --- a/src/Debug/CommandInterfaceProxy.php +++ b/src/Debug/CommandInterfaceProxy.php @@ -485,8 +485,7 @@ public function truncateTable(string $table): static public function update( string $table, array $columns, - array|string $condition = '', - array $params = [], + array|ExpressionInterface|string $condition = '', array|ExpressionInterface|string|null $from = null ): static { diff --git a/src/QueryBuilder/AbstractDMLQueryBuilder.php b/src/QueryBuilder/AbstractDMLQueryBuilder.php index d36be9fda..ec14ec48d 100644 --- a/src/QueryBuilder/AbstractDMLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDMLQueryBuilder.php @@ -139,8 +139,8 @@ public function update( string $table, array $columns, array|string $condition, - array &$params = [], - array|ExpressionInterface|string|null $from = null + array|ExpressionInterface|string|null $from = null, + array &$params = [] ): string { $updates = $this->prepareUpdateSets($table, $columns, $params); diff --git a/src/QueryBuilder/AbstractQueryBuilder.php b/src/QueryBuilder/AbstractQueryBuilder.php index 2b16727b4..e1fc7483f 100644 --- a/src/QueryBuilder/AbstractQueryBuilder.php +++ b/src/QueryBuilder/AbstractQueryBuilder.php @@ -578,10 +578,10 @@ public function update( string $table, array $columns, array|string $condition, - array &$params = [], - array|ExpressionInterface|string|null $from = null + array|ExpressionInterface|string|null $from = null, + array &$params = [] ): string { - return $this->dmlBuilder->update($table, $columns, $condition, $params); + return $this->dmlBuilder->update($table, $columns, $condition, $from, $params); } public function upsert( diff --git a/src/QueryBuilder/DMLQueryBuilderInterface.php b/src/QueryBuilder/DMLQueryBuilderInterface.php index 9052ef5df..8c3f26dfc 100644 --- a/src/QueryBuilder/DMLQueryBuilderInterface.php +++ b/src/QueryBuilder/DMLQueryBuilderInterface.php @@ -196,8 +196,8 @@ public function update( string $table, array $columns, array|string $condition, - array &$params = [], - array|ExpressionInterface|string|null $from = null + array|ExpressionInterface|string|null $from = null, + array &$params = [] ): string; /** diff --git a/tests/AbstractQueryBuilderTest.php b/tests/AbstractQueryBuilderTest.php index 243ef4d84..d1f1f9d93 100644 --- a/tests/AbstractQueryBuilderTest.php +++ b/tests/AbstractQueryBuilderTest.php @@ -2261,6 +2261,7 @@ public function testUpdate( string $table, array $columns, array|string $condition, + array|ExpressionInterface|string|null $from, array $params, string $expectedSql, array $expectedParams @@ -2268,7 +2269,7 @@ public function testUpdate( $db = $this->getConnection(); $qb = $db->getQueryBuilder(); - $sql = $qb->update($table, $columns, $condition, $params); + $sql = $qb->update($table, $columns, $condition, $from, $params); $sql = $db->getQuoter()->quoteSql($sql); $this->assertSame($expectedSql, $sql); diff --git a/tests/Db/QueryBuilder/QueryBuilderTest.php b/tests/Db/QueryBuilder/QueryBuilderTest.php index db788bc94..0ca3b3c12 100644 --- a/tests/Db/QueryBuilder/QueryBuilderTest.php +++ b/tests/Db/QueryBuilder/QueryBuilderTest.php @@ -219,6 +219,7 @@ public function testUpdate( string $table, array $columns, array|string $condition, + array|ExpressionInterface|string|null $from, array $params, string $expectedSql, array $expectedParams @@ -226,7 +227,7 @@ public function testUpdate( $db = $this->getConnection(); $qb = $db->getQueryBuilder(); - $sql = $qb->update($table, $columns, $condition, $params); + $sql = $qb->update($table, $columns, $condition, $from, $params); $sql = $db->getQuoter()->quoteSql($sql); $this->assertSame($expectedSql, $sql); diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 3ef3c8396..094ee8cd3 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -1201,6 +1201,7 @@ public static function update(): array '{{table}}', ['name' => '{{test}}'], [], + null, [], static::replaceQuotes( << '{{test}}'], ['id' => 1], + null, [], static::replaceQuotes( << '{{test}}', ], ], + [ + '{{table}}', + ['name' => '{{tmp}}.{{name}}'], + [], + 'tmp', + [], + static::replaceQuotes( + << '{{tmp}}.{{name}}', + ], + ], + [ + '{{table}}', + ['name' => '{{tmp}}.{{name}}'], + [], + ['tmp'], + [], + static::replaceQuotes( + << '{{tmp}}.{{name}}', + ], + ], + [ + '{{table}}', + ['name' => '{{tmp}}.{{name}}'], + ['id' => 1], + 'tmp', + [], + static::replaceQuotes( + << '{{tmp}}.{{name}}', + ], + ], + [ + '{{table}}', + ['name' => '{{tmp}}.{{name}}'], + [], + new Expression('SELECT [[name]] FROM [[tmp]] WHERE [[id]] = 1'), + [], + static::replaceQuotes( + << '{{tmp}}.{{name}}', + ], + ], + [ + '{{table}}', + ['name' => '{{tmp}}.{{name}}'], + [], + [new Expression('SELECT [[name]] FROM [[tmp]] WHERE [[id]] = 1')], + [], + static::replaceQuotes( + << '{{tmp}}.{{name}}', + ], + ], + [ + '{{table}}', + ['name' => '{{tmp}}'], + [], + ['tmp' => new Expression('SELECT [[name]] FROM [[tmp]] WHERE [[id]] = 1')], + [], + static::replaceQuotes( + << '{{tmp}}', + ], + ], [ '{{table}}', ['{{table}}.name' => '{{test}}'], ['id' => 1], + null, ['id' => 'boolean'], static::replaceQuotes( << 1, 'updated_at' => new Expression('now()')], ['id' => 100], + null, [], static::replaceQuotes( << new Expression('UPPER([[name]])')], '[[name]] = :name', + null, ['name' => new Expression('LOWER([[name]])')], static::replaceQuotes( << new Expression('[[price]] + :val', [':val' => 1])], '[[start_at]] < :date', + null, ['date' => new Expression('NOW()')], static::replaceQuotes( << new Expression('UPPER([[name]])')], '[[name]] = :name', + null, ['name' => new Expression('LOWER(:val)', [':val' => 'Apple'])], static::replaceQuotes( << new Expression('LOWER(:val)', ['val' => 'Apple'])], '[[name]] != :name', + null, ['name' => new Expression('UPPER(:val)', ['val' => 'Banana'])], static::replaceQuotes( << new Expression('LOWER(:val)', [':val' => 'Apple'])], '[[name]] != :name', + null, ['name' => new Expression('UPPER(:val)', ['val' => 'Banana'])], static::replaceQuotes( << new Expression('[[price]] * :val + :val1', ['val' => 1.2, 'val1' => 2])], '[[name]] IN :values', + null, ['values' => new Expression('(:val, :val2)', ['val' => 'Banana', 'val2' => 'Cherry'])], static::replaceQuotes( << new Expression('LOWER(:val)', ['val' => 'Apple'])], '[[name]] != :name', + null, ['name' => new Expression('UPPER(:val1)', ['val1' => 'Banana'])], static::replaceQuotes( << new Param('F', DataType::STRING), 'val' => new Expression('UPPER(:val || :val_0)', ['val' => 'D', 'val_0' => 'E']), @@ -1384,6 +1486,7 @@ public static function update(): array '{{product}}', ['name' => new Expression('LOWER(?)', ['Apple'])], '[[name]] != ?', + null, ['Banana'], static::replaceQuotes( << 10], ':val', + null, [':val' => new Expression("label=':val' AND name=:val", [':val' => 'Apple'])], static::replaceQuotes( << 10], ':val', + null, [':val' => new Expression("label=':val'", [':val' => 'Apple'])], static::replaceQuotes( << Date: Wed, 20 Aug 2025 17:25:17 +0500 Subject: [PATCH 03/16] Fix tests --- src/QueryBuilder/AbstractDMLQueryBuilder.php | 2 +- src/QueryBuilder/AbstractQueryBuilder.php | 2 +- src/QueryBuilder/DMLQueryBuilderInterface.php | 2 +- tests/AbstractQueryBuilderTest.php | 2 +- tests/Common/CommonCommandTest.php | 8 ++++---- tests/Common/CommonQueryBuilderTest.php | 4 ++-- tests/Db/QueryBuilder/QueryBuilderTest.php | 2 +- tests/Provider/CommandProvider.php | 12 ++++++------ 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/QueryBuilder/AbstractDMLQueryBuilder.php b/src/QueryBuilder/AbstractDMLQueryBuilder.php index ec14ec48d..d5390bea2 100644 --- a/src/QueryBuilder/AbstractDMLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDMLQueryBuilder.php @@ -138,7 +138,7 @@ public function resetSequence(string $table, int|string|null $value = null): str public function update( string $table, array $columns, - array|string $condition, + array|ExpressionInterface|string $condition, array|ExpressionInterface|string|null $from = null, array &$params = [] ): string { diff --git a/src/QueryBuilder/AbstractQueryBuilder.php b/src/QueryBuilder/AbstractQueryBuilder.php index e1fc7483f..eeeea1e0b 100644 --- a/src/QueryBuilder/AbstractQueryBuilder.php +++ b/src/QueryBuilder/AbstractQueryBuilder.php @@ -577,7 +577,7 @@ public function truncateTable(string $table): string public function update( string $table, array $columns, - array|string $condition, + array|ExpressionInterface|string $condition, array|ExpressionInterface|string|null $from = null, array &$params = [] ): string { diff --git a/src/QueryBuilder/DMLQueryBuilderInterface.php b/src/QueryBuilder/DMLQueryBuilderInterface.php index 8c3f26dfc..1a9d5cfd0 100644 --- a/src/QueryBuilder/DMLQueryBuilderInterface.php +++ b/src/QueryBuilder/DMLQueryBuilderInterface.php @@ -195,7 +195,7 @@ public function resetSequence(string $table, int|string|null $value = null): str public function update( string $table, array $columns, - array|string $condition, + array|ExpressionInterface|string $condition, array|ExpressionInterface|string|null $from = null, array &$params = [] ): string; diff --git a/tests/AbstractQueryBuilderTest.php b/tests/AbstractQueryBuilderTest.php index d1f1f9d93..0b51b48e1 100644 --- a/tests/AbstractQueryBuilderTest.php +++ b/tests/AbstractQueryBuilderTest.php @@ -2260,7 +2260,7 @@ public function testTruncateTable(): void public function testUpdate( string $table, array $columns, - array|string $condition, + array|ExpressionInterface|string $condition, array|ExpressionInterface|string|null $from, array $params, string $expectedSql, diff --git a/tests/Common/CommonCommandTest.php b/tests/Common/CommonCommandTest.php index 5d05cef73..ecca08453 100644 --- a/tests/Common/CommonCommandTest.php +++ b/tests/Common/CommonCommandTest.php @@ -1689,21 +1689,21 @@ public function testTruncateTable(): void public function testUpdate( string $table, array $columns, - array|string $conditions, - array $params, + array|ExpressionInterface|string $conditions, + array|ExpressionInterface|string|null $from, array $expectedValues, int $expectedCount, ): void { $db = $this->getConnection(true); $command = $db->createCommand(); - $count = $command->update($table, $columns, $conditions, $params)->execute(); + $count = $command->update($table, $columns, $conditions, $from)->execute(); $this->assertSame($expectedCount, $count); $values = (new Query($db)) ->from($table) - ->where($conditions, $params) + ->where($conditions) ->limit(1) ->one(); diff --git a/tests/Common/CommonQueryBuilderTest.php b/tests/Common/CommonQueryBuilderTest.php index c4aefc42c..ffb4a424f 100644 --- a/tests/Common/CommonQueryBuilderTest.php +++ b/tests/Common/CommonQueryBuilderTest.php @@ -163,7 +163,7 @@ public function testUpdateWithoutTypecasting(): void ]; $params = []; - $qb->update('{{type}}', $values, [], $params); + $qb->update('{{type}}', $values, [], null, $params); $this->assertSame([ ':qp0' => 1, @@ -173,7 +173,7 @@ public function testUpdateWithoutTypecasting(): void ], $params); $params = []; - $qb->withTypecasting(false)->update('{{type}}', $values, [], $params); + $qb->withTypecasting(false)->update('{{type}}', $values, [], null, $params); $this->assertSame([ ':qp0' => '1', diff --git a/tests/Db/QueryBuilder/QueryBuilderTest.php b/tests/Db/QueryBuilder/QueryBuilderTest.php index 0ca3b3c12..8c756926b 100644 --- a/tests/Db/QueryBuilder/QueryBuilderTest.php +++ b/tests/Db/QueryBuilder/QueryBuilderTest.php @@ -218,7 +218,7 @@ public function testResetSequence(): void public function testUpdate( string $table, array $columns, - array|string $condition, + array|ExpressionInterface|string $condition, array|ExpressionInterface|string|null $from, array $params, string $expectedSql, diff --git a/tests/Provider/CommandProvider.php b/tests/Provider/CommandProvider.php index fc506a4d1..27935e425 100644 --- a/tests/Provider/CommandProvider.php +++ b/tests/Provider/CommandProvider.php @@ -707,7 +707,7 @@ public static function update(): array '{{customer}}', ['name' => '{{test}}'], [], - [], + null, ['name' => '{{test}}'], 3, ], @@ -715,7 +715,7 @@ public static function update(): array '{{customer}}', ['name' => '{{test}}'], ['id' => 1], - [], + null, ['name' => '{{test}}'], 1, ], @@ -723,7 +723,7 @@ public static function update(): array '{{customer}}', ['{{customer}}.name' => '{{test}}'], ['id' => 1], - [], + null, ['name' => '{{test}}'], 1, ], @@ -731,7 +731,7 @@ public static function update(): array 'customer', ['status' => new Expression('1 + 2')], ['id' => 2], - [], + null, ['status' => 3], 1, ], @@ -741,8 +741,8 @@ public static function update(): array '1 + :val', ['val' => new Expression('2 + :val', ['val' => 3])] )], - '[[name]] != :val', - ['val' => new Expression('LOWER(:val)', ['val' => 'USER1'])], + new Expression('[[name]] != LOWER(:val)', ['val' => 'USER1']), + null, ['name' => 'user2', 'status' => 6], 2, ], From a4cf4342f3394aee0a4b61e36dcc38e0a87e0814 Mon Sep 17 00:00:00 2001 From: Rustam Date: Wed, 20 Aug 2025 17:43:48 +0500 Subject: [PATCH 04/16] Fix CS --- src/Command/AbstractCommand.php | 3 +-- src/Command/CommandInterface.php | 5 +++-- src/Debug/CommandInterfaceProxy.php | 3 +-- src/QueryBuilder/AbstractDMLQueryBuilder.php | 2 +- src/QueryBuilder/DMLQueryBuilderInterface.php | 4 +++- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Command/AbstractCommand.php b/src/Command/AbstractCommand.php index 8b196b342..e26deda4c 100644 --- a/src/Command/AbstractCommand.php +++ b/src/Command/AbstractCommand.php @@ -516,8 +516,7 @@ public function update( array $columns, array|ExpressionInterface|string $condition = '', array|ExpressionInterface|string|null $from = null - ): static - { + ): static { $params = []; $sql = $this->getQueryBuilder()->update($table, $columns, $condition, $from, $params); return $this->setSql($sql)->bindValues($params); diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index 9213f5152..59bb09738 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -829,13 +829,14 @@ public function truncateTable(string $table): static; * * @param string $table The name of the table to update. * @param array $columns The column data (name => value) to update. - * @param array|string $condition The condition to put in the WHERE part. Please refer to + * @param array|ExpressionInterface|string $condition The condition to put in the WHERE part. Please refer to * {@see QueryInterface::where()} on how to specify condition. + * @param array|ExpressionInterface|string|null $from The FROM part. Please refer to {@see QueryInterface::from()} + * on how to specify FROM part. * * @throws Exception * @throws InvalidArgumentException * - * * Note: The method will quote the `table` and `columns` parameter before using it in the generated SQL. */ public function update( diff --git a/src/Debug/CommandInterfaceProxy.php b/src/Debug/CommandInterfaceProxy.php index 28df1632b..f21ed2e5c 100644 --- a/src/Debug/CommandInterfaceProxy.php +++ b/src/Debug/CommandInterfaceProxy.php @@ -487,8 +487,7 @@ public function update( array $columns, array|ExpressionInterface|string $condition = '', array|ExpressionInterface|string|null $from = null - ): static - { + ): static { return new self($this->decorated->{__FUNCTION__}(...func_get_args()), $this->collector); } diff --git a/src/QueryBuilder/AbstractDMLQueryBuilder.php b/src/QueryBuilder/AbstractDMLQueryBuilder.php index d5390bea2..dd27bbe83 100644 --- a/src/QueryBuilder/AbstractDMLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDMLQueryBuilder.php @@ -458,7 +458,7 @@ protected function prepareUpsertColumns( protected function prepareFromTables(array|ExpressionInterface|string $from): array { return match (gettype($from)) { - GettypeResult::ARRAY => $from, + GettypeResult::ARRAY => $from, GettypeResult::STRING => preg_split('/\s*,\s*/', trim($from), -1, PREG_SPLIT_NO_EMPTY), default => [$from], }; diff --git a/src/QueryBuilder/DMLQueryBuilderInterface.php b/src/QueryBuilder/DMLQueryBuilderInterface.php index 1a9d5cfd0..60e91dc9d 100644 --- a/src/QueryBuilder/DMLQueryBuilderInterface.php +++ b/src/QueryBuilder/DMLQueryBuilderInterface.php @@ -178,8 +178,10 @@ public function resetSequence(string $table, int|string|null $value = null): str * * @param string $table The table to update. * @param array $columns The column data (name => value) to update the table. - * @param array|string $condition The condition to put in the `WHERE` part. Please refer to + * @param array|ExpressionInterface|string $condition The condition to put in the `WHERE` part. Please refer to * {@see Query::where()} On how to specify condition. + * @param array|ExpressionInterface|string|null $from The FROM part. Please refer to + * {@see Query::from()} On how to specify FROM part. * @param array $params The binding parameters that will be modified by this method so that they can be bound to * DB command later. * From 2e088fa5b79c9d4d447453729545a615e4ad91aa Mon Sep 17 00:00:00 2001 From: Rustam Date: Wed, 20 Aug 2025 17:52:13 +0500 Subject: [PATCH 05/16] Fix psalm --- src/QueryBuilder/AbstractDMLQueryBuilder.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/QueryBuilder/AbstractDMLQueryBuilder.php b/src/QueryBuilder/AbstractDMLQueryBuilder.php index dd27bbe83..f60d71f29 100644 --- a/src/QueryBuilder/AbstractDMLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDMLQueryBuilder.php @@ -457,6 +457,10 @@ protected function prepareUpsertColumns( protected function prepareFromTables(array|ExpressionInterface|string $from): array { + /** + * @var array + * @psalm-suppress PossiblyInvalidArgument + */ return match (gettype($from)) { GettypeResult::ARRAY => $from, GettypeResult::STRING => preg_split('/\s*,\s*/', trim($from), -1, PREG_SPLIT_NO_EMPTY), From 08a5f3a5914d2b162c78181d18baeb47308d7387 Mon Sep 17 00:00:00 2001 From: Rustam Date: Thu, 21 Aug 2025 15:34:16 +0500 Subject: [PATCH 06/16] Improve test cases --- tests/Provider/QueryBuilderProvider.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 094ee8cd3..0fc245915 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -1291,11 +1291,11 @@ public static function update(): array '{{table}}', ['name' => '{{tmp}}.{{name}}'], [], - [new Expression('SELECT [[name]] FROM [[tmp]] WHERE [[id]] = 1')], + [static::getDb()->select('name')->from('tmp')->where(['id' => 1])], [], static::replaceQuotes( << '{{tmp}}'], [], - ['tmp' => new Expression('SELECT [[name]] FROM [[tmp]] WHERE [[id]] = 1')], + ['tmp' => static::getDb()->select('name')->from('tmp')->where(['id' => 1])], [], static::replaceQuotes( << Date: Fri, 22 Aug 2025 10:50:10 +0500 Subject: [PATCH 07/16] Add changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bba33df6d..d019ba617 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -137,6 +137,9 @@ - Chg #1037: Change result type of `QueryBuilderInterface::getExpressionBuilder()` and `DQLQueryBuilderInterface::getExpressionBuilder()` methods to `ExpressionBuilderInterface` (@vjik) - New #1029: Add functions as expressions (@Tigrov) +- Enh #1038: Add ability to pass `FROM` clause to `CommandInterface::update()` and `DMLQueryBuilderInterface::update()` methods (@rustamwin) +- Enh #1038: Allow passing `ExpressionInterface` as condition in `CommandInterface::update()` and `DMLQueryBuilderInterface::update()` methods (@rustamwin) +- Chg #1038: Remove `$params` parameter from `CommandInterface::update()` method (@rustamwin) ## 1.3.0 March 21, 2024 From 28f2461b01a928e3d6948647bdcc6c6560991422 Mon Sep 17 00:00:00 2001 From: Rustam Date: Sun, 24 Aug 2025 16:32:16 +0500 Subject: [PATCH 08/16] Minor fix --- src/QueryBuilder/DMLQueryBuilderInterface.php | 4 ++-- tests/Provider/QueryBuilderProvider.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/QueryBuilder/DMLQueryBuilderInterface.php b/src/QueryBuilder/DMLQueryBuilderInterface.php index 60e91dc9d..b0fb11504 100644 --- a/src/QueryBuilder/DMLQueryBuilderInterface.php +++ b/src/QueryBuilder/DMLQueryBuilderInterface.php @@ -179,9 +179,9 @@ public function resetSequence(string $table, int|string|null $value = null): str * @param string $table The table to update. * @param array $columns The column data (name => value) to update the table. * @param array|ExpressionInterface|string $condition The condition to put in the `WHERE` part. Please refer to - * {@see Query::where()} On how to specify condition. + * {@see QueryPartsInterface::where()} On how to specify condition. * @param array|ExpressionInterface|string|null $from The FROM part. Please refer to - * {@see Query::from()} On how to specify FROM part. + * {@see QueryPartsInterface::from()} On how to specify FROM part. * @param array $params The binding parameters that will be modified by this method so that they can be bound to * DB command later. * diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index a80ce17f1..e4dfd8cf7 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -1280,11 +1280,11 @@ public static function update(): array '{{table}}', ['name' => '{{tmp}}.{{name}}'], [], - new Expression('SELECT [[name]] FROM [[tmp]] WHERE [[id]] = 1'), + new Expression('(SELECT [[name]] FROM [[tmp]] WHERE [[id]] = 1)'), [], static::replaceQuotes( << Date: Sun, 24 Aug 2025 16:36:44 +0500 Subject: [PATCH 09/16] Minor fix --- src/Command/CommandInterface.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index 59bb09738..49f08aad1 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -830,8 +830,8 @@ public function truncateTable(string $table): static; * @param string $table The name of the table to update. * @param array $columns The column data (name => value) to update. * @param array|ExpressionInterface|string $condition The condition to put in the WHERE part. Please refer to - * {@see QueryInterface::where()} on how to specify condition. - * @param array|ExpressionInterface|string|null $from The FROM part. Please refer to {@see QueryInterface::from()} + * {@see QueryPartsInterface::where()} on how to specify condition. + * @param array|ExpressionInterface|string|null $from The FROM part. Please refer to {@see QueryPartsInterface::from()} * on how to specify FROM part. * * @throws Exception From 632e5aac5b73d5f0f9d8effbcc58861e1f1a1ec8 Mon Sep 17 00:00:00 2001 From: Rustam Date: Wed, 27 Aug 2025 16:11:39 +0500 Subject: [PATCH 10/16] Fix test providers --- tests/Provider/CommandProvider.php | 24 ++++++++++++++++++++++++ tests/Provider/QueryBuilderProvider.php | 12 ++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/Provider/CommandProvider.php b/tests/Provider/CommandProvider.php index 27935e425..d3e4f28cb 100644 --- a/tests/Provider/CommandProvider.php +++ b/tests/Provider/CommandProvider.php @@ -711,6 +711,14 @@ public static function update(): array ['name' => '{{test}}'], 3, ], + [ + '{{customer}}', + ['name' => '{{test}}'], + [], + '{{customer}} c', + ['name' => '{{test}}'], + 3, + ], [ '{{customer}}', ['name' => '{{test}}'], @@ -735,6 +743,22 @@ public static function update(): array ['status' => 3], 1, ], + [ + 'customer', + ['status' => new Expression('1 + 2')], + ['customer.id' => 2], + ['c' => 'customer'], + ['status' => 3], + 1, + ], + [ + 'customer', + ['status' => new Expression('1 + 2')], + ['customer.id' => 2], + ['c' => self::getDb()->createQuery()->from('customer')], + ['status' => 3], + 1, + ], [ '{{customer}}', ['status' => new Expression( diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index cf8f48863..08daaa14e 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -1244,7 +1244,7 @@ public static function update(): array SQL ), [ - ':qp0' => '{{tmp}}.{{name}}', + ':qp0' => new Param('{{tmp}}.{{name}}', DataType::STRING), ], ], [ @@ -1259,7 +1259,7 @@ public static function update(): array SQL ), [ - ':qp0' => '{{tmp}}.{{name}}', + ':qp0' => new Param('{{tmp}}.{{name}}', DataType::STRING), ], ], [ @@ -1274,7 +1274,7 @@ public static function update(): array SQL ), [ - ':qp0' => '{{tmp}}.{{name}}', + ':qp0' => new Param('{{tmp}}.{{name}}', DataType::STRING), ], ], [ @@ -1289,7 +1289,7 @@ public static function update(): array SQL ), [ - ':qp0' => '{{tmp}}.{{name}}', + ':qp0' => new Param('{{tmp}}.{{name}}', DataType::STRING), ], ], [ @@ -1304,7 +1304,7 @@ public static function update(): array SQL ), [ - ':qp0' => '{{tmp}}.{{name}}', + ':qp0' => new Param('{{tmp}}.{{name}}', DataType::STRING), ], ], [ @@ -1319,7 +1319,7 @@ public static function update(): array SQL ), [ - ':qp0' => '{{tmp}}', + ':qp0' => new Param('{{tmp}}', DataType::STRING), ], ], [ From e2999cec3b7d570fb85d3d526ee07e40161326e1 Mon Sep 17 00:00:00 2001 From: Rustam Date: Thu, 28 Aug 2025 10:25:06 +0500 Subject: [PATCH 11/16] Fix tests --- tests/Provider/CommandProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Provider/CommandProvider.php b/tests/Provider/CommandProvider.php index d3e4f28cb..53c2d15b5 100644 --- a/tests/Provider/CommandProvider.php +++ b/tests/Provider/CommandProvider.php @@ -746,7 +746,7 @@ public static function update(): array [ 'customer', ['status' => new Expression('1 + 2')], - ['customer.id' => 2], + ['{{customer}}.id' => 2], ['c' => 'customer'], ['status' => 3], 1, @@ -754,7 +754,7 @@ public static function update(): array [ 'customer', ['status' => new Expression('1 + 2')], - ['customer.id' => 2], + ['{{customer}}.id' => 2], ['c' => self::getDb()->createQuery()->from('customer')], ['status' => 3], 1, From 10c490c5af549cdc576f8701d8555d6ca264ddbb Mon Sep 17 00:00:00 2001 From: Rustam Date: Sat, 6 Sep 2025 11:09:20 +0500 Subject: [PATCH 12/16] Fix changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fca1a47da..81631d578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -140,7 +140,6 @@ - Enh #1038: Add ability to pass `FROM` clause to `CommandInterface::update()` and `DMLQueryBuilderInterface::update()` methods (@rustamwin) - Enh #1038: Allow passing `ExpressionInterface` as condition in `CommandInterface::update()` and `DMLQueryBuilderInterface::update()` methods (@rustamwin) - Chg #1038: Remove `$params` parameter from `CommandInterface::update()` method (@rustamwin) -- New #1029, #1048: Add functions as expressions (@Tigrov) - Enh #1042: Refactor `AbstractDMLQueryBuilder` class to `upsert()` method (@Tigrov) - New #1040, #1043: Add `DateTimeValue` class (@vjik, @Tigrov) - Enh #1045: Support multi-operand functions in `CommandInterface::upsert()` and `DMLQueryBuilderInterface::upsert()` From 06a87aee98a3e00d7d785ecad7b566f772696a7e Mon Sep 17 00:00:00 2001 From: Rustam Date: Mon, 8 Sep 2025 19:13:07 +0500 Subject: [PATCH 13/16] Bring back $params argument --- src/Command/AbstractCommand.php | 4 ++-- src/Command/CommandInterface.php | 6 +++++- tests/Common/CommonCommandTest.php | 5 +++-- tests/Provider/CommandProvider.php | 10 +++++++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Command/AbstractCommand.php b/src/Command/AbstractCommand.php index b33371b1e..adac25d15 100644 --- a/src/Command/AbstractCommand.php +++ b/src/Command/AbstractCommand.php @@ -515,9 +515,9 @@ public function update( string $table, array $columns, array|ExpressionInterface|string $condition = '', - array|ExpressionInterface|string|null $from = null + array|ExpressionInterface|string|null $from = null, + array $params = [] ): static { - $params = []; $sql = $this->getQueryBuilder()->update($table, $columns, $condition, $from, $params); return $this->setSql($sql)->bindValues($params); } diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index e39280c88..393dd94fc 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -833,6 +833,9 @@ public function truncateTable(string $table): static; * {@see QueryPartsInterface::where()} on how to specify condition. * @param array|ExpressionInterface|string|null $from The FROM part. Please refer to {@see QueryPartsInterface::from()} * on how to specify FROM part. + * @param array $params The parameters to bind to the command. + * + * @psalm-param ParamsType $params * * @throws Exception * @throws InvalidArgumentException @@ -843,7 +846,8 @@ public function update( string $table, array $columns, array|ExpressionInterface|string $condition = '', - array|ExpressionInterface|string|null $from = null + array|ExpressionInterface|string|null $from = null, + array $params = [] ): static; /** diff --git a/tests/Common/CommonCommandTest.php b/tests/Common/CommonCommandTest.php index ab6877217..f9e38a89b 100644 --- a/tests/Common/CommonCommandTest.php +++ b/tests/Common/CommonCommandTest.php @@ -1691,19 +1691,20 @@ public function testUpdate( array $columns, array|ExpressionInterface|string $conditions, array|ExpressionInterface|string|null $from, + array $params, array $expectedValues, int $expectedCount, ): void { $db = $this->getConnection(true); $command = $db->createCommand(); - $count = $command->update($table, $columns, $conditions, $from)->execute(); + $count = $command->update($table, $columns, $conditions, $from, $params)->execute(); $this->assertSame($expectedCount, $count); $values = (new Query($db)) ->from($table) - ->where($conditions) + ->where($conditions, $params) ->limit(1) ->one(); diff --git a/tests/Provider/CommandProvider.php b/tests/Provider/CommandProvider.php index d2c4e42a0..95e4ff273 100644 --- a/tests/Provider/CommandProvider.php +++ b/tests/Provider/CommandProvider.php @@ -708,6 +708,7 @@ public static function update(): array ['name' => '{{test}}'], [], null, + [], ['name' => '{{test}}'], 3, ], @@ -716,6 +717,7 @@ public static function update(): array ['name' => '{{test}}'], [], '{{customer}} c', + [], ['name' => '{{test}}'], 3, ], @@ -724,6 +726,7 @@ public static function update(): array ['name' => '{{test}}'], ['id' => 1], null, + [], ['name' => '{{test}}'], 1, ], @@ -732,6 +735,7 @@ public static function update(): array ['{{customer}}.name' => '{{test}}'], ['id' => 1], null, + [], ['name' => '{{test}}'], 1, ], @@ -740,6 +744,7 @@ public static function update(): array ['status' => new Expression('1 + 2')], ['id' => 2], null, + [], ['status' => 3], 1, ], @@ -748,6 +753,7 @@ public static function update(): array ['status' => new Expression('1 + 2')], ['{{customer}}.id' => 2], ['c' => 'customer'], + [], ['status' => 3], 1, ], @@ -756,6 +762,7 @@ public static function update(): array ['status' => new Expression('1 + 2')], ['{{customer}}.id' => 2], ['c' => self::getDb()->createQuery()->from('customer')], + [], ['status' => 3], 1, ], @@ -765,8 +772,9 @@ public static function update(): array '1 + :val', ['val' => new Expression('2 + :val', ['val' => 3])] )], - new Expression('[[name]] != LOWER(:val)', ['val' => 'USER1']), + '[[name]] != :val', null, + ['val' => new Expression('LOWER(:val)', ['val' => 'USER1'])], ['name' => 'user2', 'status' => 6], 2, ], From 0064c31c66dcbd0a1ff6e30eefebb1a18295f6fa Mon Sep 17 00:00:00 2001 From: rustamwin <16498265+rustamwin@users.noreply.github.com> Date: Mon, 8 Sep 2025 14:18:17 +0000 Subject: [PATCH 14/16] Apply Rector changes (CI) --- src/Debug/CommandInterfaceProxy.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Debug/CommandInterfaceProxy.php b/src/Debug/CommandInterfaceProxy.php index f21ed2e5c..cef5c31fe 100644 --- a/src/Debug/CommandInterfaceProxy.php +++ b/src/Debug/CommandInterfaceProxy.php @@ -486,7 +486,8 @@ public function update( string $table, array $columns, array|ExpressionInterface|string $condition = '', - array|ExpressionInterface|string|null $from = null + array|ExpressionInterface|string|null $from = null, + array $params = [] ): static { return new self($this->decorated->{__FUNCTION__}(...func_get_args()), $this->collector); } From 64b6e53abbdaa3b7935ce2031ac22fc2ac862830 Mon Sep 17 00:00:00 2001 From: Rustam Mamadaminov Date: Tue, 9 Sep 2025 18:15:00 +0500 Subject: [PATCH 15/16] Apply suggestions from code review Co-authored-by: Sergei Predvoditelev --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81631d578..67d734605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -136,10 +136,9 @@ - Enh #1031: Optimize SQL generation for `Not` condition (@vjik) - Chg #1037: Change result type of `QueryBuilderInterface::getExpressionBuilder()` and `DQLQueryBuilderInterface::getExpressionBuilder()` methods to `ExpressionBuilderInterface` (@vjik) -- New #1029: Add functions as expressions (@Tigrov) +- New #1029, #1048: Add functions as expressions (@Tigrov) - Enh #1038: Add ability to pass `FROM` clause to `CommandInterface::update()` and `DMLQueryBuilderInterface::update()` methods (@rustamwin) - Enh #1038: Allow passing `ExpressionInterface` as condition in `CommandInterface::update()` and `DMLQueryBuilderInterface::update()` methods (@rustamwin) -- Chg #1038: Remove `$params` parameter from `CommandInterface::update()` method (@rustamwin) - Enh #1042: Refactor `AbstractDMLQueryBuilder` class to `upsert()` method (@Tigrov) - New #1040, #1043: Add `DateTimeValue` class (@vjik, @Tigrov) - Enh #1045: Support multi-operand functions in `CommandInterface::upsert()` and `DMLQueryBuilderInterface::upsert()` From c94a5973241f4001086b3cff65d51c9b496b56fe Mon Sep 17 00:00:00 2001 From: Tigrov Date: Mon, 22 Sep 2025 15:56:54 +0700 Subject: [PATCH 16/16] Close connections in tests --- tests/AbstractQueryBuilderTest.php | 14 ++++++++++++++ tests/Common/CommonQueryBuilderTest.php | 2 ++ tests/Common/CommonQueryTest.php | 12 ++++++++++++ tests/Db/QueryBuilder/QueryBuilderTest.php | 2 ++ 4 files changed, 30 insertions(+) diff --git a/tests/AbstractQueryBuilderTest.php b/tests/AbstractQueryBuilderTest.php index b750864fb..3d906567c 100644 --- a/tests/AbstractQueryBuilderTest.php +++ b/tests/AbstractQueryBuilderTest.php @@ -2223,6 +2223,8 @@ public function testSetSeparator(): void $sql, ); $this->assertEmpty($params); + + $db->close(); } public function testTruncateTable(): void @@ -2251,6 +2253,8 @@ public function testTruncateTable(): void ), $sql, ); + + $db->close(); } #[DataProviderExternal(QueryBuilderProvider::class, 'update')] @@ -2271,6 +2275,8 @@ public function testUpdate( $this->assertSame($expectedSql, $sql); $this->assertEquals($expectedParams, $params); + + $db->close(); } #[DataProviderExternal(QueryBuilderProvider::class, 'upsert')] @@ -2300,6 +2306,8 @@ public function testUpsert( $this->assertSame(1, $countAfter - $countBefore); $db->createCommand($sql, $params)->execute(); + + $db->close(); } #[DataProviderExternal(QueryBuilderProvider::class, 'upsertReturning')] @@ -2330,6 +2338,8 @@ public function testUpsertReturning( $this->assertSame(1, $countAfter - $countBefore); $db->createCommand($sql, $params)->execute(); + + $db->close(); } public function testOverrideParameters1(): void @@ -2353,6 +2363,8 @@ public function testOverrideParameters1(): void static::replaceQuotes('SELECT * FROM [[animal]] WHERE (id = 1 AND type = \'test\') AND ([[type]] = \'test1\')'), $command->getRawSql() ); + + $db->close(); } public function testOverrideParameters2(): void @@ -2376,6 +2388,8 @@ public function testOverrideParameters2(): void static::replaceQuotes('SELECT * FROM [[animal]] WHERE (id = 1) AND ([[type]] = \'test2\')'), $command->getRawSql() ); + + $db->close(); } #[DataProviderExternal(QueryBuilderProvider::class, 'buildColumnDefinition')] diff --git a/tests/Common/CommonQueryBuilderTest.php b/tests/Common/CommonQueryBuilderTest.php index cd74cc75e..72f9f8cbd 100644 --- a/tests/Common/CommonQueryBuilderTest.php +++ b/tests/Common/CommonQueryBuilderTest.php @@ -193,6 +193,8 @@ public function testUpdateWithoutTypecasting(): void ':qp2' => new Param('3.14', DataType::STRING), ':qp3' => new Param('1', DataType::STRING), ], $params); + + $db->close(); } #[DataProviderExternal(QueryBuilderProvider::class, 'caseXBuilder')] diff --git a/tests/Common/CommonQueryTest.php b/tests/Common/CommonQueryTest.php index 1ccd89bf0..3727c5adf 100644 --- a/tests/Common/CommonQueryTest.php +++ b/tests/Common/CommonQueryTest.php @@ -20,6 +20,8 @@ public function testAllEmpty(): void $query = (new Query($db))->from('customer')->where(['id' => 0]); $this->assertSame([], $query->all()); + + $db->close(); } public function testAllWithIndexBy(): void @@ -154,6 +156,8 @@ public function testLikeDefaultCaseSensitive(): void $this->assertSame('user1', $result); + + $db->close(); } public static function dataLikeCaseSensitive(): iterable @@ -174,6 +178,8 @@ public function testLikeCaseSensitive(mixed $expected, string $value): void ->scalar(); $this->assertSame($expected, $result); + + $db->close(); } public static function dataLikeCaseInsensitive(): iterable @@ -194,6 +200,8 @@ public function testLikeCaseInsensitive(mixed $expected, string $value): void ->scalar(); $this->assertSame($expected, $result); + + $db->close(); } public function testBatchWithResultCallback(): void @@ -224,6 +232,8 @@ public function testBatchWithResultCallback(): void ], $results, ); + + $db->close(); } public function testBatchWithIndexBy(): void @@ -249,5 +259,7 @@ public function testBatchWithIndexBy(): void ], $results, ); + + $db->close(); } } diff --git a/tests/Db/QueryBuilder/QueryBuilderTest.php b/tests/Db/QueryBuilder/QueryBuilderTest.php index 90efaeeb7..1145bb3a2 100644 --- a/tests/Db/QueryBuilder/QueryBuilderTest.php +++ b/tests/Db/QueryBuilder/QueryBuilderTest.php @@ -257,6 +257,8 @@ public function testUpdate( $this->assertSame($expectedSql, $sql); $this->assertEquals($expectedParams, $params); + + $db->close(); } #[DataProviderExternal(QueryBuilderProvider::class, 'upsert')]