Skip to content

Commit 89bf210

Browse files
authored
Merge pull request #44 from WyriHaximus/refactor-fetch-method-to-support-more-dynamic-fetching
Refactor fetch to support more dynamic fetching
2 parents f1ae2ab + 3d82671 commit 89bf210

File tree

8 files changed

+75
-18
lines changed

8 files changed

+75
-18
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ seeds:
4444
syntax-php: ## Lint PHP syntax
4545
$(DOCKER_RUN) vendor/bin/parallel-lint --exclude vendor .
4646

47-
cs-fix: ## Fix any automatically fixable code style issues ###
47+
cs-fix: ## Fix any automatically fixable code style issues
4848
$(DOCKER_RUN) vendor/bin/phpcbf --parallel=$(THREADS) --cache=./var/.phpcs.cache.json --standard=./etc/qa/phpcs.xml || $(DOCKER_RUN) vendor/bin/phpcbf --parallel=$(THREADS) --cache=./var/.phpcs.cache.json --standard=./etc/qa/phpcs.xml || $(DOCKER_RUN) vendor/bin/phpcbf --parallel=$(THREADS) --cache=./var/.phpcs.cache.json --standard=./etc/qa/phpcs.xml -vvvv
4949

5050
cs: ## Check the code for code style issues

src/Query/Limit.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WyriHaximus\React\SimpleORM\Query;
6+
7+
final class Limit implements SectionInterface
8+
{
9+
private int $limit;
10+
11+
public function __construct(int $limit)
12+
{
13+
$this->limit = $limit;
14+
}
15+
16+
public function limit(): int
17+
{
18+
return $this->limit;
19+
}
20+
}

src/Query/Order.php

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

55
namespace WyriHaximus\React\SimpleORM\Query;
66

7-
final class Order
7+
final class Order implements SectionInterface
88
{
99
/** @var array<OrderInterface> */
1010
private array $orders = [];

src/Query/SectionInterface.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WyriHaximus\React\SimpleORM\Query;
6+
7+
interface SectionInterface
8+
{
9+
}

src/Query/Where.php

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

55
namespace WyriHaximus\React\SimpleORM\Query;
66

7-
final class Where
7+
final class Where implements SectionInterface
88
{
99
/** @var array<WhereInterface> */
1010
private array $wheres = [];

src/Repository.php

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
use Rx\Scheduler\ImmediateScheduler;
1818
use Safe\DateTimeImmutable;
1919
use WyriHaximus\React\SimpleORM\Annotation\JoinInterface;
20+
use WyriHaximus\React\SimpleORM\Query\Limit;
2021
use WyriHaximus\React\SimpleORM\Query\Order;
22+
use WyriHaximus\React\SimpleORM\Query\SectionInterface;
2123
use WyriHaximus\React\SimpleORM\Query\Where;
2224
use WyriHaximus\React\SimpleORM\Query\Where\Expression;
2325
use WyriHaximus\React\SimpleORM\Query\Where\Field;
@@ -36,6 +38,7 @@
3638
use function spl_object_hash;
3739
use function strpos;
3840

41+
use const WyriHaximus\Constants\Boolean\TRUE_;
3942
use const WyriHaximus\Constants\Numeric\ONE;
4043
use const WyriHaximus\Constants\Numeric\ZERO;
4144

@@ -90,12 +93,20 @@ public function page(int $page, ?Where $where = null, ?Order $order = null, int
9093
return $this->fetchAndHydrate($query);
9194
}
9295

93-
/** @phpstan-ignore-next-line */
94-
public function fetch(?Where $where = null, ?Order $order = null, int $limit = ZERO): Observable
96+
/**
97+
* @param array<SectionInterface> $sections
98+
*
99+
* @phpstan-ignore-next-line
100+
*/
101+
public function fetch(SectionInterface ...$sections): Observable
95102
{
96-
$query = $this->buildSelectQuery($where ?? new Where(), $order ?? new Order());
97-
if ($limit > ZERO) {
98-
$query = $query->limit($limit)->offset(ZERO);
103+
$query = $this->buildSelectQuery(...$sections);
104+
foreach ($sections as $section) {
105+
if (! ($section instanceof Limit) || $section->limit() <= ZERO) {
106+
continue;
107+
}
108+
109+
$query = $query->limit($section->limit())->offset(ZERO);
99110
}
100111

101112
return $this->fetchAndHydrate($query);
@@ -138,7 +149,7 @@ public function update(EntityInterface $entity): PromiseInterface
138149
)->toPromise()->then(function () use ($entity): PromiseInterface {
139150
return $this->fetch(new Where(
140151
new Where\Field('id', 'eq', [$entity->id()]),
141-
), new Order(), ONE)->toPromise();
152+
), new Limit(ONE))->toPromise();
142153
});
143154
}
144155

