Skip to content

Commit 20b5737

Browse files
committed
Merge remote-tracking branch 'origin/master' into fix/526-custom-builder-support
2 parents 6ca586e + 0f384b5 commit 20b5737

File tree

3 files changed

+72
-9
lines changed

3 files changed

+72
-9
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
/vendor
1313
composer.lock
1414
.ai
15+
/tests/database/*.sqlite-journal

src/CacheKey.php

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace GeneaLabs\LaravelModelCaching;
46

57
use BackedEnum;
8+
use DateTimeInterface;
69
use Exception;
710
use GeneaLabs\LaravelModelCaching\Traits\CachePrefixing;
811
use Illuminate\Database\Query\Expression;
@@ -137,11 +140,6 @@ protected function getInAndNotInClauses(array $where) : string
137140

138141
$type = strtolower($where["type"]);
139142
$subquery = $this->getValuesFromWhere($where);
140-
$values = collect($this->getCurrentBinding('where', []));
141-
142-
if (Str::startsWith($subquery, $values->first())) {
143-
$this->currentBinding += count($where["values"]);
144-
}
145143

146144
if (! is_numeric($subquery) && ! is_numeric(str_replace("_", "", $subquery))) {
147145
try {
@@ -154,6 +152,23 @@ protected function getInAndNotInClauses(array $where) : string
154152
}
155153
}
156154

155+
$placeholderCount = preg_match_all('/\?(?=(?:[^"]*"[^"]*")*[^"]*\Z)/m', $subquery);
156+
157+
if ($placeholderCount === 0) {
158+
if (data_get($where, "values")) {
159+
$this->currentBinding += count(data_get($where, "values"));
160+
}
161+
162+
$values = $this->recursiveImplode([$subquery], "_");
163+
164+
return "-{$where["column"]}_{$type}{$values}";
165+
}
166+
167+
$values = collect(data_get($this->query->bindings, "where"))
168+
->slice($this->currentBinding, $placeholderCount)
169+
->values();
170+
$this->currentBinding += $placeholderCount;
171+
157172
$subquery = preg_replace('/\?(?=(?:[^"]*"[^"]*")*[^"]*\Z)/m', "_??_", $subquery);
158173
$subquery = str_replace('%', '%%', $subquery);
159174
$subquery = collect(vsprintf(str_replace("_??_", "%s", $subquery), $values->toArray()));
@@ -370,7 +385,7 @@ protected function getValuesFromBindings(array $where, string $values) : string
370385
$values = $values->format("Y-m-d-H-i-s");
371386
}
372387

373-
return $values;
388+
return (string) $values;
374389
}
375390

376391
protected function getWhereClauses(array $wheres = []) : string
@@ -483,17 +498,20 @@ protected function recursiveImplode(array $items, string $glue = ",") : string
483498
return $result;
484499
}
485500

486-
private function processEnum(BackedEnum|UnitEnum|Expression|string|null $value): ?string
487-
{
501+
private function processEnum(
502+
BackedEnum|UnitEnum|Expression|DateTimeInterface|int|float|bool|string|null $value,
503+
): string {
488504
if ($value instanceof BackedEnum) {
489505
return $value->value;
490506
} elseif ($value instanceof UnitEnum) {
491507
return $value->name;
492508
} elseif ($value instanceof Expression) {
493509
return $this->expressionToString($value);
510+
} elseif ($value instanceof DateTimeInterface) {
511+
return $value->format("Y-m-d-H-i-s");
494512
}
495513

496-
return $value;
514+
return "{$value}";
497515
}
498516

499517
private function processEnums(array $values): array

tests/Integration/CachedBuilder/WhereInTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,48 @@ public function testWhereInWithPercentCharacterInValueDoesNotThrow()
121121
$this->assertEquals($liveResults->pluck("id"), $authors->pluck("id"));
122122
$this->assertEquals($liveResults->pluck("id"), $cachedResults->pluck("id"));
123123
}
124+
125+
public function testWhereInWithSubqueryContainingSingleWhereClause()
126+
{
127+
$books = (new Book)
128+
->whereIn("author_id", function ($query) {
129+
$query->select("id")
130+
->from("authors")
131+
->where("name", "=", "John");
132+
})
133+
->get();
134+
135+
$liveResults = (new UncachedBook)
136+
->whereIn("author_id", function ($query) {
137+
$query->select("id")
138+
->from("authors")
139+
->where("name", "=", "John");
140+
})
141+
->get();
142+
143+
$this->assertEquals($liveResults->pluck("id"), $books->pluck("id"));
144+
}
145+
146+
public function testWhereInWithSubqueryContainingMultipleWhereClauses()
147+
{
148+
$books = (new Book)
149+
->whereIn("author_id", function ($query) {
150+
$query->select("id")
151+
->from("authors")
152+
->where("name", "=", "John")
153+
->where("id", ">", 0);
154+
})
155+
->get();
156+
157+
$liveResults = (new UncachedBook)
158+
->whereIn("author_id", function ($query) {
159+
$query->select("id")
160+
->from("authors")
161+
->where("name", "=", "John")
162+
->where("id", ">", 0);
163+
})
164+
->get();
165+
166+
$this->assertEquals($liveResults->pluck("id"), $books->pluck("id"));
167+
}
124168
}

0 commit comments

Comments
 (0)