Skip to content
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

feat: Implement ability to drop cache keys using combination of OR an… #75

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
feat: Implement ability to drop cache keys using combination of OR an…
…d AND logic
  • Loading branch information
KminekMatej committed Jan 4, 2024
commit 48ba8dcba5a23a0469038f23ae54f8ef5ee026b5
4 changes: 2 additions & 2 deletions src/Caching/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,13 @@ public function remove(mixed $key): void
* Removes items from the cache by conditions.
* Conditions are:
* - Cache::Priority => (int) priority
* - Cache::Tags => (array) tags
* - Cache::Tags => (array) tags | CacheSelector
* - Cache::All => true
*/
public function clean(?array $conditions = null): void
{
$conditions = (array) $conditions;
if (isset($conditions[self::Tags])) {
if (isset($conditions[self::Tags]) && !$conditions[self::Tags] instanceof CacheSelector) {
$conditions[self::Tags] = array_values((array) $conditions[self::Tags]);
}

Expand Down
34 changes: 34 additions & 0 deletions src/Caching/CacheSelector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Nette\Caching;

class CacheSelector
{
private array $conditions;


/**
* Adds where condition, more calls appends with AND.
* Pass tags as array to append with OR.
*
* Example:
* (new CacheSelector())->where("animal")->where("dog")->where(["brown", "white"])
* Creates condition looking for entities having tags animal and dog and (brown / white). Will not match entity, tagged animal, dog, black.
*
* @param string|array $tags tag names to select
*/
public function where(string|array $tags): static
{
$this->conditions[] = $tags;

return $this;
}


public function getConditions(): array
{
return $this->conditions;
}
}
18 changes: 15 additions & 3 deletions src/Caching/Storages/SQLiteJournal.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use Nette;
use Nette\Caching\Cache;
use Nette\Caching\CacheSelector;


/**
Expand Down Expand Up @@ -109,9 +110,20 @@ public function clean(array $conditions): ?array

$unions = $args = [];
if (!empty($conditions[Cache::Tags])) {
$tags = (array) $conditions[Cache::Tags];
$unions[] = 'SELECT DISTINCT key FROM tags WHERE tag IN (?' . str_repeat(', ?', count($tags) - 1) . ')';
$args = $tags;
if ($conditions[Cache::Tags] instanceof CacheSelector) {
$intersects = [];
foreach ($conditions[Cache::Tags]->getConditions() as $condition) {
$intersects[] = 'SELECT `key` FROM `tags` WHERE `tag` IN (?' . str_repeat(', ?', count((array) $condition) - 1) . ')';
is_array($condition)
? array_push($args, ...$condition)
: array_push($args, $condition);
}
$unions[] = implode(' INTERSECT ', $intersects);
} else {
$tags = (array) $conditions[Cache::Tags];
$unions[] = 'SELECT DISTINCT key FROM tags WHERE tag IN (?' . str_repeat(', ?', count($tags) - 1) . ')';
$args = $tags;
}
}

if (!empty($conditions[Cache::Priority])) {
Expand Down