Skip to content

Commit e8aa065

Browse files
committed
Fix parameter bindings caching
Fixed #111
1 parent dd9af00 commit e8aa065

File tree

6 files changed

+106
-26
lines changed

6 files changed

+106
-26
lines changed

src/CacheKey.php

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class CacheKey
1212
protected $eagerLoad;
1313
protected $model;
1414
protected $query;
15+
protected $currentBinding = 0;
1516

1617
public function __construct(
1718
array $eagerLoad,
@@ -125,24 +126,27 @@ protected function getValuesFromWhere(array $where) : string
125126
protected function getValuesFromBindings(string $values) : string
126127
{
127128
if (! $values && $this->query->bindings["where"] ?? false) {
128-
$values = implode("_", $this->query->bindings["where"]);
129+
$values = $this->query->bindings["where"][$this->currentBinding];
129130
}
130131

131132
return $values;
132133
}
133134

134135
protected function getWhereClauses(array $wheres = []) : string
135136
{
136-
return $this->getWheres($wheres)
137+
$whereClause = $this->getWheres($wheres)
137138
->reduce(function ($carry, $where) {
138-
$value = $this->getNestedClauses($where);
139+
$value = $carry;
140+
$value .= $this->getNestedClauses($where);
139141
$value .= $this->getColumnClauses($where);
140142
$value .= $this->getRawClauses($where);
141143
$value .= $this->getOtherClauses($where, $carry);
142144

143145
return $value;
144146
})
145147
. "";
148+
149+
return $whereClause;
146150
}
147151

148152
protected function getNestedClauses(array $where) : string
@@ -151,6 +155,8 @@ protected function getNestedClauses(array $where) : string
151155
return "";
152156
}
153157

158+
$this->currentBinding++;
159+
154160
return "_" . strtolower($where["type"]) . $this->getWhereClauses($where["query"]->wheres);
155161
}
156162

@@ -160,6 +166,8 @@ protected function getColumnClauses(array $where) : string
160166
return "";
161167
}
162168

169+
$this->currentBinding++;
170+
163171
return "_{$where["boolean"]}_{$where["first"]}_{$where["operator"]}_{$where["second"]}";
164172
}
165173

@@ -169,7 +177,22 @@ protected function getRawClauses(array $where) : string
169177
return "";
170178
}
171179

172-
return "_{$where["boolean"]}_" . str_slug($where["sql"]);
180+
$queryParts = explode("?", $where["sql"]);
181+
$clause = "_{$where["boolean"]}";
182+
183+
while (count($queryParts) > 1) {
184+
$clause .= "_" . array_shift($queryParts);
185+
$clause .= $this->query->bindings["where"][$this->currentBinding];
186+
$this->currentBinding++;
187+
}
188+
189+
$lastPart = array_shift($queryParts);
190+
191+
if ($lastPart) {
192+
$clause .= "_" . $lastPart;
193+
}
194+
195+
return str_replace(" ", "_", $clause);
173196
}
174197

175198
protected function getOtherClauses(array $where, string $carry = null) : string
@@ -180,8 +203,9 @@ protected function getOtherClauses(array $where, string $carry = null) : string
180203

181204
$value = $this->getTypeClause($where);
182205
$value .= $this->getValuesClause($where);
206+
$this->currentBinding++;
183207

184-
return "{$carry}-{$where["column"]}_{$value}";
208+
return "{$where["column"]}_{$value}";
185209
}
186210

187211
protected function getWheres(array $wheres) : Collection

tests/Integration/FirstOrCreateTest.php renamed to tests/Integration/CachedBuilder/FirstOrCreateTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration;
1+
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration\CachedBuilder;
22

33
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Author;
44
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Book;

tests/Integration/InRandomOrderQueryTest.php renamed to tests/Integration/CachedBuilder/InRandomOrderQueryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration;
1+
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration\CachedBuilder;
22

33
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Author;
44
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Book;

tests/Integration/UpdateExistingPivotTest.php renamed to tests/Integration/CachedBuilder/UpdateExistingPivotTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration;
1+
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration\CachedBuilder;
22

