Skip to content
Prev Previous commit
Next Next commit
Fixed ordering of methods and update binding resolution.
  • Loading branch information
mikebronner authored Jan 26, 2022
commit 1f8632020efbbf5506471d89e3d9d8920f430802
256 changes: 127 additions & 129 deletions src/CacheKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,66 @@ public function make(
return $key;
}

protected function getBindingsSlug() : string
{
if (! method_exists($this->model, 'query')) {
return '';
}

return Arr::query($this->model->query()->getBindings());
}

protected function getColumnClauses(array $where) : string
{
if ($where["type"] !== "Column") {
return "";
}

return "-{$where["boolean"]}_{$where["first"]}_{$where["operator"]}_{$where["second"]}";
}

protected function getCurrentBinding(string $type, string $bindingFallback): string
{
return data_get($this->query->bindings, "{$type}.{$this->currentBinding}", $bindingFallback);
}

protected function getIdColumn(string $idColumn) : string
{
return $idColumn ? "_{$idColumn}" : "";
}

protected function getInAndNotInClauses(array $where) : string
{
if (! in_array($where["type"], ["In", "NotIn", "InRaw"])) {
return "";
}

$type = strtolower($where["type"]);
$subquery = $this->getValuesFromWhere($where);
$values = collect($this->getCurrentBinding('where') ?? []);

if (Str::startsWith($subquery, $values->first())) {
$this->currentBinding += count($where["values"]);
}

if (! is_numeric($subquery) && ! is_numeric(str_replace("_", "", $subquery))) {
try {
$subquery = Uuid::fromBytes($subquery);
$values = $this->recursiveImplode([$subquery], "_");

return "-{$where["column"]}_{$type}{$values}";
} catch (Exception $exception) {
// do nothing
}
}

$subquery = preg_replace('/\?(?=(?:[^"]*"[^"]*")*[^"]*\Z)/m', "_??_", $subquery);
$subquery = collect(vsprintf(str_replace("_??_", "%s", $subquery), $values->toArray()));
$values = $this->recursiveImplode($subquery->toArray(), "_");

return "-{$where["column"]}_{$type}{$values}";
}

protected function getLimitClause() : string
{
if (! property_exists($this->query, "limit")
Expand All @@ -67,15 +122,18 @@ protected function getLimitClause() : string
return "-limit_{$this->query->limit}";
}

protected function getTableSlug() : string
protected function getModelSlug() : string
{
return (new Str)->slug($this->query->from)
. ":";
return (new Str)->slug(get_class($this->model));
}

protected function getModelSlug() : string
protected function getNestedClauses(array $where) : string
{
return (new Str)->slug(get_class($this->model));
if (! in_array($where["type"], ["Exists", "Nested", "NotExists"])) {
return "";
}

return "-" . strtolower($where["type"]) . $this->getWhereClauses($where["query"]->wheres);
}

protected function getOffsetClause() : string
Expand Down Expand Up @@ -110,6 +168,18 @@ protected function getOrderByClauses() : string
?: "";
}

protected function getOtherClauses(array $where) : string
{
if (in_array($where["type"], ["Exists", "Nested", "NotExists", "Column", "raw", "In", "NotIn", "InRaw"])) {
return "";
}

$value = $this->getTypeClause($where);
$value .= $this->getValuesClause($where);

return "-{$where["column"]}_{$value}";
}

