Skip to content

Commit ad2cca2

Browse files
committed
Add GROUP BY support to fetch
1 parent 1d37f22 commit ad2cca2

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

src/Query/GroupBy.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WyriHaximus\React\SimpleORM\Query;
6+
7+
final class GroupBy implements SectionInterface
8+
{
9+
/** @var array<string> */
10+
private array $columns = [];
11+
12+
public function __construct(string ...$columns)
13+
{
14+
$this->columns = $columns;
15+
}
16+
17+
/**
18+
* @return iterable<string>
19+
*/
20+
public function columns(): iterable
21+
{
22+
yield from $this->columns;
23+
}
24+
}

src/Repository.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Rx\Scheduler\ImmediateScheduler;
1818
use Safe\DateTimeImmutable;
1919
use WyriHaximus\React\SimpleORM\Annotation\JoinInterface;
20+
use WyriHaximus\React\SimpleORM\Query\GroupBy;
2021
use WyriHaximus\React\SimpleORM\Query\Limit;
2122
use WyriHaximus\React\SimpleORM\Query\Order;
2223
use WyriHaximus\React\SimpleORM\Query\SectionInterface;
@@ -25,6 +26,7 @@
2526
use WyriHaximus\React\SimpleORM\Query\Where\Field;
2627

2728
use function array_key_exists;
29+
use function array_map;
2830
use function array_values;
2931
use function explode;
3032
use function is_scalar;
@@ -37,6 +39,7 @@
3739
use function Safe\substr;
3840
use function spl_object_hash;
3941
use function strpos;
42+
use function WyriHaximus\iteratorOrArrayToArray;
4043

4144
use const WyriHaximus\Constants\Boolean\TRUE_;
4245
use const WyriHaximus\Constants\Numeric\ONE;
@@ -184,6 +187,16 @@ private function buildSelectQuery(SectionInterface ...$sections): SelectQuery
184187
$query = $query->orderBy($field, $by->order());
185188
}
186189

190+
break;
191+
case $section instanceof GroupBy:
192+
/**
193+
* @psalm-suppress ArgumentTypeCoercion
194+
* @psalm-suppress UndefinedInterfaceMethod
195+
*/
196+
$query = $query->groupBy(array_map(
197+
fn (string $column): string => $this->translateFieldName($column),
198+
iteratorOrArrayToArray($section->columns())
199+
));
187200
break;
188201
}
189202
}

tests/FunctionalTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use WyriHaximus\React\SimpleORM\Client;
1515
use WyriHaximus\React\SimpleORM\ClientInterface;
1616
use WyriHaximus\React\SimpleORM\Middleware\QueryCountMiddleware;
17+
use WyriHaximus\React\SimpleORM\Query\GroupBy;
1718
use WyriHaximus\React\SimpleORM\Query\Limit;
1819
use WyriHaximus\React\SimpleORM\Query\Where;
1920
use WyriHaximus\React\Tests\SimpleORM\Stub\BlogPostStub;
@@ -584,4 +585,15 @@ public function countWithConstraints(): void
584585
$count = $this->await($repository->count(new Where(new Where\Field('author_id', 'eq', ['fb175cbc-04cc-41c7-8e35-6b817ac016ca']))), $this->loop, self::AWAIT_TIMEOUT);
585586
self::assertSame(1, $count);
586587
}
588+
589+
/**
590+
* @test
591+
*/
592+
public function groupBy(): void
593+
{
594+
$repository = $this->client->repository(BlogPostStub::class);
595+
596+
$count = $this->await($repository->fetch(new GroupBy('author_id'))->count()->toPromise(), $this->loop, self::AWAIT_TIMEOUT);
597+
self::assertSame(1, $count);
598+
}
587599
}

0 commit comments

Comments
 (0)