Skip to content

Commit ff42fa8

Browse files
committed
Fix caching of whereIn clauses
Fixes #128
1 parent b9494ef commit ff42fa8

File tree

5 files changed

+160
-39
lines changed

5 files changed

+160
-39
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [0.2.58] - 24 May 2018
8+
### Fixed
9+
- caching of queries with `whereIn` clauses.
10+
711
## [0.2.57] - 19 May 2018
812
### Added
913
- database name to cache keys and tags to help with multi-tenancy use-cases.

src/CacheKey.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ protected function getWhereClauses(array $wheres = []) : string
150150
$value .= $this->getNestedClauses($where);
151151
$value .= $this->getColumnClauses($where);
152152
$value .= $this->getRawClauses($where);
153+
$value .= $this->getInClauses($where);
153154
$value .= $this->getOtherClauses($where, $carry);
154155

155156
return $value;
@@ -178,6 +179,35 @@ protected function getColumnClauses(array $where) : string
178179
return "-{$where["boolean"]}_{$where["first"]}_{$where["operator"]}_{$where["second"]}";
179180
}
180181

182+
protected function getInClauses(array $where) : string
183+
{
184+
if ($where["type"] !== "In") {
185+
return "";
186+
}
187+
188+
$this->currentBinding++;
189+
$values = $this->recursiveImplode($where["values"], "_");
190+
191+
return "-{$where["column"]}_in{$values}";
192+
}
193+
194+
protected function recursiveImplode(array $items, string $glue = ",") : string
195+
{
196+
$result = "";
197+
198+
foreach ($items as $key => $value) {
199+
if (is_array($value)) {
200+
$result .= $this->recursiveImplode($value, $glue);
201+
202+
continue;
203+
}
204+
205+
$result .= $glue . $value;
206+
}
207+
208+
return $result;
209+
}
210+
181211
protected function getRawClauses(array $where) : string
182212
{
183213
if ($where["type"] !== "raw") {
@@ -202,9 +232,9 @@ protected function getRawClauses(array $where) : string
202232
return "-" . str_replace(" ", "_", $clause);
203233
}
204234

205-
protected function getOtherClauses(array $where, string $carry = null) : string
235+
protected function getOtherClauses(array $where) : string
206236
{
207-
if (in_array($where["type"], ["Exists", "Nested", "NotExists", "raw", "Column"])) {
237+
if (in_array($where["type"], ["Exists", "Nested", "NotExists", "Column", "raw", "In"])) {
208238
return "";
209239
}
210240

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration\CachedBuilder;
2+
3+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Author;
4+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Book;
5+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Profile;
6+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Publisher;
7+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Store;
8+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedAuthor;
9+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedBook;
10+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedProfile;
11+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedPublisher;
12+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedStore;
13+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Http\Resources\Author as AuthorResource;
14+
use GeneaLabs\LaravelModelCaching\Tests\IntegrationTestCase;
15+
use Illuminate\Foundation\Testing\RefreshDatabase;
16+
use Illuminate\Support\Collection;
17+
18+
class GetTest extends IntegrationTestCase
19+
{
20+
use RefreshDatabase;
21+
22+
public function testGetModelResultsCreatesCache()
23+
{
24+
$authors = (new Author)->with('books', 'profile')
25+
->get();
26+
$key = sha1('genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesauthor-books-profile');
27+
$tags = [
28+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesauthor',
29+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesbook',
30+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesprofile',
31+
];
32+
33+
$cachedResults = $this->cache()->tags($tags)
34+
->get($key)['value'];
35+
$liveResults = (new UncachedAuthor)->with('books', 'profile')
36+
->get();
37+
38+
$this->assertEquals($authors, $cachedResults);
39+
$this->assertEmpty($liveResults->diffKeys($cachedResults));
40+
}
41+
42+
public function testAccessingGetResultsViaArrayIndexDoesNotError()
43+
{
44+
$author = (new Author)
45+
->where('id', 1)
46+
->get()[0];
47+
$cachedAuthor = (new Author)
48+
->where('id', 1)
49+
->get()[0];
50+
$uncachedAuthor = (new UncachedAuthor)
51+
->where('id', 1)
52+
->get()[0];
53+
54+
$this->assertEquals(1, $author->id);
55+
$this->assertEquals($author, $cachedAuthor);
56+
$this->assertEquals($author->toArray(), $uncachedAuthor->toArray());
57+
}
58+
59+
public function testGetWithFieldArrayCachesResults()
60+
{
61+
$key = sha1('genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesauthor_id_name');
62+
$tags = [
63+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesauthor',
64+
];
65+
66+
$authors = (new Author)
67+
->get(["id", "name"]);
68+
$cachedResults = $this
69+
->cache()
70+
->tags($tags)
71+
->get($key)['value'];
72+
$liveResults = (new UncachedAuthor)
73+
->get();
74+
75+
$this->assertEquals($liveResults->pluck("id"), $authors->pluck("id"));
76+
$this->assertEquals($liveResults->pluck("id"), $cachedResults->pluck("id"));
77+
}
78+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration\CachedBuilder;
2+
3+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Author;
4+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Book;
5+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Profile;
6+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Publisher;
7+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Store;
8+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedAuthor;
9+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedBook;
10+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedProfile;
11+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedPublisher;
12+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedStore;
13+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Http\Resources\Author as AuthorResource;
14+
use GeneaLabs\LaravelModelCaching\Tests\IntegrationTestCase;
15+
use Illuminate\Foundation\Testing\RefreshDatabase;
16+
use Illuminate\Support\Collection;
17+
18+
class WhereInTest extends IntegrationTestCase
19+
{
20+
use RefreshDatabase;
21+
22+
public function testWithInUsingCollectionQuery()
23+
{
24+
$key = sha1('genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesbook-author_id_in_1_2_3_4');
25+
$tags = [
26+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesbook',
27+
];
28+
$authors = (new UncachedAuthor)
29+
->where("id", "<", 5)
30+
->get(["id"]);
31+
32+
$books = (new Book)
33+
->whereIn("author_id", $authors)
34+
->get();
35+
$cachedResults = $this
36+
->cache()
37+
->tags($tags)
38+
->get($key)['value'];
39+
$liveResults = (new UncachedBook)
40+
->whereIn("author_id", $authors)
41+
->get();
42+
43+
$this->assertEquals($liveResults->pluck("id"), $books->pluck("id"));
44+
$this->assertEquals($liveResults->pluck("id"), $cachedResults->pluck("id"));
45+
}
46+
}

tests/Integration/CachedBuilderTest.php

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -285,26 +285,6 @@ public function testFirstModelResultsCreatesCache()
285285
$this->assertEquals($liveResult->id, $author->id);
286286
}
287287

288-
public function testGetModelResultsCreatesCache()
289-
{
290-
$authors = (new Author)->with('books', 'profile')
291-
->get();
292-
$key = sha1('genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesauthor-books-profile');
293-
$tags = [
294-
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesauthor',
295-
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesbook',
296-
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesprofile',
297-
];
298-
299-
$cachedResults = $this->cache()->tags($tags)
300-
->get($key)['value'];
301-
$liveResults = (new UncachedAuthor)->with('books', 'profile')
302-
->get();
303-
304-
$this->assertEquals($authors, $cachedResults);
305-
$this->assertEmpty($liveResults->diffKeys($cachedResults));
306-
}
307-
308288
public function testMaxModelResultsCreatesCache()
309289
{
310290
$authorId = (new Author)->with('books', 'profile')
@@ -818,21 +798,4 @@ public function testAttachInvalidatesCache()
818798

819799
$this->assertTrue($book->stores->keyBy('id')->has(1));
820800
}
821-
822-
public function testAccessingGetResultsViaArrayIndexDoesNotError()
823-
{
824-
$author = (new Author)
825-
->where('id', 1)
826-
->get()[0];
827-
$cachedAuthor = (new Author)
828-
->where('id', 1)
829-
->get()[0];
830-
$uncachedAuthor = (new UncachedAuthor)
831-
->where('id', 1)
832-
->get()[0];
833-
834-
$this->assertEquals(1, $author->id);
835-
$this->assertEquals($author, $cachedAuthor);
836-
$this->assertEquals($author->toArray(), $uncachedAuthor->toArray());
837-
}
838801
}

0 commit comments

Comments
 (0)