Skip to content

Commit 3fba50c

Browse files
authored
Move method populate to Helper (#540)
* Move method populate to Helper * styleci * AR fix * styleci * cov fix
1 parent ebd4054 commit 3fba50c

10 files changed

Lines changed: 319 additions & 279 deletions

‎src/Helper/ArrayHelper.php‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,4 +320,33 @@ public static function multisort(
320320
$array
321321
);
322322
}
323+
324+
/**
325+
* @todo - Write correct description
326+
* Converts the array with data, using index-key if needed
327+
*
328+
* This method is internally used to convert the data fetched from database into the format as required by this
329+
* query.
330+
*
331+
* @param array $rows the raw query result from database.
332+
* @psalm-suppress MixedArrayOffset
333+
*
334+
* @return array the converted query result.
335+
*/
336+
public static function populate(array $rows, Closure|string|null $indexBy = null): array
337+
{
338+
if ($indexBy === null) {
339+
return $rows;
340+
}
341+
342+
$result = [];
343+
344+
/** @psalm-var array[][] $row */
345+
foreach ($rows as $row) {
346+
/** @psalm-suppress MixedArrayOffset */
347+
$result[self::getValueByPath($row, $indexBy)] = $row;
348+
}
349+
350+
return $result;
351+
}
323352
}

‎src/Query/BatchQueryResult.php‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Yiisoft\Db\Query;
66

7+
use Closure;
78
use Throwable;
89
use Yiisoft\Db\Exception\Exception;
910
use Yiisoft\Db\Exception\InvalidConfigException;
@@ -33,6 +34,8 @@ class BatchQueryResult implements BatchQueryResultInterface
3334
*/
3435
private array|null $batch = null;
3536

37+
private Closure|null $populateMethod = null;
38+
3639
/**
3740
* @var mixed The value for the current iteration.
3841
*/
@@ -101,7 +104,11 @@ protected function fetchData(): array
101104

102105
$rows = $this->getRows();
103106

104-
return $this->query->populate($rows);
107+
if ($this->populateMethod !== null) {
108+
return (array) ($this->populateMethod)($rows, $this->query->getIndexBy());
109+
}
110+
111+
return $rows;
105112
}
106113

107114
/**
@@ -152,4 +159,11 @@ public function batchSize(int $value): self
152159

153160
return $this;
154161
}
162+
163+
public function setPopulatedMethod(Closure|null $populateMethod = null): static
164+
{
165+
$this->populateMethod = $populateMethod;
166+
167+
return $this;
168+
}
155169
}

‎src/Query/BatchQueryResultInterface.php‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Yiisoft\Db\Query;
66

7+
use Closure;
78
use Iterator;
89
use Throwable;
910
use Yiisoft\Db\Exception\Exception;
@@ -102,4 +103,6 @@ public function getBatchSize(): int;
102103
* @return $this
103104
*/
104105
public function batchSize(int $value): self;
106+
107+
public function setPopulatedMethod(Closure|null $populateMethod = null): self;
105108
}

‎src/Query/Query.php‎

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,11 @@ public function andWhere($condition, array $params = []): static
225225

226226
public function all(): array
227227
{
228-
return match ($this->emulateExecution) {
229-
true => [],
230-
false => $this->populate($this->createCommand()->queryAll()),
231-
};
228+
if ($this->emulateExecution === true) {
229+
return [];
230+
}
231+
232+
return ArrayHelper::populate($this->createCommand()->queryAll(), $this->indexBy);
232233
}
233234

234235
public function average(string $q): int|float|null|string
@@ -241,7 +242,11 @@ public function average(string $q): int|float|null|string
241242

242243
public function batch(int $batchSize = 100): BatchQueryResultInterface
243244
{
244-
return $this->db->createBatchQueryResult($this)->batchSize($batchSize);
245+
return $this->db
246+
->createBatchQueryResult($this)
247+
->batchSize($batchSize)
248+
->setPopulatedMethod(fn (array $rows, Closure|string|null $indexBy = null): array => ArrayHelper::populate($rows, $indexBy))
249+
;
245250
}
246251

247252
public function column(): array
@@ -311,7 +316,11 @@ public function distinct(bool|null $value = true): static
311316

