From d39648da772f94d28208d5d26e4225a132a46878 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Fri, 30 Apr 2021 16:35:50 -0400 Subject: [PATCH 01/13] Create Queries validator to parse indexes --- src/Database/Validator/Queries.php | 82 ++++++++++++++++++++++++ tests/Database/Validator/QueriesTest.php | 54 ++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/Database/Validator/Queries.php create mode 100644 tests/Database/Validator/QueriesTest.php diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php new file mode 100644 index 000000000..dea3971c3 --- /dev/null +++ b/src/Database/Validator/Queries.php @@ -0,0 +1,82 @@ +validator= $validator; + } + + /** + * Get Description. + * + * Returns validator description + * + * @return string + */ + public function getDescription() + { + return $this->message; + } + + /** + * Is valid. + * + * Returns true if all $queries are valid as a set. + * + * @param Query[] $queries + * @param bool $strict + * + * @return bool + */ + public function isValid($queries, $strict = true) + { + return true; + } + /** + * Is array + * + * Function will return true if object is array. + * + * @return bool + */ + public function isArray(): bool + { + return true; + } + + /** + * Get Type + * + * Returns validator type. + * + * @return string + */ + public function getType(): string + { + return self::TYPE_OBJECT; + } +} diff --git a/tests/Database/Validator/QueriesTest.php b/tests/Database/Validator/QueriesTest.php new file mode 100644 index 000000000..d27285ef1 --- /dev/null +++ b/tests/Database/Validator/QueriesTest.php @@ -0,0 +1,54 @@ + 'testindex', + 'type' => 'text', + 'attributes' => [ + 'title', + 'description' + ], + 'orders' => [ + 'ASC', + 'DESC' + ], + ], + [ + '$id' => 'testindex2', + 'type' => 'text', + 'attributes' => [ + 'title', + 'description' + ], + 'orders' => [ + 'ASC', + 'DESC' + ], + ], + ]; + + public function setUp(): void + { + } + + public function tearDown(): void + { + } + + public function testQueries() + { + } + +} From d1bd087a47621461f5270b73cff89d1e8b52d6c8 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Fri, 30 Apr 2021 17:24:17 -0400 Subject: [PATCH 02/13] Construct Queries validator with array of indexes --- src/Database/Validator/Queries.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index dea3971c3..67fa2c236 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -18,16 +18,21 @@ class Queries extends Validator */ protected $validator; + /** + * @var array + */ + protected $indexes = []; /** * Queries constructor * * @param QueryValidator $validator - * @param Query[] $queries + * @param array $indexes */ - public function __construct($validator) + public function __construct($validator, $indexes) { - $this->validator= $validator; + $this->validator = $validator; + $this->indexes = $indexes; } /** From 5869e492342f523e36e21e29f9e2d65062675d5b Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Fri, 30 Apr 2021 17:24:45 -0400 Subject: [PATCH 03/13] Test Queries validator --- tests/Database/Validator/QueriesTest.php | 82 +++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/tests/Database/Validator/QueriesTest.php b/tests/Database/Validator/QueriesTest.php index d27285ef1..cf64b37b8 100644 --- a/tests/Database/Validator/QueriesTest.php +++ b/tests/Database/Validator/QueriesTest.php @@ -9,6 +9,66 @@ class QueriesTest extends TestCase { + /** + * @var array + */ + public $schema = [ + [ + '$id' => 'title', + 'type' => Database::VAR_STRING, + 'size' => 256, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'description', + 'type' => Database::VAR_STRING, + 'size' => 1000000, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'rating', + 'type' => Database::VAR_INTEGER, + 'size' => 5, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'price', + 'type' => Database::VAR_FLOAT, + 'size' => 5, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'published', + 'type' => Database::VAR_BOOLEAN, + 'size' => 5, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'tags', + 'type' => Database::VAR_STRING, + 'size' => 55, + 'required' => true, + 'signed' => true, + 'array' => true, + 'filters' => [], + ], + ]; + /** * @var array */ @@ -39,8 +99,26 @@ class QueriesTest extends TestCase ], ]; + /** + * @var Query[] $queries + */ + protected $queries = []; + + /** + * @var QueryValidator + */ + protected $queryValidator; + public function setUp(): void { + $this->queryValidator= new QueryValidator($this->schema); + + $query1 = Query::parse('title.notEqual("Iron Man", "Ant Man")'); + $query2 = Query::parse('description.equal("Best movie ever")'); + $query3 = Query::parse('rating.greater(4)'); + $query4 = Query::parse('price.lesserEqual(6.50)'); + + array_push($queries, $query1, $query2, $query3, $query4); } public function tearDown(): void @@ -49,6 +127,8 @@ public function tearDown(): void public function testQueries() { - } + $validator = new Queries($this->validator, $this->indexes); + $this->assertEquals(1, 1); + } } From 3029df96bf57cf899ae2a408f6c28efd95a20e99 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Fri, 30 Apr 2021 17:28:16 -0400 Subject: [PATCH 04/13] Check each query isValid --- src/Database/Validator/Queries.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index 67fa2c236..d844cdd9a 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -59,6 +59,29 @@ public function getDescription() */ public function isValid($queries, $strict = true) { + /** + * Array of attributes from $queries + * + * @var string[] + */ + $found = []; + + foreach ($queries as $query) { + // individually validate $query + if (!$this->validator->isValid($query)) { + $this->message = 'Query not valid: ' . $this->validator->getDescription(); + return false; + } + + // $attribute = array_search($query->getAttribute(), $indexes); + // TODO@kodumbeats add logic to check all attributes can be found in a single index + + // if ($strict && !$attribute) { + // $this->message = 'Index does not exist for ' . $query->getAttribute(); + // return false; + // } + } + return true; } /** From 2c32bc2a0db193ecdc63fc5c1c642d4ca44930be Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Mon, 3 May 2021 12:06:25 -0400 Subject: [PATCH 05/13] Fix queries validator tests --- tests/Database/Validator/QueriesTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Database/Validator/QueriesTest.php b/tests/Database/Validator/QueriesTest.php index cf64b37b8..dc1166de9 100644 --- a/tests/Database/Validator/QueriesTest.php +++ b/tests/Database/Validator/QueriesTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use Utopia\Database\Database; use Utopia\Database\Query; +use Utopia\Database\Validator\Queries; class QueriesTest extends TestCase { @@ -118,7 +119,7 @@ public function setUp(): void $query3 = Query::parse('rating.greater(4)'); $query4 = Query::parse('price.lesserEqual(6.50)'); - array_push($queries, $query1, $query2, $query3, $query4); + array_push($this->queries, $query1, $query2, $query3, $query4); } public function tearDown(): void From 42ebc77e0f3d90eb1067bb090e5a2aa681c8ddb5 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Mon, 3 May 2021 13:39:35 -0400 Subject: [PATCH 06/13] Fix queries validator psalm warnings --- src/Database/Validator/Queries.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index d844cdd9a..93b95bb84 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -3,7 +3,7 @@ namespace Utopia\Database\Validator; use Utopia\Validator; -use Utopia\Validator\QueryValidator; +use Utopia\Database\Validator\QueryValidator; use Utopia\Database\Query; class Queries extends Validator @@ -52,21 +52,21 @@ public function getDescription() * * Returns true if all $queries are valid as a set. * - * @param Query[] $queries + * @param mixed $value as array of Query objects * @param bool $strict * * @return bool */ - public function isValid($queries, $strict = true) + public function isValid($value, $strict = true) { /** - * Array of attributes from $queries + * Array of attributes from $value * * @var string[] */ $found = []; - foreach ($queries as $query) { + foreach ($value as $query) { // individually validate $query if (!$this->validator->isValid($query)) { $this->message = 'Query not valid: ' . $this->validator->getDescription(); From 81bec539a3f9017ee2233a5715b61ec2f78056e1 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Mon, 3 May 2021 13:49:07 -0400 Subject: [PATCH 07/13] Set strict validation on validator construction --- src/Database/Validator/Queries.php | 24 +++++++++++++++++++++--- tests/Database/Validator/QueriesTest.php | 11 +++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index 93b95bb84..0f366e41a 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -23,16 +23,23 @@ class Queries extends Validator */ protected $indexes = []; + /** + * @var bool + */ + protected $strict; + /** * Queries constructor * * @param QueryValidator $validator * @param array $indexes + * @param bool $strict */ - public function __construct($validator, $indexes) + public function __construct($validator, $indexes, $strict = true) { $this->validator = $validator; $this->indexes = $indexes; + $this->strict = $strict; } /** @@ -53,11 +60,10 @@ public function getDescription() * Returns true if all $queries are valid as a set. * * @param mixed $value as array of Query objects - * @param bool $strict * * @return bool */ - public function isValid($value, $strict = true) + public function isValid($value) { /** * Array of attributes from $value @@ -107,4 +113,16 @@ public function getType(): string { return self::TYPE_OBJECT; } + + /** + * Is Strict + * + * Returns true if strict validation is set + * + * @return bool + */ + public function isStrict(): bool + { + return $this->strict; + } } diff --git a/tests/Database/Validator/QueriesTest.php b/tests/Database/Validator/QueriesTest.php index dc1166de9..1531854cb 100644 --- a/tests/Database/Validator/QueriesTest.php +++ b/tests/Database/Validator/QueriesTest.php @@ -132,4 +132,15 @@ public function testQueries() $this->assertEquals(1, 1); } + + public function testIsStrict() + { + $validator = new Queries($this->validator, $this->indexes); + + $this->assertEquals(true, $validator->isStrict()); + + $validator = new Queries($this->validator, $this->indexes, false); + + $this->assertEquals(false, $validator->isStrict()); + } } From 6e8c5f65dff0bd022b833b409a0842977c763e6d Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Mon, 3 May 2021 14:55:36 -0400 Subject: [PATCH 08/13] Check for strict order match in indexes --- src/Database/Validator/Queries.php | 28 ++++++++++++++++-------- tests/Database/Validator/QueriesTest.php | 23 +++++++++++++------ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index 0f366e41a..b741a3642 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -66,26 +66,36 @@ public function getDescription() public function isValid($value) { /** - * Array of attributes from $value + * Array of attributes from Query->getAttribute() * * @var string[] */ - $found = []; + $queries = []; foreach ($value as $query) { - // individually validate $query + $queries[] = $query->getAttribute(); + if (!$this->validator->isValid($query)) { $this->message = 'Query not valid: ' . $this->validator->getDescription(); return false; } + } - // $attribute = array_search($query->getAttribute(), $indexes); - // TODO@kodumbeats add logic to check all attributes can be found in a single index + /** + * @var string + */ + $indexId = null; + + // look for strict match among indexes + foreach ($this->indexes as $index) { + if ($index['attributes'] === $queries) { + $indexId = $index['$id']; + } + } - // if ($strict && !$attribute) { - // $this->message = 'Index does not exist for ' . $query->getAttribute(); - // return false; - // } + if (!$indexId) { + $this->message = 'Index not found for ' . implode(",", $queries); + return false; } return true; diff --git a/tests/Database/Validator/QueriesTest.php b/tests/Database/Validator/QueriesTest.php index 1531854cb..adcdb5c9f 100644 --- a/tests/Database/Validator/QueriesTest.php +++ b/tests/Database/Validator/QueriesTest.php @@ -91,7 +91,8 @@ class QueriesTest extends TestCase 'type' => 'text', 'attributes' => [ 'title', - 'description' + 'description', + 'price' ], 'orders' => [ 'ASC', @@ -112,14 +113,12 @@ class QueriesTest extends TestCase public function setUp(): void { - $this->queryValidator= new QueryValidator($this->schema); + $this->queryValidator = new QueryValidator($this->schema); $query1 = Query::parse('title.notEqual("Iron Man", "Ant Man")'); $query2 = Query::parse('description.equal("Best movie ever")'); - $query3 = Query::parse('rating.greater(4)'); - $query4 = Query::parse('price.lesserEqual(6.50)'); - array_push($this->queries, $query1, $query2, $query3, $query4); + array_push($this->queries, $query1, $query2); } public function tearDown(): void @@ -128,9 +127,19 @@ public function tearDown(): void public function testQueries() { - $validator = new Queries($this->validator, $this->indexes); + // test for SUCCESS + $validator = new Queries($this->queryValidator, $this->indexes); + + $this->assertEquals(true, $validator->isValid($this->queries)); + + $this->queries[] = Query::parse('price.lesserEqual(6.50)'); + $this->assertEquals(true, $validator->isValid($this->queries)); + + //test for FAILURE + $this->queries[] = Query::parse('rating.greater(4)'); - $this->assertEquals(1, 1); + $this->assertEquals(false, $validator->isValid($this->queries)); + $this->assertEquals("Index not found for title,description,price,rating", $validator->getDescription()); } public function testIsStrict() From dd0edf8e21ee42e688efdd212129ce1c1b3973f4 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Mon, 3 May 2021 14:58:03 -0400 Subject: [PATCH 09/13] Only check if strict validation enabled --- src/Database/Validator/Queries.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index b741a3642..48323d381 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -86,16 +86,19 @@ public function isValid($value) */ $indexId = null; - // look for strict match among indexes - foreach ($this->indexes as $index) { - if ($index['attributes'] === $queries) { - $indexId = $index['$id']; + // Return false if attributes do not exactly match an index + if ($strict) { + // look for strict match among indexes + foreach ($this->indexes as $index) { + if ($index['attributes'] === $queries) { + $indexId = $index['$id']; + } } - } - if (!$indexId) { - $this->message = 'Index not found for ' . implode(",", $queries); - return false; + if (!$indexId) { + $this->message = 'Index not found for ' . implode(",", $queries); + return false; + } } return true; From 262c20dd0890b9907944c4c228ce01b8f471b25b Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Mon, 3 May 2021 15:34:22 -0400 Subject: [PATCH 10/13] Use strict set on construction --- src/Database/Validator/Queries.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index 48323d381..2fcc4ccd9 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -87,7 +87,7 @@ public function isValid($value) $indexId = null; // Return false if attributes do not exactly match an index - if ($strict) { + if ($this->strict) { // look for strict match among indexes foreach ($this->indexes as $index) { if ($index['attributes'] === $queries) { From acefb9292cb0edb03b85e9169f31f196fb94310c Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Tue, 4 May 2021 16:07:24 -0400 Subject: [PATCH 11/13] Check indexQueue for verbose error messaging --- src/Database/Validator/Queries.php | 30 +++- tests/Database/Validator/QueriesTest.php | 199 +++++++++++++---------- 2 files changed, 138 insertions(+), 91 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index 2fcc4ccd9..f7f7bcc1a 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -23,6 +23,11 @@ class Queries extends Validator */ protected $indexes = []; + /** + * @var array + */ + protected $indexesInQueue = []; + /** * @var bool */ @@ -33,12 +38,14 @@ class Queries extends Validator * * @param QueryValidator $validator * @param array $indexes + * @param array $indexesInQueue * @param bool $strict */ - public function __construct($validator, $indexes, $strict = true) + public function __construct($validator, $indexes, $indexesInQueue, $strict = true) { $this->validator = $validator; $this->indexes = $indexes; + $this->indexesInQueue = $indexesInQueue; $this->strict = $strict; } @@ -58,9 +65,7 @@ public function getDescription() * Is valid. * * Returns true if all $queries are valid as a set. - * * @param mixed $value as array of Query objects - * * @return bool */ public function isValid($value) @@ -85,6 +90,11 @@ public function isValid($value) * @var string */ $indexId = null; + + /** + * @var bool + */ + $queued = false; // Return false if attributes do not exactly match an index if ($this->strict) { @@ -96,7 +106,19 @@ public function isValid($value) } if (!$indexId) { - $this->message = 'Index not found for ' . implode(",", $queries); + // check against the indexesInQueue + foreach ($this->indexesInQueue as $index) { + if ($index['attributes'] === $queries) { + $queued = true; + } + } + + if ($queued) { + $this->message = 'Index still in creation queue: ' . implode(",", $queries); + return false; + } + + $this->message = 'Index not found: ' . implode(",", $queries); return false; } } diff --git a/tests/Database/Validator/QueriesTest.php b/tests/Database/Validator/QueriesTest.php index adcdb5c9f..6e0d41c3e 100644 --- a/tests/Database/Validator/QueriesTest.php +++ b/tests/Database/Validator/QueriesTest.php @@ -10,97 +10,113 @@ class QueriesTest extends TestCase { - /** - * @var array - */ - public $schema = [ - [ - '$id' => 'title', - 'type' => Database::VAR_STRING, - 'size' => 256, - 'required' => true, - 'signed' => true, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => 'description', - 'type' => Database::VAR_STRING, - 'size' => 1000000, - 'required' => true, - 'signed' => true, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => 'rating', - 'type' => Database::VAR_INTEGER, - 'size' => 5, - 'required' => true, - 'signed' => true, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => 'price', - 'type' => Database::VAR_FLOAT, - 'size' => 5, - 'required' => true, - 'signed' => true, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => 'published', - 'type' => Database::VAR_BOOLEAN, - 'size' => 5, - 'required' => true, - 'signed' => true, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => 'tags', - 'type' => Database::VAR_STRING, - 'size' => 55, - 'required' => true, - 'signed' => true, - 'array' => true, - 'filters' => [], - ], - ]; - /** * @var array */ - protected $indexes = [ - [ - '$id' => 'testindex', - 'type' => 'text', - 'attributes' => [ - 'title', - 'description' + protected $collection = [ + '$id' => Database::COLLECTIONS, + '$collection' => Database::COLLECTIONS, + 'name' => 'movies', + 'attributes' => [ + [ + '$id' => 'title', + 'type' => Database::VAR_STRING, + 'size' => 256, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], ], - 'orders' => [ - 'ASC', - 'DESC' + [ + '$id' => 'description', + 'type' => Database::VAR_STRING, + 'size' => 1000000, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'rating', + 'type' => Database::VAR_INTEGER, + 'size' => 5, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'price', + 'type' => Database::VAR_FLOAT, + 'size' => 5, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'published', + 'type' => Database::VAR_BOOLEAN, + 'size' => 5, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'tags', + 'type' => Database::VAR_STRING, + 'size' => 55, + 'required' => true, + 'signed' => true, + 'array' => true, + 'filters' => [], ], ], - [ - '$id' => 'testindex2', - 'type' => 'text', - 'attributes' => [ - 'title', - 'description', - 'price' + 'indexes' => [ + [ + '$id' => 'testindex', + 'type' => 'text', + 'attributes' => [ + 'title', + 'description' + ], + 'orders' => [ + 'ASC', + 'DESC' + ], ], - 'orders' => [ - 'ASC', - 'DESC' + [ + '$id' => 'testindex2', + 'type' => 'text', + 'attributes' => [ + 'title', + 'description', + 'price' + ], + 'orders' => [ + 'ASC', + 'DESC' + ], ], ], + 'indexesInQueue' => [ + [ + '$id' => 'testindex3', + 'type' => 'text', + 'attributes' => [ + 'price', + 'title' + ], + 'orders' => [ + 'ASC', + 'DESC' + ] + ] + ] ]; + /** * @var Query[] $queries */ @@ -109,11 +125,11 @@ class QueriesTest extends TestCase /** * @var QueryValidator */ - protected $queryValidator; + protected $queryValidator = null; public function setUp(): void { - $this->queryValidator = new QueryValidator($this->schema); + $this->queryValidator = new QueryValidator($this->collection['attributes']); $query1 = Query::parse('title.notEqual("Iron Man", "Ant Man")'); $query2 = Query::parse('description.equal("Best movie ever")'); @@ -128,27 +144,36 @@ public function tearDown(): void public function testQueries() { // test for SUCCESS - $validator = new Queries($this->queryValidator, $this->indexes); + $validator = new Queries($this->queryValidator, $this->collection['indexes'], $this->collection['indexesInQueue']); $this->assertEquals(true, $validator->isValid($this->queries)); $this->queries[] = Query::parse('price.lesserEqual(6.50)'); $this->assertEquals(true, $validator->isValid($this->queries)); - //test for FAILURE + // test for FAILURE $this->queries[] = Query::parse('rating.greater(4)'); $this->assertEquals(false, $validator->isValid($this->queries)); - $this->assertEquals("Index not found for title,description,price,rating", $validator->getDescription()); + $this->assertEquals("Index not found: title,description,price,rating", $validator->getDescription()); + + // test for queued index + $query1 = Query::parse('price.lesserEqual(6.50)'); + $query2 = Query::parse('title.notEqual("Iron Man", "Ant Man")'); + + $this->queries = [$query1, $query2]; + $this->assertEquals(false, $validator->isValid($this->queries)); + $this->assertEquals("Index still in creation queue: price,title", $validator->getDescription()); + } public function testIsStrict() { - $validator = new Queries($this->validator, $this->indexes); + $validator = new Queries($this->queryValidator, $this->collection['indexes'], $this->collection['indexesInQueue']); $this->assertEquals(true, $validator->isStrict()); - $validator = new Queries($this->validator, $this->indexes, false); + $validator = new Queries($this->queryValidator, $this->collection['indexes'], $this->collection['indexesInQueue'], false); $this->assertEquals(false, $validator->isStrict()); } From 66bf4d3d4e004535337bdde2263d91f00baa2d7b Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Wed, 5 May 2021 12:30:59 -0400 Subject: [PATCH 12/13] Break from indexesQueu check once a match is found --- src/Database/Validator/Queries.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index f7f7bcc1a..6332d8860 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -91,11 +91,6 @@ public function isValid($value) */ $indexId = null; - /** - * @var bool - */ - $queued = false; - // Return false if attributes do not exactly match an index if ($this->strict) { // look for strict match among indexes @@ -109,15 +104,11 @@ public function isValid($value) // check against the indexesInQueue foreach ($this->indexesInQueue as $index) { if ($index['attributes'] === $queries) { - $queued = true; + $this->message = 'Index still in creation queue: ' . implode(",", $queries); + return false; } } - if ($queued) { - $this->message = 'Index still in creation queue: ' . implode(",", $queries); - return false; - } - $this->message = 'Index not found: ' . implode(",", $queries); return false; } From eac3929b319fcfaf4c98e4e12d497f1203f7e1cb Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Wed, 5 May 2021 13:15:05 -0400 Subject: [PATCH 13/13] Handle array matching logic in arrayMatch --- src/Database/Validator/Queries.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index 6332d8860..18e2ee727 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -95,7 +95,7 @@ public function isValid($value) if ($this->strict) { // look for strict match among indexes foreach ($this->indexes as $index) { - if ($index['attributes'] === $queries) { + if ($this->arrayMatch($index['attributes'], $queries)) { $indexId = $index['$id']; } } @@ -103,7 +103,7 @@ public function isValid($value) if (!$indexId) { // check against the indexesInQueue foreach ($this->indexesInQueue as $index) { - if ($index['attributes'] === $queries) { + if ($this->arrayMatch($index['attributes'], $queries)) { $this->message = 'Index still in creation queue: ' . implode(",", $queries); return false; } @@ -151,4 +151,27 @@ public function isStrict(): bool { return $this->strict; } + + /** + * Check if indexed array $indexes matches $queries + * + * @param array $indexes + * @param array $queries + * + * @return bool + */ + protected function arrayMatch($indexes, $queries): bool + { + // Check the count of indexes first for performance + if (count($indexes) !== count($queries)) { + return false; + } + + // Only matching arrays will have equal diffs in both directions + if (array_diff_assoc($indexes, $queries) !== array_diff_assoc($queries, $indexes)) { + return false; + } + + return true; + } }