From ad2cca2814f1e973e3877a1800606599a9fb132e Mon Sep 17 00:00:00 2001 From: Cees-Jan Kiewiet Date: Sat, 3 Apr 2021 09:41:11 +0200 Subject: [PATCH] Add GROUP BY support to fetch --- src/Query/GroupBy.php | 24 ++++++++++++++++++++++++ src/Repository.php | 13 +++++++++++++ tests/FunctionalTest.php | 12 ++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 src/Query/GroupBy.php diff --git a/src/Query/GroupBy.php b/src/Query/GroupBy.php new file mode 100644 index 0000000..3ffa00e --- /dev/null +++ b/src/Query/GroupBy.php @@ -0,0 +1,24 @@ + */ + private array $columns = []; + + public function __construct(string ...$columns) + { + $this->columns = $columns; + } + + /** + * @return iterable + */ + public function columns(): iterable + { + yield from $this->columns; + } +} diff --git a/src/Repository.php b/src/Repository.php index 5a8b22a..dd1aa39 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -17,6 +17,7 @@ use Rx\Scheduler\ImmediateScheduler; use Safe\DateTimeImmutable; use WyriHaximus\React\SimpleORM\Annotation\JoinInterface; +use WyriHaximus\React\SimpleORM\Query\GroupBy; use WyriHaximus\React\SimpleORM\Query\Limit; use WyriHaximus\React\SimpleORM\Query\Order; use WyriHaximus\React\SimpleORM\Query\SectionInterface; @@ -25,6 +26,7 @@ use WyriHaximus\React\SimpleORM\Query\Where\Field; use function array_key_exists; +use function array_map; use function array_values; use function explode; use function is_scalar; @@ -37,6 +39,7 @@ use function Safe\substr; use function spl_object_hash; use function strpos; +use function WyriHaximus\iteratorOrArrayToArray; use const WyriHaximus\Constants\Boolean\TRUE_; use const WyriHaximus\Constants\Numeric\ONE; @@ -184,6 +187,16 @@ private function buildSelectQuery(SectionInterface ...$sections): SelectQuery $query = $query->orderBy($field, $by->order()); } + break; + case $section instanceof GroupBy: + /** + * @psalm-suppress ArgumentTypeCoercion + * @psalm-suppress UndefinedInterfaceMethod + */ + $query = $query->groupBy(array_map( + fn (string $column): string => $this->translateFieldName($column), + iteratorOrArrayToArray($section->columns()) + )); break; } } diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index 33722c4..73b2f20 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -14,6 +14,7 @@ use WyriHaximus\React\SimpleORM\Client; use WyriHaximus\React\SimpleORM\ClientInterface; use WyriHaximus\React\SimpleORM\Middleware\QueryCountMiddleware; +use WyriHaximus\React\SimpleORM\Query\GroupBy; use WyriHaximus\React\SimpleORM\Query\Limit; use WyriHaximus\React\SimpleORM\Query\Where; use WyriHaximus\React\Tests\SimpleORM\Stub\BlogPostStub; @@ -584,4 +585,15 @@ public function countWithConstraints(): void $count = $this->await($repository->count(new Where(new Where\Field('author_id', 'eq', ['fb175cbc-04cc-41c7-8e35-6b817ac016ca']))), $this->loop, self::AWAIT_TIMEOUT); self::assertSame(1, $count); } + + /** + * @test + */ + public function groupBy(): void + { + $repository = $this->client->repository(BlogPostStub::class); + + $count = $this->await($repository->fetch(new GroupBy('author_id'))->count()->toPromise(), $this->loop, self::AWAIT_TIMEOUT); + self::assertSame(1, $count); + } }