From 11b9c4ade00998b6d5ee84ce080a4145d683cc02 Mon Sep 17 00:00:00 2001 From: codeliner Date: Wed, 2 Oct 2019 22:13:19 +0200 Subject: [PATCH] Fix InArray filter for object items --- src/PostgresDocumentStore.php | 2 +- tests/PostgresDocumentStoreTest.php | 91 ++++++++++++++++++++++ tests/SchemedPostgresDocumentStoreTest.php | 2 +- tests/TestUtil.php | 1 + 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/PostgresDocumentStore.php b/src/PostgresDocumentStore.php index 9c70dec..f80b3fa 100644 --- a/src/PostgresDocumentStore.php +++ b/src/PostgresDocumentStore.php @@ -621,7 +621,7 @@ private function filterToWhereClause(Filter $filter, $argsCount = 0): array case DocumentStore\Filter\InArrayFilter::class: /** @var DocumentStore\Filter\InArrayFilter $filter */ $prop = $this->propToJsonPath($filter->prop()); - return ["$prop @> :a$argsCount", ["a$argsCount" => $this->prepareVal($filter->val(), $filter->prop())], ++$argsCount]; + return ["$prop @> :a$argsCount", ["a$argsCount" => '[' . $this->prepareVal($filter->val(), $filter->prop()) . ']'], ++$argsCount]; case DocumentStore\Filter\ExistsFilter::class: /** @var DocumentStore\Filter\ExistsFilter $filter */ $prop = $this->propToJsonPath($filter->prop()); diff --git a/tests/PostgresDocumentStoreTest.php b/tests/PostgresDocumentStoreTest.php index fbfd40f..f42ea9c 100644 --- a/tests/PostgresDocumentStoreTest.php +++ b/tests/PostgresDocumentStoreTest.php @@ -14,6 +14,7 @@ use EventEngine\DocumentStore\Filter\AnyOfDocIdFilter; use EventEngine\DocumentStore\Filter\AnyOfFilter; use EventEngine\DocumentStore\Filter\DocIdFilter; +use EventEngine\DocumentStore\Filter\InArrayFilter; use EventEngine\DocumentStore\Filter\NotFilter; use PHPUnit\Framework\TestCase; use EventEngine\DocumentStore\FieldIndex; @@ -305,6 +306,96 @@ public function it_handles_not_any_of_id_filter() $this->assertEquals(['bat'], $vals); } + /** + * @test + */ + public function it_handles_in_array_filter() + { + $collectionName = 'test_in_array_filter'; + $this->documentStore->addCollection($collectionName); + + $firstDocId = Uuid::uuid4()->toString(); + $secondDocId = Uuid::uuid4()->toString(); + $thirdDocId = Uuid::uuid4()->toString(); + + $this->documentStore->addDoc($collectionName, $firstDocId, ['foo' => ['bar' => ['tag1', 'tag2'], 'ref' => $firstDocId]]); + $this->documentStore->addDoc($collectionName, $secondDocId, ['foo' => ['bar' => ['tag2', 'tag3'], 'ref' => $secondDocId]]); + $this->documentStore->addDoc($collectionName, $thirdDocId, ['foo' => ['bar' => ['tag3', 'tag4'], 'ref' => $thirdDocId]]); + + $filteredDocs = \iterator_to_array($this->documentStore->filterDocs( + $collectionName, + new InArrayFilter('foo.bar', 'tag3') + )); + + $this->assertCount(2, $filteredDocs); + + $refs = array_map(function (array $doc) { + return $doc['foo']['ref']; + }, $filteredDocs); + + $this->assertEquals([$secondDocId, $thirdDocId], $refs); + } + + /** + * @test + */ + public function it_handles_not_in_array_filter() + { + $collectionName = 'test_not_in_array_filter'; + $this->documentStore->addCollection($collectionName); + + $firstDocId = Uuid::uuid4()->toString(); + $secondDocId = Uuid::uuid4()->toString(); + $thirdDocId = Uuid::uuid4()->toString(); + + $this->documentStore->addDoc($collectionName, $firstDocId, ['foo' => ['bar' => ['tag1', 'tag2'], 'ref' => $firstDocId]]); + $this->documentStore->addDoc($collectionName, $secondDocId, ['foo' => ['bar' => ['tag2', 'tag3'], 'ref' => $secondDocId]]); + $this->documentStore->addDoc($collectionName, $thirdDocId, ['foo' => ['bar' => ['tag3', 'tag4'], 'ref' => $thirdDocId]]); + + $filteredDocs = \iterator_to_array($this->documentStore->filterDocs( + $collectionName, + new NotFilter(new InArrayFilter('foo.bar', 'tag3')) + )); + + $this->assertCount(1, $filteredDocs); + + $refs = array_map(function (array $doc) { + return $doc['foo']['ref']; + }, $filteredDocs); + + $this->assertEquals([$firstDocId], $refs); + } + + /** + * @test + */ + public function it_handles_in_array_filter_with_object_items() + { + $collectionName = 'test_in_array_with_object_filter'; + $this->documentStore->addCollection($collectionName); + + $firstDocId = Uuid::uuid4()->toString(); + $secondDocId = Uuid::uuid4()->toString(); + $thirdDocId = Uuid::uuid4()->toString(); + + $this->documentStore->addDoc($collectionName, $firstDocId, ['foo' => ['bar' => [['tag' => 'tag1', 'other' => 'data'], ['tag' => 'tag2']], 'ref' => $firstDocId]]); + $this->documentStore->addDoc($collectionName, $secondDocId, ['foo' => ['bar' => [['tag' => 'tag2', 'other' => 'data'], ['tag' => 'tag3']], 'ref' => $secondDocId]]); + $this->documentStore->addDoc($collectionName, $thirdDocId, ['foo' => ['bar' => [['tag' => 'tag3', 'other' => 'data'], ['tag' => 'tag4']], 'ref' => $thirdDocId]]); + + $filteredDocs = \iterator_to_array($this->documentStore->filterDocs( + $collectionName, + new InArrayFilter('foo.bar', ['tag' => 'tag3']) + )); + + $this->assertCount(2, $filteredDocs); + + $refs = array_map(function (array $doc) { + return $doc['foo']['ref']; + }, $filteredDocs); + + $this->assertEquals([$secondDocId, $thirdDocId], $refs); + } + private function getIndexes(string $collectionName): array { return TestUtil::getIndexes($this->connection, self::TABLE_PREFIX.$collectionName); diff --git a/tests/SchemedPostgresDocumentStoreTest.php b/tests/SchemedPostgresDocumentStoreTest.php index 8e54346..4c513ad 100644 --- a/tests/SchemedPostgresDocumentStoreTest.php +++ b/tests/SchemedPostgresDocumentStoreTest.php @@ -43,7 +43,7 @@ protected function setUp(): void $this->documentStore = new PostgresDocumentStore($this->connection, self::TABLE_PREFIX); } - public function tearDown(): void + protected function tearDown(): void { TestUtil::tearDownDatabase(); } diff --git a/tests/TestUtil.php b/tests/TestUtil.php index fe263d0..8ce61bf 100644 --- a/tests/TestUtil.php +++ b/tests/TestUtil.php @@ -86,6 +86,7 @@ public static function tearDownDatabase(): void $connection = self::getConnection(); $statement = $connection->prepare('SELECT table_name FROM information_schema.tables WHERE table_schema = \'public\';'); $connection->exec('DROP SCHEMA IF EXISTS prooph CASCADE'); + $connection->exec('DROP SCHEMA IF EXISTS test CASCADE'); $statement->execute(); $tables = $statement->fetchAll(PDO::FETCH_COLUMN);