Skip to content

[bug] Fix current binding count when previous binding is false #409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 26, 2022
256 changes: 132 additions & 124 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, $bindingFallback = null)
{
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,12 +274,15 @@ protected function getValuesFromWhere(array $where) : string

protected function getValuesFromBindings(array $where, string $values) : string
{
if (($this->query->bindings["where"][$this->currentBinding] ?? false) !== false) {
$values = $this->query->bindings["where"][$this->currentBinding];
$bindingFallback = __CLASS__ . ':UNKNOWN_BINDING';
$currentBinding = $this->getCurrentBinding("where", $bindingFallback);

if ($currentBinding !== $bindingFallback) {
$values = $currentBinding;
$this->currentBinding++;

if ($where["type"] === "between") {
$values .= "_" . $this->query->bindings["where"][$this->currentBinding];
$values .= "_" . $this->getCurrentBinding("where");
$this->currentBinding++;
}
}
Expand Down Expand Up @@ -207,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->query->bindings["where"][$this->currentBinding] ?? []);
$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 @@ -283,83 +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->query->bindings["where"][$this->currentBinding];
$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());
}
}
Loading