Skip to content

Commit

Permalink
Merge pull request #48 from kbond/as-dto
Browse files Browse the repository at this point in the history
fix(ORM): normalize with modifier when iterating
  • Loading branch information
kbond authored Nov 23, 2024
2 parents ffa728b + f9d0ee7 commit fc12693
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 6 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: [ 8.1, 8.2, 8.3 ]
php: [ 8.1, 8.2, 8.3, 8.4 ]
deps: [ highest ]
symfony: [ 6.4.*, 7.0.* ]
symfony: [ 6.4.*, 7.1.*, 7.2.* ]
include:
- php: 8.1
deps: lowest
symfony: '*'
exclude:
- php: 8.1
symfony: 7.0.*
symfony: 7.1.*
- php: 8.1
symfony: 7.2.*
steps:
- uses: zenstruck/.github/actions/php-test-symfony@main
with:
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,7 @@
},
"autoload-dev": {
"psr-4": { "Zenstruck\\Collection\\Tests\\": ["tests/"] }
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
12 changes: 10 additions & 2 deletions src/Collection/Doctrine/ORM/EntityResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
use Zenstruck\Collection\IterableCollection;
use Zenstruck\Collection\LazyCollection;

use function Zenstruck\collect;

/**
* @author Kevin Bond <[email protected]>
*
Expand Down Expand Up @@ -254,7 +256,13 @@ public function getIterator(): \Traversable
}

try {
yield from $this->query()->toIterable(hydrationMode: $this->hydrationMode ?? Query::HYDRATE_OBJECT);
$iterator = $this->query()->toIterable(hydrationMode: $this->hydrationMode ?? Query::HYDRATE_OBJECT);

if ($this->resultModifier) {
$iterator = collect(fn() => yield from $iterator)->map($this->resultModifier);
}

yield from $iterator;
} catch (QueryException $e) {
if ($e->getMessage() === QueryException::iterateWithMixedResultNotAllowed()->getMessage()) {
throw new \LogicException(\sprintf('Results contain aggregate fields, call %s::withAggregates().', self::class), 0, $e);
Expand Down Expand Up @@ -320,7 +328,7 @@ private function paginator(?Query $query = null): Paginator
{
$paginator = new Paginator($query ?? $this->query(), $this->fetchJoins);

if ($this->hydrationMode) {
if ($this->resultModifier || $this->hydrationMode) {
$paginator->setUseOutputWalkers(false);
}

Expand Down
19 changes: 19 additions & 0 deletions tests/Doctrine/Fixture/EntityDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* This file is part of the zenstruck/collection package.
*
* (c) Kevin Bond <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Zenstruck\Collection\Tests\Doctrine\Fixture;

final class EntityDto
{
public function __construct(public string $value)
{
}
}
37 changes: 37 additions & 0 deletions tests/Doctrine/ORM/Result/EntityDtoCallbackTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/*
* This file is part of the zenstruck/collection package.
*
* (c) Kevin Bond <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Zenstruck\Collection\Tests\Doctrine\ORM\Result;

use Zenstruck\Collection\Doctrine\ORM\EntityResult;
use Zenstruck\Collection\Tests\Doctrine\Fixture\Entity;
use Zenstruck\Collection\Tests\Doctrine\Fixture\EntityDto;
use Zenstruck\Collection\Tests\Doctrine\ORM\EntityResultTest;

/**
* @author Kevin Bond <[email protected]>
*/
final class EntityDtoCallbackTest extends EntityResultTest
{
protected function expectedValueAt(int $position)
{
return new EntityDto((string) $position);
}

protected function createWithItems(int $count): EntityResult
{
$this->persistEntities($count);

return (new EntityResult($this->em->createQueryBuilder()->select('e.id')->from(Entity::class, 'e')))
->as(fn(array $v) => new EntityDto((string) $v['id']))
;
}
}
10 changes: 10 additions & 0 deletions tests/Doctrine/ORM/Result/FloatResultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ public function null_result(): void
$this->assertSame([], \array_filter($result->eager()->all()));
}

/**
* @test
*/
public function iterator_exact_match(): void
{
$results = $this->createWithItems(3);

$this->assertSame([1.0, 2.0, 3.0], \iterator_to_array($results));
}

protected function expectedValueAt(int $position)
{
return (float) $position;
Expand Down
10 changes: 10 additions & 0 deletions tests/Doctrine/ORM/Result/IntResultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ public function can_select_single_scalar(): void
$this->assertSame(6, $result->first());
}

/**
* @test
*/
public function iterator_exact_match(): void
{
$results = $this->createWithItems(3);

$this->assertSame([1, 2, 3], \iterator_to_array($results));
}

protected function expectedValueAt(int $position)
{
return $position;
Expand Down
10 changes: 10 additions & 0 deletions tests/Doctrine/ORM/Result/StringResultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@
*/
final class StringResultTest extends EntityResultTest
{
/**
* @test
*/
public function iterator_exact_match(): void
{
$results = $this->createWithItems(3);

$this->assertSame(['1', '2', '3'], \iterator_to_array($results));
}

protected function expectedValueAt(int $position)
{
return (string) $position;
Expand Down

0 comments on commit fc12693

Please sign in to comment.