@@ -150,15 +161,31 @@ public function delete(EntityInterface $entity): PromiseInterface
150161
)->toPromise();
151162
}
152163

153-
private function buildSelectQuery(Where $constraints, Order $order): SelectQuery
164+
/**
165+
* @param array<SectionInterface> $sections
166+
*
167+
* @phpstan-ignore-next-line
168+
*/
169+
private function buildSelectQuery(SectionInterface ...$sections): SelectQuery
154170
{
155171
$query = $this->buildBaseSelectQuery();
156172
$query = $query->columns(...array_values($this->fields));
157-
$query = $this->applyWhereToQuery($constraints, $query);
173+
foreach ($sections as $section) {
174+
/** @phpstan-ignore-next-line */
175+
switch (TRUE_) {
176+
case $section instanceof Where:
177+
/** @psalm-suppress ArgumentTypeCoercion */
178+
$query = $this->applyWhereToQuery($section, $query);
179+
break;
180+
case $section instanceof Order:
181+
/** @psalm-suppress UndefinedInterfaceMethod */
182+
foreach ($section->orders() as $by) {
183+
$field = $this->translateFieldName($by->field());
184+
$query = $query->orderBy($field, $by->order());
185+
}
158186

159-
foreach ($order->orders() as $by) {
160-
$field = $this->translateFieldName($by->field());
161-
$query = $query->orderBy($field, $by->order());
187+
break;
188+
}
162189
}
163190

164191
return $query;
@@ -379,7 +406,7 @@ private function buildTree(array $row, InspectedEntityInterface $entity, string
379406
$this->client
380407
->repository($join->entity()
381408
->class())
382-
->fetch(new Where(...$where), new Order(), self::SINGLE)
409+
->fetch(new Where(...$where), new Limit(self::SINGLE))
383410
->toPromise()
384411
->then($resolve, $reject);
385412
});

src/RepositoryInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use React\Promise\PromiseInterface;
88
use Rx\Observable;
99
use WyriHaximus\React\SimpleORM\Query\Order;
10+
use WyriHaximus\React\SimpleORM\Query\SectionInterface;
1011
use WyriHaximus\React\SimpleORM\Query\Where;
1112

1213
interface RepositoryInterface
@@ -19,8 +20,7 @@ public function count(?Where $where = null): PromiseInterface;
1920
/** @phpstan-ignore-next-line */
2021
public function page(int $page, ?Where $where = null, ?Order $order = null, int $perPage = self::DEFAULT_PER_PAGE): Observable;
2122

22-
/** @phpstan-ignore-next-line */
23-
public function fetch(?Where $where = null, ?Order $order = null, int $limit = 0): Observable;
23+
public function fetch(SectionInterface ...$sections): Observable;
2424

2525
/**
2626
* @param array<string, mixed> $fields

tests/FunctionalTest.php

Lines changed: 2 additions & 1 deletion
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\Limit;
1718
use WyriHaximus\React\SimpleORM\Query\Where;
1819
use WyriHaximus\React\Tests\SimpleORM\Stub\BlogPostStub;
1920
use WyriHaximus\React\Tests\SimpleORM\Stub\CommentStub;
@@ -218,7 +219,7 @@ public function firstBlogPostAuthorIdUsingLimit(): void
218219
self::assertSame(
219220
'fb175cbc-04cc-41c7-8e35-6b817ac016ca',
220221
$this->await(
221-
$this->client->repository(BlogPostStub::class)->fetch(null, null, 1)->toPromise()->then(static function (BlogPostStub $blogPost): string {
222+
$this->client->repository(BlogPostStub::class)->fetch(new Limit(1))->toPromise()->then(static function (BlogPostStub $blogPost): string {
222223
return $blogPost->getAuthor()->id();
223224
}),
224225
$this->loop,

0 commit comments

Comments
 (0)