312317
public function each(int $batchSize = 100): BatchQueryResultInterface
313318
{
314-
return $this->db->createBatchQueryResult($this, true)->batchSize($batchSize);
319+
return $this->db
320+
->createBatchQueryResult($this, true)
321+
->batchSize($batchSize)
322+
->setPopulatedMethod(fn (array $rows, Closure|string|null $indexBy = null): array => ArrayHelper::populate($rows, $indexBy))
323+
;
315324
}
316325

317326
public function exists(): bool
@@ -586,23 +595,6 @@ public function params(array $params): static
586595
return $this;
587596
}
588597

589-
public function populate(array $rows): array
590-
{
591-
if ($this->indexBy === null) {
592-
return $rows;
593-
}
594-
595-
$result = [];
596-
597-
/** @psalm-var array[][] $row */
598-
foreach ($rows as $row) {
599-
/** @psalm-suppress MixedArrayOffset */
600-
$result[ArrayHelper::getValueByPath($row, $this->indexBy)] = $row;
601-
}
602-
603-
return $result;
604-
}
605-
606598
public function prepare(QueryBuilderInterface $builder): QueryInterface
607599
{
608600
return $this;

‎src/Query/QueryInterface.php‎

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -258,18 +258,6 @@ public function one(): array|null;
258258
*/
259259
public function params(array $params): static;
260260

261-
/**
262-
* Converts the raw query results into the format as specified by this query.
263-
*
264-
* This method is internally used to convert the data fetched from database into the format as required by this
265-
* query.
266-
*
267-
* @param array $rows The raw query result from database.
268-
*
269-
* @return array The converted query result.
270-
*/
271-
public function populate(array $rows): array;
272-
273261
/**
274262
* Prepares for building SQL.
275263
*

‎tests/AbstractQueryTest.php‎

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Yiisoft\Db\Tests;
66

7-
use Closure;
87
use PHPUnit\Framework\TestCase;
98
use Throwable;
109
use Yiisoft\Db\Exception\Exception;
@@ -754,65 +753,6 @@ public function testColumnWithIndexBy(): void
754753
], $query->column());
755754
}
756755

757-
/**
758-
* @dataProvider \Yiisoft\Db\Tests\Provider\QueryProvider::populate
759-
*/
760-
public function testPopulate(array $rows): void
761-
{
762-
$db = $this->getConnection(false);
763-
$query = (new Query($db));
764-
765-
$this->assertSame($rows, $query->populate($rows));
766-
}
767-
768-
/**
769-
* @dataProvider \Yiisoft\Db\Tests\Provider\QueryProvider::populateWithIndexBy
770-
* @dataProvider \Yiisoft\Db\Tests\Provider\QueryProvider::populateWithIncorrectIndexBy
771-
* @dataProvider \Yiisoft\Db\Tests\Provider\QueryProvider::populateWithIndexByClosure
772-
*/
773-
public function testPopulateWithIndexBy(Closure|string|null $indexBy, array $rows, array $populated): void
774-
{
775-
$db = $this->getConnection(false);
776-
$query = (new Query($db))->indexBy($indexBy);
777-
778-
$this->assertSame($populated, $query->populate($rows));
779-
}
780-
781-
/**
782-
* @dataProvider \Yiisoft\Db\Tests\Provider\QueryProvider::populateWithIndexBy
783-
*/
784-
public function testPopulateWithIndexByWithObject(Closure|string|null $indexBy, array $rows, array $expectedPopulated): void
785-
{
786-
$db = $this->getConnection(false);
787-
$query = (new Query($db))->indexBy($indexBy);
788-
789-
$rows = json_decode(json_encode($rows));
790-
$populated = json_decode(json_encode($query->populate($rows)), true);
791-
792-
$this->assertSame($expectedPopulated, $populated);
793-
}
794-
795-
/**
796-
* @dataProvider \Yiisoft\Db\Tests\Provider\QueryProvider::populateWithIncorrectIndexBy
797-
*/
798-
public function testPopulateWithIncorrectIndexByWithObject(Closure|string|null $indexBy, array $rows): void
799-
{
800-
$db = $this->getConnection(false);
801-
$query = (new Query($db))->indexBy($indexBy);
802-
803-
$rows = json_decode(json_encode($rows));
804-
805-
set_error_handler(static function (int $errno, string $errstr) {
806-
throw new \Exception('E_WARNING: ' . $errstr, $errno);
807-
}, E_WARNING);
808-
809-
$this->expectExceptionMessageMatches('/^E_WARNING: /');
810-
811-
$query->populate($rows);
812-
813-
restore_error_handler();
814-
}
815-
816756
/**
817757
* @dataProvider \Yiisoft\Db\Tests\Provider\QueryProvider::filterConditionData
818758
*/

‎tests/Common/CommonBatchQueryResultTest.php‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Yiisoft\Db\Tests\Common;
66

77
use PHPUnit\Framework\TestCase;
8+
use Yiisoft\Db\Query\BatchQueryResult;
89
use Yiisoft\Db\Query\BatchQueryResultInterface;
910
use Yiisoft\Db\Query\Query;
1011
use Yiisoft\Db\Tests\Support\TestTrait;
@@ -137,6 +138,23 @@ public function testBatchWithIndexBy(): void
137138
$db->close();
138139
}
139140

