Skip to content

Commit 28cd7c1

Browse files
authored
Merge pull request #37 from WyriHaximus/add-constraint-support-to-count
Add constraint support to count
2 parents c47854a + 2d57ce7 commit 28cd7c1

File tree

4 files changed

+74
-9
lines changed

4 files changed

+74
-9
lines changed

src/Repository.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,16 @@ public function __construct(InspectedEntityInterface $entity, ClientInterface $c
6666
$this->hydrator = new Hydrator();
6767
}
6868

69-
public function count(): PromiseInterface
69+
/** @phpstan-ignore-next-line */
70+
public function count(?Where $where = null): PromiseInterface
7071
{
72+
$query = $this->queryFactory->select(alias(func('COUNT', '*'), 'count'))->from(alias($this->entity->table(), 't0'));
73+
if ($where instanceof Where) {
74+
$query = $this->applyWhereToQuery($where, $query);
75+
}
76+
7177
return $this->client->query(
72-
$this->queryFactory->select(alias(func('COUNT', '*'), 'count'))->from($this->entity->table())->asExpression()
78+
$query->asExpression()
7379
)->take(self::SINGLE)->toPromise()->then(static function (array $row): int {
7480
return (int) $row['count'];
7581
});
@@ -147,9 +153,19 @@ public function delete(EntityInterface $entity): PromiseInterface
147153
private function buildSelectQuery(Where $constraints, Order $order): SelectQuery
148154
{
149155
$query = $this->buildBaseSelectQuery();
150-
151156
$query = $query->columns(...array_values($this->fields));
157+
$query = $this->applyWhereToQuery($constraints, $query);
158+
159+
foreach ($order->orders() as $by) {
160+
$field = $this->translateFieldName($by->field());
161+
$query = $query->orderBy($field, $by->order());
162+
}
152163

164+
return $query;
165+
}
166+
167+
private function applyWhereToQuery(Where $constraints, SelectQuery $query): SelectQuery
168+
{
153169
foreach ($constraints->wheres() as $i => $constraint) {
154170
if ($constraint instanceof Expression) {
155171
$where = $constraint->expression();
@@ -169,11 +185,6 @@ private function buildSelectQuery(Where $constraints, Order $order): SelectQuery
169185
$query = $query->andWhere($where);
170186
}
171187

172-
foreach ($order->orders() as $by) {
173-
$field = $this->translateFieldName($by->field());
174-
$query = $query->orderBy($field, $by->order());
175-
}
176-
177188
return $query;
178189
}
179190

src/RepositoryInterface.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ interface RepositoryInterface
1313
{
1414
public const DEFAULT_PER_PAGE = 50;
1515

16-
public function count(): PromiseInterface;
16+
/** @phpstan-ignore-next-line */
17+
public function count(?Where $where = null): PromiseInterface;
1718

1819
/** @phpstan-ignore-next-line */
1920
public function page(int $page, ?Where $where = null, ?Order $order = null, int $perPage = self::DEFAULT_PER_PAGE): Observable;

tests/FunctionalTest.php

Lines changed: 23 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\Where;
1718
use WyriHaximus\React\Tests\SimpleORM\Stub\BlogPostStub;
1819
use WyriHaximus\React\Tests\SimpleORM\Stub\CommentStub;
1920
use WyriHaximus\React\Tests\SimpleORM\Stub\UserStub;
@@ -560,4 +561,26 @@ public function userSelf(): void
560561
'completed' => 2,
561562
], iteratorOrArrayToArray($this->counter->counters()));
562563
}
564+
565+
/**
566+
* @test
567+
*/
568+
public function countWithoutConstraints(): void
569+
{
570+
$repository = $this->client->repository(BlogPostStub::class);
571+
572+
$count = $this->await($repository->count(), $this->loop, self::AWAIT_TIMEOUT);
573+
self::assertSame(2, $count);
574+
}
575+
576+
/**
577+
* @test
578+
*/
579+
public function countWithConstraints(): void
580+
{
581+
$repository = $this->client->repository(BlogPostStub::class);
582+
583+
$count = $this->await($repository->count(new Where(new Where\Field('author_id', 'eq', ['fb175cbc-04cc-41c7-8e35-6b817ac016ca']))), $this->loop, self::AWAIT_TIMEOUT);
584+
self::assertSame(1, $count);
585+
}
563586
}

tests/RepositoryTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,36 @@ public function testCount(): void
6161
self::assertSame(123, $this->await($repository->count()));
6262
}
6363

64+
public function testCountWithContraints(): void
65+
{
66+
$this->client->query(Argument::that(static function (ExpressionInterface $expression): bool {
67+
self::assertCount(1, $expression->params(new PostgresEngine()));
68+
$query = $expression->sql(new PostgresEngine());
69+
self::assertStringContainsString('FROM "users"', $query);
70+
self::assertStringContainsString('COUNT(*) AS "count"', $query);
71+
self::assertStringContainsString('WHERE "t0"."field" = ?', $query);
72+
73+
return true;
74+
}))->shouldBeCalled()->willReturn(observableFromArray([
75+
['count' => '123'],
76+
]));
77+
78+
$client = $this->client->reveal();
79+
assert($client instanceof ClientInterface);
80+
81+
$repository = new Repository(
82+
(new EntityInspector(new AnnotationReader()))->entity(UserStub::class),
83+
$client,
84+
new QueryFactory()
85+
);
86+
87+
self::assertSame(123, $this->await($repository->count(
88+
new Where(
89+
new Where\Field('field', 'eq', ['values']),
90+
),
91+
)));
92+
}
93+
6494
public function testCountWithJoins(): void
6595
{
6696
$this->client->repository(CommentStub::class)->shouldNotBeCalled();

0 commit comments

Comments
 (0)