protected function getQueryColumns(array $columns) : string
{
if (($columns === ["*"]
Expand All @@ -129,6 +199,36 @@ protected function getQueryColumns(array $columns) : string
return "_" . implode("_", $columns);
}

protected function getRawClauses(array $where) : string
{
if (! in_array($where["type"], ["raw"])) {
return "";
}

$queryParts = explode("?", $where["sql"]);
$clause = "_{$where["boolean"]}";

while (count($queryParts) > 1) {
$clause .= "_" . array_shift($queryParts);
$clause .= $this->getCurrentBinding('where');
$this->currentBinding++;
}

$lastPart = array_shift($queryParts);

if ($lastPart) {
$clause .= "_" . $lastPart;
}

return "-" . str_replace(" ", "_", $clause);
}

protected function getTableSlug() : string
{
return (new Str)->slug($this->query->from)
. ":";
}

protected function getTypeClause($where) : string
{
$type = in_array($where["type"], ["InRaw", "In", "NotIn", "Null", "NotNull", "between", "NotInSub", "InSub", "JsonContains"])
Expand Down Expand Up @@ -174,9 +274,8 @@ protected function getValuesFromWhere(array $where) : string

protected function getValuesFromBindings(array $where, string $values) : string
{
// Fallback to this when the current binding does not exist in the bindings array
$bindingFallback = __CLASS__ . ':UNKNOWN_BINDING';
$currentBinding = $this->getCurrentBinding('where') ?? $bindingFallback;
$currentBinding = $this->getCurrentBinding('where', $bindingFallback);

if ($currentBinding !== $bindingFallback) {
$values = $currentBinding;
Expand Down Expand Up @@ -211,57 +310,41 @@ protected function getWhereClauses(array $wheres = []) : string
return $value;
});
}

protected function getNestedClauses(array $where) : string
protected function getWheres(array $wheres) : Collection
{
if (! in_array($where["type"], ["Exists", "Nested", "NotExists"])) {
return "";
}

return "-" . strtolower($where["type"]) . $this->getWhereClauses($where["query"]->wheres);
}
$wheres = collect($wheres);

protected function getColumnClauses(array $where) : string
{
if ($where["type"] !== "Column") {
return "";
if ($wheres->isEmpty()
&& property_exists($this->query, "wheres")
) {
$wheres = collect($this->query->wheres);
}

return "-{$where["boolean"]}_{$where["first"]}_{$where["operator"]}_{$where["second"]}";
return $wheres;
}

protected function getInAndNotInClauses(array $where) : string
protected function getWithModels() : string
{
if (! in_array($where["type"], ["In", "NotIn", "InRaw"])) {
return "";
}

$type = strtolower($where["type"]);
$subquery = $this->getValuesFromWhere($where);
$values = collect($this->getCurrentBinding('where') ?? []);
$eagerLoads = collect($this->eagerLoad);

if (Str::startsWith($subquery, $values->first())) {
$this->currentBinding += count($where["values"]);
if ($eagerLoads->isEmpty()) {
return "";
}

if (! is_numeric($subquery) && ! is_numeric(str_replace("_", "", $subquery))) {
try {
$subquery = Uuid::fromBytes($subquery);
$values = $this->recursiveImplode([$subquery], "_");

return "-{$where["column"]}_{$type}{$values}";
} catch (Exception $exception) {
// do nothing
return $eagerLoads->keys()->reduce(function ($carry, $related) {
if (! method_exists($this->model, $related)) {
return "{$carry}-{$related}";
}
}

$subquery = preg_replace('/\?(?=(?:[^"]*"[^"]*")*[^"]*\Z)/m', "_??_", $subquery);
$subquery = collect(vsprintf(str_replace("_??_", "%s", $subquery), $values->toArray()));
$values = $this->recursiveImplode($subquery->toArray(), "_");
$relatedModel = $this->model->$related()->getRelated();
$relatedConnection = $relatedModel->getConnection()->getName();
$relatedDatabase = $relatedModel->getConnection()->getDatabaseName();

return "-{$where["column"]}_{$type}{$values}";
return "{$carry}-{$relatedConnection}:{$relatedDatabase}:{$related}";
});
}

protected function recursiveImplode(array $items, string $glue = ",") : string
{
$result = "";
Expand All @@ -287,89 +370,4 @@ protected function recursiveImplode(array $items, string $glue = ",") : string

return $result;
}

protected function getRawClauses(array $where) : string
{
if (! in_array($where["type"], ["raw"])) {
return "";
}

$queryParts = explode("?", $where["sql"]);
$clause = "_{$where["boolean"]}";

while (count($queryParts) > 1) {
$clause .= "_" . array_shift($queryParts);
$clause .= $this->getCurrentBinding('where');
$this->currentBinding++;
}

$lastPart = array_shift($queryParts);

if ($lastPart) {
$clause .= "_" . $lastPart;
}

return "-" . str_replace(" ", "_", $clause);
}

protected function getOtherClauses(array $where) : string
{
if (in_array($where["type"], ["Exists", "Nested", "NotExists", "Column", "raw", "In", "NotIn", "InRaw"])) {
return "";
}

$value = $this->getTypeClause($where);
$value .= $this->getValuesClause($where);

return "-{$where["column"]}_{$value}";
}

protected function getWheres(array $wheres) : Collection
{
$wheres = collect($wheres);

if ($wheres->isEmpty()
&& property_exists($this->query, "wheres")
) {
$wheres = collect($this->query->wheres);
}

return $wheres;
}

protected function getWithModels() : string
{
$eagerLoads = collect($this->eagerLoad);

if ($eagerLoads->isEmpty()) {
return "";
}

return $eagerLoads->keys()->reduce(function ($carry, $related) {
if (! method_exists($this->model, $related)) {
return "{$carry}-{$related}";
}

$relatedModel = $this->model->$related()->getRelated();
$relatedConnection = $relatedModel->getConnection()->getName();
$relatedDatabase = $relatedModel->getConnection()->getDatabaseName();

return "{$carry}-{$relatedConnection}:{$relatedDatabase}:{$related}";
});
}

protected function getBindingsSlug() : string
{
if (! method_exists($this->model, 'query')) {
return '';
}

return Arr::query($this->model->query()->getBindings());
}


private function getCurrentBinding(string $type)
{
return data_get($this->query->bindings, "$type.$this->currentBinding");
}
}