33
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Author;
44
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Book;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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 WhereRawTest extends IntegrationTestCase
19+
{
20+
use RefreshDatabase;
21+
22+
public function testRawWhereClauseParsing()
23+
{
24+
$authors = collect([(new Author)
25+
->whereRaw('name <> \'\'')
26+
->first()]);
27+
28+
$key = sha1('genealabs:laravel-model-caching:testing:genealabslaravelmodelcachingtestsfixturesauthor_and_name-first');
29+
$tags = ['genealabs:laravel-model-caching:testing:genealabslaravelmodelcachingtestsfixturesauthor'];
30+
31+
$cachedResults = collect([$this->cache()->tags($tags)->get($key)['value']]);
32+
33+
$liveResults = collect([(new UncachedAuthor)
34+
->whereRaw('name <> \'\'')->first()]);
35+
36+
$this->assertTrue($authors->diffKeys($cachedResults)->isEmpty());
37+
$this->assertTrue($liveResults->diffKeys($cachedResults)->isEmpty());
38+
}
39+
40+
/** @group test */
41+
public function testWhereRawWithQueryParameters()
42+
{
43+
$authorName = (new Author)->first()->name;
44+
$authors = (new Author)
45+
->where("name", "!=", "test")
46+
->whereRaw("name != 'test3'")
47+
->whereRaw('name = ? AND name != ?', [$authorName, "test2"])
48+
->get();
49+
$key = sha1("genealabs:laravel-model-caching:testing:genealabslaravelmodelcachingtestsfixturesauthorname_!=_test_and_name_!=_'test3'_and_name_=_Guido_Feest__AND_name_!=_test2");
50+
$tags = ['genealabs:laravel-model-caching:testing:genealabslaravelmodelcachingtestsfixturesauthor'];
51+
52+
$cachedResults = collect([$this->cache()->tags($tags)->get($key)['value']]);
53+
$liveResults = (new UncachedAuthor)
54+
->where("name", "!=", "test")
55+
->whereRaw("name != 'test3'")
56+
->whereRaw('name = ? AND name != ?', [$authorName, "test2"])
57+
->get();
58+
59+
$this->assertTrue($authors->diffKeys($cachedResults)->isEmpty());
60+
$this->assertTrue($liveResults->diffKeys($cachedResults)->isEmpty());
61+
}
62+
63+
/** @group test */
64+
public function testMultipleWhereRawCacheUniquely()
65+
{
66+
$book1 = (new UncachedBook)->first();
67+
$book2 = (new UncachedBook)->orderBy("id", "DESC")->first();
68+
$cachedBook1 = (new Book)->whereRaw('title = ?', [$book1->title])->first();
69+
$cachedBook2 = (new Book)->whereRaw('title = ?', [$book2->title])->first();
70+
71+
$this->assertEquals($cachedBook1->title, $book1->title);
72+
$this->assertEquals($cachedBook2->title, $book2->title);
73+
}
74+
}

tests/Integration/CachedBuilderTest.php

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -579,24 +579,6 @@ public function testColumnsRelationshipWhereClauseParsing()
579579
$this->assertEmpty($liveResults->diffKeys($cachedResults));
580580
}
581581

582-
public function testRawWhereClauseParsing()
583-
{
584-
$authors = collect([(new Author)
585-
->whereRaw('name <> \'\'')
586-
->first()]);
587-
588-
$key = sha1('genealabs:laravel-model-caching:testing:genealabslaravelmodelcachingtestsfixturesauthor_and_name-first');
589-
$tags = ['genealabs:laravel-model-caching:testing:genealabslaravelmodelcachingtestsfixturesauthor'];
590-
591-
$cachedResults = collect([$this->cache()->tags($tags)->get($key)['value']]);
592-
593-
$liveResults = collect([(new UncachedAuthor)
594-
->whereRaw('name <> \'\'')->first()]);
595-
596-
$this->assertTrue($authors->diffKeys($cachedResults)->isEmpty());
597-
$this->assertTrue($liveResults->diffKeys($cachedResults)->isEmpty());
598-
}
599-
600582
public function testScopeClauseParsing()
601583
{
602584
$author = factory(Author::class, 1)

0 commit comments

Comments
 (0)