From 1da8e949689b88f61e4e564d721570dd248661e5 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 1 May 2024 22:37:01 +0700 Subject: [PATCH 1/9] Add callback to `Query::all()` and `Query::one()` --- UPGRADE.md | 2 ++ src/Query/Query.php | 50 ++++++++++++++++++++++++--- src/Query/QueryInterface.php | 15 ++++++++ tests/AbstractQueryTest.php | 18 ++++++++++ tests/Common/CommonQueryTest.php | 59 ++++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 5 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 2c8b0c6a7..f0ce0813b 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -115,6 +115,8 @@ Each table column has its own class in the `Yiisoft\Db\Schema\Column` namespace ### New methods - `QuoterInterface::getRawTableName()` - returns the raw table name without quotes; +- `QueryInterface::callback()` - allows to use a callback, which should be called on each row of the query result; +- `QueryInterface::getCallback()` - returns the callback to be called on each row of the query result or `null` if not set; - `SchemaInterface::getColumnFactory()` - returns the column factory object for concrete DBMS; - `QueryBuilderInterface::buildColumnDefinition()` - builds column definition for `CREATE TABLE` statement; - `QueryBuilderInterface::prepareParam()` - converts a `ParamInterface` object to its SQL representation; diff --git a/src/Query/Query.php b/src/Query/Query.php index 0c6921cbc..15452fee6 100644 --- a/src/Query/Query.php +++ b/src/Query/Query.php @@ -72,12 +72,15 @@ * Query internally uses the {@see \Yiisoft\Db\QueryBuilder\AbstractQueryBuilder} class to generate the SQL statement. * * @psalm-import-type SelectValue from QueryPartsInterface + * @psalm-import-type CallbackType from QueryInterface */ class Query implements QueryInterface { /** @psalm-var SelectValue $select */ protected array $select = []; protected string|null $selectOption = null; + /** @psalm-var CallbackType|null $callback */ + protected Closure|null $callback = null; protected bool|null $distinct = null; protected array $from = []; protected array $groupBy = []; @@ -230,7 +233,26 @@ public function all(): array return []; } - return DbArrayHelper::populate($this->createCommand()->queryAll(), $this->indexBy); + $rows = $this->createCommand()->queryAll(); + + if (empty($rows)) { + return []; + } + + if ($this->indexBy !== null) { + if (is_string($this->indexBy)) { + $indexes = array_column($rows, $this->indexBy); + } else { + $indexes = array_map($this->indexBy, $rows); + } + } + + if ($this->callback !== null) { + $rows = array_map($this->callback, $rows); + } + + /** @psalm-suppress MixedArgument */ + return isset($indexes) ? array_combine($indexes, $rows) : $rows; } public function average(string $sql): int|float|null|string @@ -250,6 +272,12 @@ public function batch(int $batchSize = 100): BatchQueryResultInterface ; } + public function callback(Closure|null $callback): static + { + $this->callback = $callback; + return $this; + } + public function column(): array { if ($this->emulateExecution) { @@ -384,6 +412,11 @@ public function from(array|ExpressionInterface|string $tables): static return $this; } + public function getCallback(): Closure|null + { + return $this->callback; + } + public function getDistinct(): bool|null { return $this->distinct; @@ -533,10 +566,17 @@ public function offset(ExpressionInterface|int|null $offset): static public function one(): array|object|null { - return match ($this->emulateExecution) { - true => null, - false => $this->createCommand()->queryOne(), - }; + if ($this->emulateExecution) { + return null; + } + + $row = $this->createCommand()->queryOne(); + + if ($this->callback === null || $row === null) { + return $row; + } + + return ($this->callback)($row); } public function orderBy(array|string|ExpressionInterface $columns): static diff --git a/src/Query/QueryInterface.php b/src/Query/QueryInterface.php index da42a8fcc..3ea9b2f8b 100644 --- a/src/Query/QueryInterface.php +++ b/src/Query/QueryInterface.php @@ -29,6 +29,7 @@ * * @psalm-import-type ParamsType from ConnectionInterface * @psalm-import-type SelectValue from QueryPartsInterface + * @psalm-type CallbackType = Closure(array):(array|object) */ interface QueryInterface extends ExpressionInterface, QueryPartsInterface, QueryFunctionsInterface { @@ -81,6 +82,13 @@ public function all(): array; */ public function batch(int $batchSize = 100): BatchQueryResultInterface; + /** + * Sets callback, which should be called on each row of the query result. + * + * @psalm-param CallbackType|null $callback + */ + public function callback(Closure|null $callback): static; + /** * Executes the query and returns the first column of the result. * @@ -148,6 +156,13 @@ public function emulateExecution(bool $value = true): static; */ public function exists(): bool; + /** + * Returns the callback to be called on each row of the query result. `null` will be returned if no callback is set. + * + * @psalm-return CallbackType|null + */ + public function getCallback(): Closure|null; + /** * @return bool|null The "distinct" value. */ diff --git a/tests/AbstractQueryTest.php b/tests/AbstractQueryTest.php index a068e8715..0874c582c 100644 --- a/tests/AbstractQueryTest.php +++ b/tests/AbstractQueryTest.php @@ -4,6 +4,7 @@ namespace Yiisoft\Db\Tests; +use Closure; use PHPUnit\Framework\TestCase; use Throwable; use Yiisoft\Db\Exception\Exception; @@ -824,4 +825,21 @@ public function testCountGreaterThanPhpIntMax(): void $this->assertSame('12345678901234567890', $query->count()); } + + public function testCallback(): void + { + $db = $this->getConnection(); + + $query = (new Query($db)); + + $this->assertNull($query->getCallback()); + + $query->callback(fn (array $row) => (object) $row); + + $this->assertInstanceOf(Closure::class, $query->getCallback()); + + $query->callback(null); + + $this->assertNull($query->getCallback()); + } } diff --git a/tests/Common/CommonQueryTest.php b/tests/Common/CommonQueryTest.php index 18d9769e9..d3e70ce51 100644 --- a/tests/Common/CommonQueryTest.php +++ b/tests/Common/CommonQueryTest.php @@ -81,4 +81,63 @@ public function testSelectWithoutFrom() $db->close(); } + + public function testCallbackAll(): void + { + $db = $this->getConnection(true); + + $query = (new Query($db)) + ->from('customer') + ->callback(fn (array $row) => (object) $row); + + $this->assertEquals([ + (object) [ + 'id' => '1', + 'email' => 'user1@example.com', + 'name' => 'user1', + 'address' => 'address1', + 'status' => '1', + 'profile_id' => '1', + ], + (object) [ + 'id' => '2', + 'email' => 'user2@example.com', + 'name' => 'user2', + 'address' => 'address2', + 'status' => '1', + 'profile_id' => null, + ], + (object) [ + 'id' => '3', + 'email' => 'user3@example.com', + 'name' => 'user3', + 'address' => 'address3', + 'status' => '2', + 'profile_id' => '2', + ], + ], $query->all()); + + $db->close(); + } + + public function testCallbackOne(): void + { + $db = $this->getConnection(true); + + $query = (new Query($db)) + ->from('customer') + ->where(['id' => 2]) + ->callback(fn (array $row) => (object) $row); + + $this->assertEquals((object) [ + 'id' => '2', + 'email' => 'user2@example.com', + 'name' => 'user2', + 'address' => 'address2', + 'status' => '1', + 'profile_id' => null, + ], $query->one()); + + $db->close(); + } } From ae6de5a2d19707fe3fddc5a8ca427c9ed7998482 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 18:43:46 +0700 Subject: [PATCH 2/9] Rename to `resultCallback` --- src/Query/Query.php | 22 +++++++-------- src/Query/QueryInterface.php | 29 +++++++++++++++----- tests/AbstractQueryTest.php | 12 ++++----- tests/Common/CommonQueryTest.php | 46 ++++++-------------------------- 4 files changed, 47 insertions(+), 62 deletions(-) diff --git a/src/Query/Query.php b/src/Query/Query.php index 15452fee6..7c4db0d86 100644 --- a/src/Query/Query.php +++ b/src/Query/Query.php @@ -72,15 +72,15 @@ * Query internally uses the {@see \Yiisoft\Db\QueryBuilder\AbstractQueryBuilder} class to generate the SQL statement. * * @psalm-import-type SelectValue from QueryPartsInterface - * @psalm-import-type CallbackType from QueryInterface + * @psalm-import-type ResultCallback from QueryInterface */ class Query implements QueryInterface { /** @psalm-var SelectValue $select */ protected array $select = []; protected string|null $selectOption = null; - /** @psalm-var CallbackType|null $callback */ - protected Closure|null $callback = null; + /** @psalm-var ResultCallback|null $resultCallback */ + protected Closure|null $resultCallback = null; protected bool|null $distinct = null; protected array $from = []; protected array $groupBy = []; @@ -247,8 +247,8 @@ public function all(): array } } - if ($this->callback !== null) { - $rows = array_map($this->callback, $rows); + if ($this->resultCallback !== null) { + $rows = ($this->resultCallback)($rows); } /** @psalm-suppress MixedArgument */ @@ -272,9 +272,9 @@ public function batch(int $batchSize = 100): BatchQueryResultInterface ; } - public function callback(Closure|null $callback): static + public function resultCallback(Closure|null $resultCallback): static { - $this->callback = $callback; + $this->resultCallback = $resultCallback; return $this; } @@ -412,9 +412,9 @@ public function from(array|ExpressionInterface|string $tables): static return $this; } - public function getCallback(): Closure|null + public function getResultCallback(): Closure|null { - return $this->callback; + return $this->resultCallback; } public function getDistinct(): bool|null @@ -572,11 +572,11 @@ public function one(): array|object|null $row = $this->createCommand()->queryOne(); - if ($this->callback === null || $row === null) { + if ($this->resultCallback === null || $row === null) { return $row; } - return ($this->callback)($row); + return ($this->resultCallback)([$row])[0]; } public function orderBy(array|string|ExpressionInterface $columns): static diff --git a/src/Query/QueryInterface.php b/src/Query/QueryInterface.php index 3ea9b2f8b..6deea2bb4 100644 --- a/src/Query/QueryInterface.php +++ b/src/Query/QueryInterface.php @@ -29,7 +29,7 @@ * * @psalm-import-type ParamsType from ConnectionInterface * @psalm-import-type SelectValue from QueryPartsInterface - * @psalm-type CallbackType = Closure(array):(array|object) + * @psalm-type ResultCallback = Closure(list):list */ interface QueryInterface extends ExpressionInterface, QueryPartsInterface, QueryFunctionsInterface { @@ -83,11 +83,25 @@ public function all(): array; public function batch(int $batchSize = 100): BatchQueryResultInterface; /** - * Sets callback, which should be called on each row of the query result. + * Sets the callback, to be called on all rows of the query result before returning them. * - * @psalm-param CallbackType|null $callback + * For example: + * + * ```php + * $users = (new Query($db)) + * ->from('user') + * ->resultCallback(function (array $rows): array { + * foreach ($rows as &$row) { + * $row['name'] = strtoupper($row['name']); + * } + * return $rows; + * }) + * ->all(); + * ``` + * + * @psalm-param ResultCallback|null $resultCallback */ - public function callback(Closure|null $callback): static; + public function resultCallback(Closure|null $resultCallback): static; /** * Executes the query and returns the first column of the result. @@ -157,11 +171,12 @@ public function emulateExecution(bool $value = true): static; public function exists(): bool; /** - * Returns the callback to be called on each row of the query result. `null` will be returned if no callback is set. + * Returns the callback to be called on all rows of the query result. + * `null` will be returned if the callback is not set. * - * @psalm-return CallbackType|null + * @psalm-return ResultCallback|null */ - public function getCallback(): Closure|null; + public function getResultCallback(): Closure|null; /** * @return bool|null The "distinct" value. diff --git a/tests/AbstractQueryTest.php b/tests/AbstractQueryTest.php index 0874c582c..dd96344e8 100644 --- a/tests/AbstractQueryTest.php +++ b/tests/AbstractQueryTest.php @@ -826,20 +826,20 @@ public function testCountGreaterThanPhpIntMax(): void $this->assertSame('12345678901234567890', $query->count()); } - public function testCallback(): void + public function testResultCallback(): void { $db = $this->getConnection(); $query = (new Query($db)); - $this->assertNull($query->getCallback()); + $this->assertNull($query->getResultCallback()); - $query->callback(fn (array $row) => (object) $row); + $query->resultCallback(fn (array $rows) => array_map(fn (array $row) => (object) $row, $rows)); - $this->assertInstanceOf(Closure::class, $query->getCallback()); + $this->assertInstanceOf(Closure::class, $query->getResultCallback()); - $query->callback(null); + $query->resultCallback(null); - $this->assertNull($query->getCallback()); + $this->assertNull($query->getResultCallback()); } } diff --git a/tests/Common/CommonQueryTest.php b/tests/Common/CommonQueryTest.php index d3e70ce51..74bf3cf8a 100644 --- a/tests/Common/CommonQueryTest.php +++ b/tests/Common/CommonQueryTest.php @@ -88,34 +88,11 @@ public function testCallbackAll(): void $query = (new Query($db)) ->from('customer') - ->callback(fn (array $row) => (object) $row); - - $this->assertEquals([ - (object) [ - 'id' => '1', - 'email' => 'user1@example.com', - 'name' => 'user1', - 'address' => 'address1', - 'status' => '1', - 'profile_id' => '1', - ], - (object) [ - 'id' => '2', - 'email' => 'user2@example.com', - 'name' => 'user2', - 'address' => 'address2', - 'status' => '1', - 'profile_id' => null, - ], - (object) [ - 'id' => '3', - 'email' => 'user3@example.com', - 'name' => 'user3', - 'address' => 'address3', - 'status' => '2', - 'profile_id' => '2', - ], - ], $query->all()); + ->resultCallback(fn (array $rows) => array_map(fn (array $row) => (object) $row, $rows)); + + foreach ($query->all() as $row) { + $this->assertIsObject($row); + } $db->close(); } @@ -127,16 +104,9 @@ public function testCallbackOne(): void $query = (new Query($db)) ->from('customer') ->where(['id' => 2]) - ->callback(fn (array $row) => (object) $row); - - $this->assertEquals((object) [ - 'id' => '2', - 'email' => 'user2@example.com', - 'name' => 'user2', - 'address' => 'address2', - 'status' => '1', - 'profile_id' => null, - ], $query->one()); + ->resultCallback(fn (array $rows) => [(object) $rows[0]]); + + $this->assertIsObject($query->one()); $db->close(); } From 8e9831f4e2d86d63a0f68e483cf63f1842540135 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 18:54:57 +0700 Subject: [PATCH 3/9] Rearrange methods --- src/Query/Query.php | 26 ++++++++-------- src/Query/QueryInterface.php | 58 ++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/Query/Query.php b/src/Query/Query.php index 5333d3cef..3e37d40b1 100644 --- a/src/Query/Query.php +++ b/src/Query/Query.php @@ -81,8 +81,6 @@ class Query implements QueryInterface /** @psalm-var SelectValue $select */ protected array $select = []; protected string|null $selectOption = null; - /** @psalm-var ResultCallback|null $resultCallback */ - protected Closure|null $resultCallback = null; protected bool|null $distinct = null; protected array $from = []; protected array $groupBy = []; @@ -90,6 +88,8 @@ class Query implements QueryInterface protected array $join = []; protected array $orderBy = []; protected array $params = []; + /** @psalm-var ResultCallback|null $resultCallback */ + protected Closure|null $resultCallback = null; protected array $union = []; protected array $withQueries = []; /** @psalm-var IndexBy|null $indexBy */ @@ -275,12 +275,6 @@ public function batch(int $batchSize = 100): BatchQueryResultInterface ; } - public function resultCallback(Closure|null $resultCallback): static - { - $this->resultCallback = $resultCallback; - return $this; - } - public function column(): array { if ($this->emulateExecution) { @@ -415,11 +409,6 @@ public function from(array|ExpressionInterface|string $tables): static return $this; } - public function getResultCallback(): Closure|null - { - return $this->resultCallback; - } - public function getDistinct(): bool|null { return $this->distinct; @@ -470,6 +459,11 @@ public function getParams(): array return $this->params; } + public function getResultCallback(): Closure|null + { + return $this->resultCallback; + } + public function getSelect(): array { return $this->select; @@ -650,6 +644,12 @@ public function prepare(QueryBuilderInterface $builder): QueryInterface return $this; } + public function resultCallback(Closure|null $resultCallback): static + { + $this->resultCallback = $resultCallback; + return $this; + } + public function rightJoin(array|string $table, array|string $on = '', array $params = []): static { $this->join[] = ['RIGHT JOIN', $table, $on]; diff --git a/src/Query/QueryInterface.php b/src/Query/QueryInterface.php index 2bbb304f9..0d20f0583 100644 --- a/src/Query/QueryInterface.php +++ b/src/Query/QueryInterface.php @@ -83,27 +83,6 @@ public function all(): array; */ public function batch(int $batchSize = 100): BatchQueryResultInterface; - /** - * Sets the callback, to be called on all rows of the query result before returning them. - * - * For example: - * - * ```php - * $users = (new Query($db)) - * ->from('user') - * ->resultCallback(function (array $rows): array { - * foreach ($rows as &$row) { - * $row['name'] = strtoupper($row['name']); - * } - * return $rows; - * }) - * ->all(); - * ``` - * - * @psalm-param ResultCallback|null $resultCallback - */ - public function resultCallback(Closure|null $resultCallback): static; - /** * Executes the query and returns the first column of the result. * @@ -171,14 +150,6 @@ public function emulateExecution(bool $value = true): static; */ public function exists(): bool; - /** - * Returns the callback to be called on all rows of the query result. - * `null` will be returned if the callback is not set. - * - * @psalm-return ResultCallback|null - */ - public function getResultCallback(): Closure|null; - /** * @return bool|null The "distinct" value. */ @@ -240,6 +211,14 @@ public function getOrderBy(): array; */ public function getParams(): array; + /** + * Returns the callback to be called on all rows of the query result. + * `null` will be returned if the callback is not set. + * + * @psalm-return ResultCallback|null + */ + public function getResultCallback(): Closure|null; + /** * @return array The "select" value. * @psalm-return SelectValue @@ -318,6 +297,27 @@ public function params(array $params): static; */ public function prepare(QueryBuilderInterface $builder): self; + /** + * Sets the callback, to be called on all rows of the query result before returning them. + * + * For example: + * + * ```php + * $users = (new Query($db)) + * ->from('user') + * ->resultCallback(function (array $rows): array { + * foreach ($rows as &$row) { + * $row['name'] = strtoupper($row['name']); + * } + * return $rows; + * }) + * ->all(); + * ``` + * + * @psalm-param ResultCallback|null $resultCallback + */ + public function resultCallback(Closure|null $resultCallback): static; + /** * Returns the query results as a scalar value. * The value returned will be the first column in the first row of the query results. From b586b7929623c11d6b1f9885cbf11d53c234b2f8 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 18:58:32 +0700 Subject: [PATCH 4/9] Update UPGRADE.md --- UPGRADE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 1654a23f9..7cae44bc3 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -117,8 +117,9 @@ Each table column has its own class in the `Yiisoft\Db\Schema\Column` namespace ### New methods - `QuoterInterface::getRawTableName()` - returns the raw table name without quotes; -- `QueryInterface::callback()` - allows to use a callback, which should be called on each row of the query result; -- `QueryInterface::getCallback()` - returns the callback to be called on each row of the query result or `null` if not set; +- `QueryInterface::resultCallback()` - allows to use a callback, to be called on all rows of the query result; +- `QueryInterface::getResultCallback()` - returns the callback to be called on all rows of the query result or + `null` if the callback is not set; - `SchemaInterface::getColumnFactory()` - returns the column factory object for concrete DBMS; - `ConnectionInterface::getColumnFactory()` - returns the column factory object for concrete DBMS; - `ConnectionInterface::getServerInfo()` - returns `ServerInfoInterface` instance which provides server information; From 2d11ad90b7b652636de5609da2f441aec24ebf44 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 19:01:37 +0700 Subject: [PATCH 5/9] Fix psalm --- src/Query/QueryInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Query/QueryInterface.php b/src/Query/QueryInterface.php index 0d20f0583..8c2dacb3b 100644 --- a/src/Query/QueryInterface.php +++ b/src/Query/QueryInterface.php @@ -30,7 +30,7 @@ * @psalm-type IndexBy = Closure(array):array-key|string * @psalm-import-type ParamsType from ConnectionInterface * @psalm-import-type SelectValue from QueryPartsInterface - * @psalm-type ResultCallback = Closure(list):list + * @psalm-type ResultCallback = Closure(non-empty-array):non-empty-array */ interface QueryInterface extends ExpressionInterface, QueryPartsInterface, QueryFunctionsInterface { From 1ab7d3ff0d6b129f3fc5924e05826fdd1a2501aa Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 19:33:08 +0700 Subject: [PATCH 6/9] Update UPGRADE.md [skip ci] --- UPGRADE.md | 1 - 1 file changed, 1 deletion(-) diff --git a/UPGRADE.md b/UPGRADE.md index 7cae44bc3..ac451e5fd 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -120,7 +120,6 @@ Each table column has its own class in the `Yiisoft\Db\Schema\Column` namespace - `QueryInterface::resultCallback()` - allows to use a callback, to be called on all rows of the query result; - `QueryInterface::getResultCallback()` - returns the callback to be called on all rows of the query result or `null` if the callback is not set; -- `SchemaInterface::getColumnFactory()` - returns the column factory object for concrete DBMS; - `ConnectionInterface::getColumnFactory()` - returns the column factory object for concrete DBMS; - `ConnectionInterface::getServerInfo()` - returns `ServerInfoInterface` instance which provides server information; - `QueryBuilderInterface::buildColumnDefinition()` - builds column definition for `CREATE TABLE` statement; From 39782f5c235bca775bd643a8052739dbd68e0471 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 19:39:34 +0700 Subject: [PATCH 7/9] Improve test coverage --- tests/Common/CommonQueryTest.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Common/CommonQueryTest.php b/tests/Common/CommonQueryTest.php index 388f2bb42..72a025c10 100644 --- a/tests/Common/CommonQueryTest.php +++ b/tests/Common/CommonQueryTest.php @@ -9,8 +9,29 @@ use Yiisoft\Db\Query\Query; use Yiisoft\Db\Tests\AbstractQueryTest; +use function array_keys; + abstract class CommonQueryTest extends AbstractQueryTest { + public function testAllWithIndexBy(): void + { + $db = $this->getConnection(true); + + $query = (new Query($db)) + ->from('customer') + ->indexBy('name'); + + $this->assertSame(['user1', 'user2', 'user3'], array_keys($query->all())); + + $query = (new Query($db)) + ->from('customer') + ->indexBy(fn (array $row) => $row['id'] * 2); + + $this->assertSame([2, 4, 6], array_keys($query->all())); + + $db->close(); + } + public function testColumnIndexByWithClosure() { $db = $this->getConnection(true); From dc1927c8a0eb9319bb1ee76262bd69b9dae0096e Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 20:12:45 +0700 Subject: [PATCH 8/9] Improve test coverage --- tests/Common/CommonQueryTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/Common/CommonQueryTest.php b/tests/Common/CommonQueryTest.php index 72a025c10..09e60600a 100644 --- a/tests/Common/CommonQueryTest.php +++ b/tests/Common/CommonQueryTest.php @@ -13,6 +13,15 @@ abstract class CommonQueryTest extends AbstractQueryTest { + public function testAllEmpty(): void + { + $db = $this->getConnection(true); + + $query = (new Query($db))->from('customer')->where(['id' => 0]); + + $this->assertSame([], $query->all()); + } + public function testAllWithIndexBy(): void { $db = $this->getConnection(true); From 2b56ea16d8e7100deab7b2659600697369def8c9 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 2 Apr 2025 20:28:14 +0700 Subject: [PATCH 9/9] Add line to CHANGELOG.md [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 938e3960b..db70448d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ - New #939: Add `caseSensitive` option to like condition (@vjik) - New #942: Allow PHP backed enums as values (@Tigrov) - Enh #943: Add `getCacheKey()` and `getCacheTag()` methods to `AbstractPdoSchema` class (@Tigrov) +- Enh #925: Add callback to `Query::all()` and `Query::one()` methods (@Tigrov) ## 1.3.0 March 21, 2024