141+
public function testBatchQueryResultWithoutPopulate(): void
142+
{
143+
$db = $this->getConnection(true);
144+
145+
$query = new Query($db);
146+
$query->from('customer')->orderBy('id')->limit(3)->indexBy('id');
147+
148+
$batchQueryResult = new BatchQueryResult($query);
149+
150+
$customers = $this->getAllRowsFromBatch($batchQueryResult);
151+
152+
$this->assertCount(3, $customers);
153+
$this->assertEquals('user1', $customers[0]['name']);
154+
$this->assertEquals('user2', $customers[1]['name']);
155+
$this->assertEquals('user3', $customers[2]['name']);
156+
}
157+
140158
protected function getAllRowsFromBatch(BatchQueryResultInterface $batch): array
141159
{
142160
$allRows = [];

‎tests/Db/Helper/ArrayHelperTest.php‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Yiisoft\Db\Tests\Db\Helper;
66

7+
use Closure;
78
use PHPUnit\Framework\TestCase;
89
use Yiisoft\Db\Helper\ArrayHelper;
910

@@ -18,4 +19,51 @@ public function testIsAssociative(): void
1819
$this->assertTrue(ArrayHelper::isAssociative(['test' => 1]));
1920
$this->assertFalse(ArrayHelper::isAssociative([1]));
2021
}
22+
23+
/**
24+
* @dataProvider \Yiisoft\Db\Tests\Provider\PopulateProvider::populate
25+
*/
26+
public function testPopulate(array $rows): void
27+
{
28+
$this->assertSame($rows, ArrayHelper::populate($rows));
29+
}
30+
31+
/**
32+
* @dataProvider \Yiisoft\Db\Tests\Provider\PopulateProvider::populateWithIndexBy
33+
* @dataProvider \Yiisoft\Db\Tests\Provider\PopulateProvider::populateWithIncorrectIndexBy
34+
* @dataProvider \Yiisoft\Db\Tests\Provider\PopulateProvider::populateWithIndexByClosure
35+
*/
36+
public function testPopulateWithIndexBy(Closure|string|null $indexBy, array $rows, array $populated): void
37+
{
38+
$this->assertSame($populated, ArrayHelper::populate($rows, $indexBy));
39+
}
40+
41+
/**
42+
* @dataProvider \Yiisoft\Db\Tests\Provider\PopulateProvider::populateWithIndexBy
43+
*/
44+
public function testPopulateWithIndexByWithObject(Closure|string|null $indexBy, array $rows, array $expectedPopulated): void
45+
{
46+
$rows = json_decode(json_encode($rows));
47+
$populated = json_decode(json_encode(ArrayHelper::populate($rows, $indexBy)), true);
48+
49+
$this->assertSame($expectedPopulated, $populated);
50+
}
51+
52+
/**
53+
* @dataProvider \Yiisoft\Db\Tests\Provider\PopulateProvider::populateWithIncorrectIndexBy
54+
*/
55+
public function testPopulateWithIncorrectIndexByWithObject(Closure|string|null $indexBy, array $rows): void
56+
{
57+
$rows = json_decode(json_encode($rows));
58+
59+
set_error_handler(static function (int $errno, string $errstr) {
60+
throw new \Exception('E_WARNING: ' . $errstr, $errno);
61+
}, E_WARNING);
62+
63+
$this->expectExceptionMessageMatches('/^E_WARNING: /');
64+
65+
ArrayHelper::populate($rows, $indexBy);
66+
67+
restore_error_handler();
68+
}
2169
}

0 commit comments

Comments
 (0)