Skip to content

Commit 81f3eb6

Browse files
author
codeliner
committed
Handle new EE filters
1 parent e7c2b6f commit 81f3eb6

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

src/PostgresDocumentStore.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,15 @@ private function filterToWhereClause(Filter $filter, $argsCount = 0): array
393393
}
394394

395395
switch (get_class($filter)) {
396+
case DocumentStore\Filter\DocIdFilter::class:
397+
/** @var DocumentStore\Filter\DocIdFilter $filter */
398+
return ["id = :a$argsCount", ["a$argsCount" => $filter->val()], ++$argsCount];
399+
case DocumentStore\Filter\AnyOfDocIdFilter::class:
400+
/** @var DocumentStore\Filter\AnyOfDocIdFilter $filter */
401+
return $this->makeInClause('id', $filter->valList(), $argsCount);
402+
case DocumentStore\Filter\AnyOfFilter::class:
403+
/** @var DocumentStore\Filter\AnyOfFilter $filter */
404+
return $this->makeInClause($this->propToJsonPath($filter->prop()), $filter->valList(), $argsCount, true);
396405
case DocumentStore\Filter\EqFilter::class:
397406
/** @var DocumentStore\Filter\EqFilter $filter */
398407
$prop = $this->propToJsonPath($filter->prop());
@@ -430,6 +439,12 @@ private function filterToWhereClause(Filter $filter, $argsCount = 0): array
430439

431440
[$innerFilterStr, $args, $argsCount] = $this->filterToWhereClause($innerFilter);
432441

442+
if($innerFilter instanceof DocumentStore\Filter\AnyOfFilter || $innerFilter instanceof DocumentStore\Filter\AnyOfDocIdFilter) {
443+
$inPos = strpos($innerFilterStr, ' IN(');
444+
$filterStr = substr_replace($innerFilterStr, ' NOT IN(', $inPos, 4 /* " IN(" */);
445+
return [$filterStr, $args, $argsCount];
446+
}
447+
433448
return ["NOT $innerFilterStr", $args, $argsCount];
434449
case DocumentStore\Filter\InArrayFilter::class:
435450
/** @var DocumentStore\Filter\InArrayFilter $filter */
@@ -464,6 +479,19 @@ private function isPropFilter(Filter $filter): bool
464479
}
465480
}
466481

