From 1e413bb1ae1b55cf6908556f1507659886dfdd73 Mon Sep 17 00:00:00 2001 From: Timothy Marois Date: Thu, 16 Aug 2018 23:18:53 -0400 Subject: [PATCH] =?UTF-8?q?Changed:=20#24=20=E2=80=93=20Array=20keys=20on?= =?UTF-8?q?=20query=20results()=20and=20resultDocuments()=20change=20index?= =?UTF-8?q?es=20from=20chronological=20integers=20to=20document=20Id.=20Ad?= =?UTF-8?q?ding=20the=20ID=20within=20the=20array=20key=20allows=20a=20ref?= =?UTF-8?q?erence=20the=20original=20document.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 ++ README.md | 6 +-- src/Cache.php | 2 +- src/Database.php | 8 +-- src/Query.php | 2 +- src/QueryLogic.php | 6 +-- tests/DatabaseTest.php | 2 +- tests/QueryTest.php | 119 +++++++++++++++++++++++++++++++++-------- 8 files changed, 115 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a71e0a9..8826c0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ Change Log ========== +### 08/16/2018 - 1.0.21 +* Changed: #24 – Array keys on query `results()` and `resultDocuments()` change indexes from chronological integers to document Id. Adding the ID within the array key allows a reference the original document. + +**NOTE** It is possible this *could* potentially break code. This will change query array indexes from `$myResults[0]` to `$myResults['my_document_id']`. + ### 08/16/2018 - 1.0.20 * Fixed #23 – Caching is cleared when deleting/saving documents to prevent cache from being out of sync with document data. diff --git a/README.md b/README.md index cffa27e..116792b 100644 --- a/README.md +++ b/README.md @@ -215,7 +215,7 @@ Here is a list of methods you can use on the database class. |---|---| |`version()` | Current version of your Filebase library | |`get($id)` | Refer to [get()](https://github.com/filebase/Filebase#3-get-and-methods) | -|`has($id)` | Check if a record exist returning true/false | +|`has($id)` | Check if a record exist returning true/false (added: 1.0.19) | |`findAll()` | Returns all documents in database | |`count()` | Number of documents in database | |`flush(true)` | Deletes all documents. | @@ -405,8 +405,8 @@ The below **methods execute the query** and return results *(do not try to use t |`count()` | Counts and returns the number of documents in results. | |`first()` | Returns only the first document in results. | |`last()` | Returns only the last document in results. | -|`results()` | This will return all the documents found and their data as an array. Passing the argument of `false` will be the same as `resultDocuments()` (returning the full document objects) | -|`resultDocuments()` | This will return all the documents found and their data as document objects, or you can do `results(false)` which is the alias. | +|`results()` | This will return all the documents found and their data as an array. | +|`resultDocuments()` | This will return all the documents found and their data as document objects. | ### Comparison Operators: diff --git a/src/Cache.php b/src/Cache.php index 47090f3..212bd73 100644 --- a/src/Cache.php +++ b/src/Cache.php @@ -119,7 +119,7 @@ public function getDocuments($documents) $d = []; foreach($documents as $document) { - $d[] = $this->database->get($document)->setFromCache(true); + $d[$document] = $this->database->get($document)->setFromCache(true); } return $d; diff --git a/src/Database.php b/src/Database.php index 88f6ed0..eddd0f8 100644 --- a/src/Database.php +++ b/src/Database.php @@ -16,7 +16,7 @@ class Database * Stores the version of Filebase * use $db->getVersion() */ - const VERSION = '1.0.20'; + const VERSION = '1.0.21'; //-------------------------------------------------------------------- @@ -100,13 +100,15 @@ public function findAll($include_documents = true, $data_only = false) foreach($all_items as $a) { + $document = $this->get($a); + if ($data_only === true) { - $items[] = $this->get($a)->getData(); + $items[$document->getId()] = $document->getData(); } else { - $items[] = $this->get($a); + $items[$document->getId()] = $document; } } diff --git a/src/Query.php b/src/Query.php index 62869ac..f13558b 100644 --- a/src/Query.php +++ b/src/Query.php @@ -260,7 +260,7 @@ public function toArray() { foreach($this->documents as $document) { - $docs[] = (array) $document->getData(); + $docs[$document->getId()] = (array) $document->getData(); } } diff --git a/src/QueryLogic.php b/src/QueryLogic.php index 764e190..cac9982 100644 --- a/src/QueryLogic.php +++ b/src/QueryLogic.php @@ -71,7 +71,7 @@ public function run() if ($cached_documents = $this->cache->get()) { - $this->documents = $cached_documents; + $this->documents = ($cached_documents); $this->sort(); $this->offsetLimit(); @@ -141,7 +141,7 @@ protected function filter($documents, $predicates) { list($field, $operator, $value) = $predicate; - $documents = array_values(array_filter($documents, function ($document) use ($field, $operator, $value) { + $documents = (array_filter($documents, function ($document) use ($field, $operator, $value) { return $this->match($document, $field, $operator, $value); })); @@ -155,7 +155,7 @@ protected function filter($documents, $predicates) { list($field, $operator, $value) = $predicate; - $documents = array_values(array_filter($org_docs, function ($document) use ($field, $operator, $value) { + $documents = (array_filter($org_docs, function ($document) use ($field, $operator, $value) { return $this->match($document, $field, $operator, $value); })); diff --git a/tests/DatabaseTest.php b/tests/DatabaseTest.php index ddd6d7c..3ec0830 100644 --- a/tests/DatabaseTest.php +++ b/tests/DatabaseTest.php @@ -236,7 +236,7 @@ public function testDatabaseFindAllDataOnly() // should only have 1 doc $this->assertEquals(1, count($documents)); - $this->assertEquals(['key'=>'value'], $documents[0]); + $this->assertEquals(['key'=>'value'], current($documents)); $db->flush(true); } diff --git a/tests/QueryTest.php b/tests/QueryTest.php index c5a1db4..b162848 100644 --- a/tests/QueryTest.php +++ b/tests/QueryTest.php @@ -347,9 +347,11 @@ public function testLimitOffset() // test that the offset takes off the first array (should return "apple", not "google") $test3 = $db->query()->where('rank','=',150)->limit(1,1)->results(); + $test3Current = current($test3); + $this->assertEquals(2, (count($test1))); $this->assertEquals(3, (count($test2))); - $this->assertEquals('Apple', $test3[0]['name']); + $this->assertEquals('Apple', $test3Current['name']); $db->flush(true); } @@ -457,23 +459,38 @@ public function testSorting() // test that they are ordered by name ASC (check first, second, and last) $test1 = $db->query()->where('status','=','enabled')->orderBy('name', 'ASC')->results(); - $this->assertEquals(['first'=>'Amazon','second'=>'Amex','last'=>'Microsoft'], ['first'=>$test1[0]['name'],'second'=>$test1[1]['name'],'last'=>$test1[5]['name']]); + $test1A = current($test1); + $test1B = next($test1); + $test1C = end($test1); + $this->assertEquals(['first'=>'Amazon','second'=>'Amex','last'=>'Microsoft'], ['first'=>$test1A['name'],'second'=>$test1B['name'],'last'=>$test1C['name']]); // test that they are ordered by name ASC (check first, second, and last) $test2 = $db->query()->where('status','=','enabled')->limit(3)->orderBy('name', 'ASC')->results(); - $this->assertEquals(['Amazon','Amex','Apple'], [$test2[0]['name'],$test2[1]['name'],$test2[2]['name']]); + $testA = current($test2); + $testB = next($test2); + $testC = end($test2); + $this->assertEquals(['Amazon','Amex','Apple'], [$testA['name'],$testB['name'],$testC['name']]); // test that they are ordered by name DESC (check first, second, and last) $test3 = $db->query()->where('status','=','enabled')->limit(3)->orderBy('name', 'DESC')->results(); - $this->assertEquals(['Microsoft','Hooli','Google'], [$test3[0]['name'],$test3[1]['name'],$test3[2]['name']]); + $testA = current($test3); + $testB = next($test3); + $testC = end($test3); + $this->assertEquals(['Microsoft','Hooli','Google'], [$testA['name'],$testB['name'],$testC['name']]); // test that they are ordered by rank nested [reviews] DESC $test4 = $db->query()->where('status','=','enabled')->limit(3)->orderBy('rank.reviews', 'DESC')->results(); - $this->assertEquals(['Apple','Google','Amazon'], [$test4[0]['name'],$test4[1]['name'],$test4[2]['name']]); + $testA = current($test4); + $testB = next($test4); + $testC = end($test4); + $this->assertEquals(['Apple','Google','Amazon'], [$testA['name'],$testB['name'],$testC['name']]); // test that they are ordered by rank nested [reviews] ASC $test5 = $db->query()->where('status','=','enabled')->limit(3)->orderBy('rank.reviews', 'ASC')->results(); - $this->assertEquals(['Amex','Hooli','Microsoft'], [$test5[0]['name'],$test5[1]['name'],$test5[2]['name']]); + $testA = current($test5); + $testB = next($test5); + $testC = end($test5); + $this->assertEquals(['Amex','Hooli','Microsoft'], [$testA['name'],$testB['name'],$testC['name']]); $db->flush(true); @@ -488,11 +505,17 @@ public function testSorting() // order the results ASC (but inject numbers into strings) $test6 = $db->query()->limit(3)->orderBy('name', 'ASC')->results(); - $this->assertEquals(['Google 1','Google 2','Google 3'], [$test6[0]['name'],$test6[1]['name'],$test6[2]['name']]); + $testA = current($test6); + $testB = next($test6); + $testC = end($test6); + $this->assertEquals(['Google 1','Google 2','Google 3'], [$testA['name'],$testB['name'],$testC['name']]); // order the results DESC (but inject numbers into strings) $test6 = $db->query()->limit(3)->orderBy('name', 'DESC')->results(); - $this->assertEquals(['Google 10','Google 9','Google 7'], [$test6[0]['name'],$test6[1]['name'],$test6[2]['name']]); + $testA = current($test6); + $testB = next($test6); + $testC = end($test6); + $this->assertEquals(['Google 10','Google 9','Google 7'], [$testA['name'],$testB['name'],$testC['name']]); $db->flush(true); @@ -562,8 +585,8 @@ public function testWhereIn() $this->assertEquals('Microsoft', $test3['name']); // check if the method createdAt() exists or not based on the argument boolean - $this->assertEquals(true, method_exists($test5[0], 'createdAt')); - $this->assertEquals(false, method_exists($test6[0], 'createdAt')); + $this->assertEquals(true, method_exists(current($test5), 'createdAt')); + $this->assertEquals(false, method_exists(current($test6), 'createdAt')); // check if the results = 2 $this->assertEquals(2, count($test4)); @@ -956,8 +979,10 @@ public function testWhereQueryFromCache() ->andWhere('email','==','john@example.com') ->resultDocuments(); + $first = current($result_from_cache); + $this->assertEquals(10, count($results)); - $this->assertEquals(true, ($result_from_cache[0]->isCache())); + $this->assertEquals(true, ($first->isCache())); $db->flush(true); } @@ -983,21 +1008,24 @@ public function testQueryFromCacheAfterDelete() $results = $db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->resultDocuments(); $result_from_cache = $db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->resultDocuments(); + $current = current($result_from_cache); + $this->assertEquals(10, count($results)); - $this->assertEquals(true, ($result_from_cache[0]->isCache())); + $this->assertEquals(10, count($result_from_cache)); + $this->assertEquals(true, $current->isCache()); - $id = $result_from_cache[0]->getId(); - $id2 = $result_from_cache[1]->getId(); + $id = $current->getId(); + $id2 = next($result_from_cache)->getId(); // delete the file - $result_from_cache[0]->delete(); + $current->delete(); $results = $db->query() ->where('name','=','John') ->andWhere('email','==','john@example.com') ->resultDocuments(); - $this->assertEquals($id2, $results[0]->getId()); + $this->assertEquals($id2, current($results)->getId()); $db->flush(true); } @@ -1024,25 +1052,70 @@ public function testQueryFromCacheAfterSave() $results = $db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->resultDocuments(); $result_from_cache = $db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->resultDocuments(); + $current = current($result_from_cache); + $this->assertEquals(10, count($results)); - $this->assertEquals(true, ($result_from_cache[0]->isCache())); + $this->assertEquals(10, count($result_from_cache)); + $this->assertEquals(true, $current->isCache()); - $id = $result_from_cache[0]->getId(); - $id2 = $result_from_cache[1]->getId(); + $id = $current->getId(); + $id2 = next($result_from_cache)->getId(); // Change the name - $result_from_cache[0]->name = 'Tim'; - $result_from_cache[0]->save(); + $current->name = 'Tim'; + $current->save(); $results = $db->query() ->where('name','=','John') ->andWhere('email','==','john@example.com') ->resultDocuments(); - $this->assertEquals($id2, $results[0]->getId()); - $this->assertEquals('John', $results[0]->name); + $this->assertEquals($id2, current($results)->getId()); + $this->assertEquals('John', current($results)->name); + + $db->flush(true); + } + + + public function testQueryResultKeys() + { + $db = new \Filebase\Database([ + 'dir' => __DIR__.'/databases/results', + 'cache' => true + ]); + + $db->flush(true); + + for ($x = 1; $x <= 10; $x++) + { + $user = $db->get(uniqid()); + $user->name = 'John'; + $user->email = 'john@example.com'; + $user->save(); + } + + $resultsA = $db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->results(); + $resultsB = $db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->results(); + + $this->assertEquals($resultsB, $resultsA); + + $db->flushCache(); + $resultsC = current($db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->results()); + $db->flushCache(); + $resultsD = current($db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->results()); + + $this->assertEquals($resultsC, $resultsD); + + $db->flushCache(); + $resultsE = current($db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->resultDocuments()); + $db->flushCache(); + $resultsF = $db->query()->where('name','=','John')->andWhere('email','==','john@example.com')->resultDocuments(); + + $this->assertEquals($resultsB[$resultsE->getId()], $resultsE->getData()); + $this->assertEquals($resultsF[$resultsE->getId()]->getData(), $resultsE->getData()); $db->flush(true); + $db->flushCache(); } }