482+
private function makeInClause(string $prop, array $valList, int $argsCount, bool $jsonEncode = false): array
483+
{
484+
$argList = [];
485+
$params = \implode(",", \array_map(function ($val) use (&$argsCount, &$argList, $jsonEncode) {
486+
$param = ":a$argsCount";
487+
$argList["a$argsCount"] = $jsonEncode? \json_encode($val) : $val;
488+
$argsCount++;
489+
return $param;
490+
}, $valList));
491+
492+
return ["$prop IN($params)", $argList, $argsCount];
493+
}
494+
467495
private function orderByToSort(DocumentStore\OrderBy\OrderBy $orderBy): array
468496
{
469497
$sort = [];

tests/PostgresDocumentStoreTest.php

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@
1111

1212
namespace EventEngine\DocumentStoreTest\Postgres;
1313

14+
use EventEngine\DocumentStore\Filter\AnyOfDocIdFilter;
15+
use EventEngine\DocumentStore\Filter\AnyOfFilter;
16+
use EventEngine\DocumentStore\Filter\DocIdFilter;
17+
use EventEngine\DocumentStore\Filter\NotFilter;
1418
use PHPUnit\Framework\TestCase;
1519
use EventEngine\DocumentStore\FieldIndex;
1620
use EventEngine\DocumentStore\Index;
1721
use EventEngine\DocumentStore\MultiFieldIndex;
1822
use EventEngine\DocumentStore\Postgres\PostgresDocumentStore;
23+
use Ramsey\Uuid\Uuid;
1924

2025
class PostgresDocumentStoreTest extends TestCase
2126
{
@@ -134,6 +139,146 @@ public function it_adds_collection_with_multi_field_index_unique(): void
134139
$this->assertStringStartsWith('CREATE UNIQUE INDEX', $indexes[1]['indexdef']);
135140
}
136141

142+
/**
143+
* @test
144+
*/
145+
public function it_handles_any_of_filter()
146+
{
147+
$collectionName = 'test_any_of_filter';
148+
$this->documentStore->addCollection($collectionName);
149+
150+
$doc1 = ["foo" => "bar"];
151+
$doc2 = ["foo" => "baz"];
152+
$doc3 = ["foo" => "bat"];
153+
154+
$docs = [$doc1, $doc2, $doc3];
155+
156+
array_walk($docs, function (array $doc) use ($collectionName) {
157+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), $doc);
158+
});
159+
160+
$filteredDocs = $this->documentStore->filterDocs(
161+
$collectionName,
162+
new AnyOfFilter("foo", ["bar", "bat"])
163+
);
164+
165+
$this->assertCount(2, $filteredDocs);
166+
}
167+
168+
/**
169+
* @test
170+
*/
171+
public function it_handles_not_any_of_filter()
172+
{
173+
$collectionName = 'test_not_any_of_filter';
174+
$this->documentStore->addCollection($collectionName);
175+
176+
$doc1 = ["foo" => "bar"];
177+
$doc2 = ["foo" => "baz"];
178+
$doc3 = ["foo" => "bat"];
179+
180+
$docs = [$doc1, $doc2, $doc3];
181+
182+
array_walk($docs, function (array $doc) use ($collectionName) {
183+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), $doc);
184+
});
185+
186+
$filteredDocs = $this->documentStore->filterDocs(
187+
$collectionName,
188+
new NotFilter(new AnyOfFilter("foo", ["bar", "bat"]))
189+
);
190+
191+
$filteredDocs = iterator_to_array($filteredDocs);
192+
193+
$this->assertCount(1, $filteredDocs);
194+
195+
$this->assertSame('baz', $filteredDocs[0]['foo']);
196+
}
197+
198+
/**
199+
* @test
200+
*/
201+
public function it_handles_doc_id_filter()
202+
{
203+
$collectionName = 'test_doc_id_filter';
204+
$this->documentStore->addCollection($collectionName);
205+
206+
$firstDocId = Uuid::uuid4()->toString();
207+
$secondDocId = Uuid::uuid4()->toString();
208+
209+
$this->documentStore->addDoc($collectionName, $firstDocId, ['foo' => 'bar']);
210+
$this->documentStore->addDoc($collectionName, $secondDocId, ['foo' => 'bat']);
211+
212+
$filteredDocs = \iterator_to_array($this->documentStore->filterDocs(
213+
$collectionName,
214+
new DocIdFilter($secondDocId)
215+
));
216+
217+
$this->assertCount(1, $filteredDocs);
218+
219+
$this->assertSame('bat', $filteredDocs[0]['foo']);
220+
}
221+
222+
/**
223+
* @test
224+
*/
225+
public function it_handles_any_of_doc_id_filter()
226+
{
227+
$collectionName = 'test_any_of_doc_id_filter';
228+
$this->documentStore->addCollection($collectionName);
229+
230+
$firstDocId = Uuid::uuid4()->toString();
231+
$secondDocId = Uuid::uuid4()->toString();
232+
$thirdDocId = Uuid::uuid4()->toString();
233+
234+
$this->documentStore->addDoc($collectionName, $firstDocId, ['foo' => 'bar']);
235+
$this->documentStore->addDoc($collectionName, $secondDocId, ['foo' => 'bat']);
236+
$this->documentStore->addDoc($collectionName, $thirdDocId, ['foo' => 'baz']);
237+
238+
$filteredDocs = \iterator_to_array($this->documentStore->filterDocs(
239+
$collectionName,
240+
new AnyOfDocIdFilter([$firstDocId, $thirdDocId])
241+
));
242+
243+
$this->assertCount(2, $filteredDocs);
244+
245+
$vals = array_map(function (array $doc) {
246+
return $doc['foo'];
247+
}, $filteredDocs);
248+
249+
$this->assertEquals(['bar', 'baz'], $vals);
250+
}
251+
252+
/**
253+
* @test
254+
*/
255+
public function it_handles_not_any_of_id_filter()
256+
{
257+
$collectionName = 'test_any_of_doc_id_filter';
258+
$this->documentStore->addCollection($collectionName);
259+
260+
$firstDocId = Uuid::uuid4()->toString();
261+
$secondDocId = Uuid::uuid4()->toString();
262+
$thirdDocId = Uuid::uuid4()->toString();
263+
264+
$this->documentStore->addDoc($collectionName, $firstDocId, ['foo' => 'bar']);
265+
$this->documentStore->addDoc($collectionName, $secondDocId, ['foo' => 'bat']);
266+
$this->documentStore->addDoc($collectionName, $thirdDocId, ['foo' => 'baz']);
267+
268+
$filteredDocs = \iterator_to_array($this->documentStore->filterDocs(
269+
$collectionName,
270+
new NotFilter(new AnyOfDocIdFilter([$firstDocId, $thirdDocId]))
271+
));
272+
273+
$this->assertCount(1, $filteredDocs);
274+
275+
$vals = array_map(function (array $doc) {
276+
return $doc['foo'];
277+
}, $filteredDocs);
278+
279+
$this->assertEquals(['bat'], $vals);
280+
}
281+
137282
private function getIndexes(string $collectionName): array
138283
{
139284
$stmt = $this->connection->prepare(

0 commit comments

Comments
 (0)