Skip to content

Allow cleaning namespace only #52

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

Closed
wants to merge 11 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Caching/Cache.php
Original file line number Diff line number Diff line change
@@ -31,9 +31,9 @@ class Cache
ITEMS = 'items',
CONSTS = 'consts',
CALLBACKS = 'callbacks',
NAMESPACES = 'namespaces',
ALL = 'all';

/** @internal */
public const NAMESPACE_SEPARATOR = "\x00";

/** @var IStorage */
@@ -155,7 +155,7 @@ public function bulkLoad(array $keys, callable $fallback = null): array
*
* @param mixed
* @param mixed
* @return mixed value itself
* @return mixed value itself
* @throws Nette\InvalidArgumentException
*/
public function save($key, $data, array $dependencies = null)
18 changes: 17 additions & 1 deletion src/Caching/Storages/FileStorage.php
Original file line number Diff line number Diff line change
@@ -153,7 +153,7 @@ public function lock(string $key): void
/**
* Writes item into the cache.
*/
public function write(string $key, $data, array $dp): void
public function write(string $key, $data, array $dp = []): void
{
$meta = [
self::META_TIME => microtime(),
@@ -249,6 +249,7 @@ public function clean(array $conditions): void
{
$all = !empty($conditions[Cache::ALL]);
$collector = empty($conditions);
$namespaces = $conditions[Cache::NAMESPACES] ?? false;

// cleaning using file iterator
if ($all || $collector) {
@@ -284,6 +285,21 @@ public function clean(array $conditions): void
$this->journal->clean($conditions);
}
return;
} elseif ($namespaces) {
if (!is_array($namespaces)) {
$namespaces = [$namespaces];
}

foreach ($namespaces as $namespace) {
$dir = $this->dir . '/_' . urlencode($namespace);
if (is_dir($dir)) {
$items = Nette\Utils\Finder::findFiles('*')->from($dir);
foreach ($items as $item) {
$this->delete((string) $item);
}
@rmdir($dir); // may already contain new files
}
}
}

// cleaning using journal
16 changes: 14 additions & 2 deletions src/Caching/Storages/SQLiteStorage.php
Original file line number Diff line number Diff line change
@@ -142,8 +142,7 @@ public function clean(array $conditions): void
{
if (!empty($conditions[Cache::ALL])) {
$this->pdo->prepare('DELETE FROM cache')->execute();

} else {
} elseif (!empty($conditions[Cache::TAGS])) {
$sql = 'DELETE FROM cache WHERE expire < ?';
$args = [time()];

@@ -154,6 +153,19 @@ public function clean(array $conditions): void
}

$this->pdo->prepare($sql)->execute($args);
} elseif (!empty($conditions[Cache::NAMESPACES])) {
if (is_array($conditions[Cache::NAMESPACES])) {
$namespaces = $conditions[Cache::NAMESPACES];
} else {
$namespaces = [$conditions[Cache::NAMESPACES]];
}


foreach ($namespaces as $namespace) {
$this->pdo
->prepare('DELETE FROM cache WHERE key LIKE ?')
->execute([$namespace . Cache::NAMESPACE_SEPARATOR]);
}
}
}
}
6 changes: 3 additions & 3 deletions tests/Bridges.Latte/CacheMacro.createCache.phpt
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ require __DIR__ . '/../bootstrap.php';
test(function () {
$parents = [];
$dp = [Cache::TAGS => ['rum', 'cola']];
$outputHelper = CacheMacro::createCache(new DevNullStorage(), 'test', $parents);
$outputHelper = CacheMacro::createCache(new DevNullStorage, 'test', $parents);
Assert::type(Nette\Caching\OutputHelper::class, $outputHelper);
CacheMacro::endCache($parents, $dp);
Assert::same($dp + [Cache::EXPIRATION => '+ 7 days'], $outputHelper->dependencies);
@@ -29,7 +29,7 @@ test(function () {
$dpFallback = function () use ($dp) {
return $dp;
};
$outputHelper = CacheMacro::createCache(new DevNullStorage(), 'test', $parents);
$outputHelper = CacheMacro::createCache(new DevNullStorage, 'test', $parents);
CacheMacro::endCache($parents, ['dependencies' => $dpFallback]);
Assert::same($dp + [Cache::EXPIRATION => '+ 7 days'], $outputHelper->dependencies);
});
@@ -43,7 +43,7 @@ test(function () {
$dpFallback = function () use ($dp) {
return $dp;
};
$outputHelper = CacheMacro::createCache(new DevNullStorage(), 'test', $parents);
$outputHelper = CacheMacro::createCache(new DevNullStorage, 'test', $parents);
CacheMacro::endCache($parents, ['dependencies' => $dpFallback]);
Assert::same($dp, $outputHelper->dependencies);
});
2 changes: 1 addition & 1 deletion tests/Caching/Cache.bulkLoad.phpt
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ test(function () {

test(function () {
Assert::exception(function () {
$cache = new Cache(new BulkReadTestStorage());
$cache = new Cache(new BulkReadTestStorage);
$cache->bulkLoad([[1]]);
}, Nette\InvalidArgumentException::class, 'Only scalar keys are allowed in bulkLoad()');
});
4 changes: 2 additions & 2 deletions tests/Caching/Cache.load.phpt
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ require __DIR__ . '/Cache.php';


// load twice with fallback
$storage = new TestStorage();
$storage = new TestStorage;
$cache = new Cache($storage, 'ns');

$value = $cache->load('key', function () {
@@ -32,7 +32,7 @@ Assert::equal('value', $data['data']);

// load twice with closure fallback, pass dependencies
$dependencies = [Cache::TAGS => ['tag']];
$storage = new TestStorage();
$storage = new TestStorage;
$cache = new Cache($storage, 'ns');

$value = $cache->load('key', function (&$deps) use ($dependencies) {
8 changes: 4 additions & 4 deletions tests/Caching/Cache.save.phpt
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ require __DIR__ . '/Cache.php';


// save value with dependencies
$storage = new testStorage();
$storage = new testStorage;
$cache = new Cache($storage, 'ns');
$dependencies = [Cache::TAGS => ['tag']];

@@ -28,7 +28,7 @@ Assert::equal($dependencies, $res['dependencies']);


// save callback return value
$storage = new testStorage();
$storage = new testStorage;
$cache = new Cache($storage, 'ns');

$cache->save('key', function () {
@@ -41,7 +41,7 @@ Assert::equal([], $res['dependencies']);


// save callback return value with dependencies
$storage = new testStorage();
$storage = new testStorage;
$cache = new Cache($storage, 'ns');
$dependencies = [Cache::TAGS => ['tag']];

@@ -55,7 +55,7 @@ Assert::equal($dependencies, $res['dependencies']);


// do not save already expired data
$storage = new testStorage();
$storage = new testStorage;
$cache = new Cache($storage, 'ns');
$dependencies = [Cache::EXPIRATION => new DateTime];

1 change: 0 additions & 1 deletion tests/Storages/FileStorage.clean-all.phpt
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ use Nette\Caching\Cache;
use Nette\Caching\Storages\FileStorage;
use Tester\Assert;


require __DIR__ . '/../bootstrap.php';


109 changes: 109 additions & 0 deletions tests/Storages/FileStorage.clean-namespace.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

/**
* Test: Nette\Caching\Storages\FileStorage clean with Cache::NAMESPACE
*/

declare(strict_types=1);

use Nette\Caching\Cache;
use Nette\Caching\Storages\FileStorage;
use Tester\Assert;


require __DIR__ . '/../bootstrap.php';

$storage = new FileStorage(TEMP_DIR);

/*
* Create filestorage cache without namespace and some with namespaces
*/
$cacheA = new Cache($storage);
$cacheB = new Cache($storage, 'B');
$cacheC = new Cache($storage, 'C');
$cacheD = new Cache($storage, 'D');

/*
* Fill with data
*/
$cacheA->save('test1', 'David');
$cacheA->save('test2', 'Grudl');

$cacheB->save('test1', 'Barry');
$cacheB->save('test2', 'Allen');

$cacheC->save('test1', 'Oliver');
$cacheC->save('test2', 'Queen');

$cacheD->save('test1', 'Bruce');
$cacheD->save('test2', 'Wayne');


/*
* Check if fill wass successfull
*/
Assert::same('David Grudl', implode(' ', [
$cacheA->load('test1'),
$cacheA->load('test2'),
]));

Assert::same('Barry Allen', implode(' ', [
$cacheB->load('test1'),
$cacheB->load('test2'),
]));

Assert::same('Oliver Queen', implode(' ', [
$cacheC->load('test1'),
$cacheC->load('test2'),
]));

Assert::same('Bruce Wayne', implode(' ', [
$cacheD->load('test1'),
$cacheD->load('test2'),
]));


/*
* Clean one namespace
*/
$storage->clean([Cache::NAMESPACES => 'B']);

Assert::same('David Grudl', implode(' ', [
$cacheA->load('test1'),
$cacheA->load('test2'),
]));

// Only these should be null now
Assert::null($cacheB->load('test1'));
Assert::null($cacheB->load('test2'));

Assert::same('Oliver Queen', implode(' ', [
$cacheC->load('test1'),
$cacheC->load('test2'),
]));

Assert::same('Bruce Wayne', implode(' ', [
$cacheD->load('test1'),
$cacheD->load('test2'),
]));


/*
* Test cleaning multiple namespaces
*/
$storage->clean([Cache::NAMESPACES => ['C', 'D']]);

Assert::same('David Grudl', implode(' ', [
$cacheA->load('test1'),
$cacheA->load('test2'),
]));

// All other should be null
Assert::null($cacheB->load('test1'));
Assert::null($cacheB->load('test2'));

Assert::null($cacheC->load('test1'));
Assert::null($cacheC->load('test2'));

Assert::null($cacheD->load('test1'));
Assert::null($cacheD->load('test2'));
3 changes: 3 additions & 0 deletions tests/Storages/SQLiteJournal.phpt
Original file line number Diff line number Diff line change
@@ -14,6 +14,9 @@ require __DIR__ . '/../bootstrap.php';
require __DIR__ . '/IJournalTestCase.php';


/**
* @testCase
*/
class SQLiteJournalTest extends IJournalTestCase
{
public function createJournal()
110 changes: 110 additions & 0 deletions tests/Storages/SQLiteStorage.clean-namespace.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

/**
* Test: Nette\Caching\Storages\SQLiteStorage clean with Cache::NAMESPACE
*/


declare(strict_types=1);

use Nette\Caching\Cache;
use Nette\Caching\Storages\SQLiteStorage;
use Tester\Assert;


require __DIR__ . '/../bootstrap.php';

$storage = new SQLiteStorage(':memory:');

/*
* Create SQLiteStorage cache without namespace and some with namespaces
*/
$cacheA = new Cache($storage);
$cacheB = new Cache($storage, 'B');
$cacheC = new Cache($storage, 'C');
$cacheD = new Cache($storage, 'D');

/*
* Fill with data
*/
$cacheA->save('test1', 'David');
$cacheA->save('test2', 'Grudl');

$cacheB->save('test1', 'Barry');
$cacheB->save('test2', 'Allen');

$cacheC->save('test1', 'Oliver');
$cacheC->save('test2', 'Queen');

$cacheD->save('test1', 'Bruce');
$cacheD->save('test2', 'Wayne');


/*
* Check if fill wass successfull
*/
Assert::same('David Grudl', implode(' ', [
$cacheA->load('test1'),
$cacheA->load('test2'),
]));

Assert::same('Barry Allen', implode(' ', [
$cacheB->load('test1'),
$cacheB->load('test2'),
]));

Assert::same('Oliver Queen', implode(' ', [
$cacheC->load('test1'),
$cacheC->load('test2'),
]));

Assert::same('Bruce Wayne', implode(' ', [
$cacheD->load('test1'),
$cacheD->load('test2'),
]));


/*
* Clean one namespace
*/
$storage->clean([Cache::NAMESPACES => 'B']);

Assert::same('David Grudl', implode(' ', [
$cacheA->load('test1'),
$cacheA->load('test2'),
]));

// Only these should be null now
Assert::null($cacheB->load('test1'));
Assert::null($cacheB->load('test2'));

Assert::same('Oliver Queen', implode(' ', [
$cacheC->load('test1'),
$cacheC->load('test2'),
]));

Assert::same('Bruce Wayne', implode(' ', [
$cacheD->load('test1'),
$cacheD->load('test2'),
]));


/*
* Test cleaning multiple namespaces
*/
$storage->clean([Cache::NAMESPACES => ['C', 'D']]);

Assert::same('David Grudl', implode(' ', [
$cacheA->load('test1'),
$cacheA->load('test2'),
]));

// All other should be null
Assert::null($cacheB->load('test1'));
Assert::null($cacheB->load('test2'));

Assert::null($cacheC->load('test1'));
Assert::null($cacheC->load('test2'));

Assert::null($cacheD->load('test1'));
Assert::null($cacheD->load('test2'));
27 changes: 25 additions & 2 deletions tests/php-unix.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
[PHP]
;extension_dir = "./ext"
extension=memcache.so
extension=memcached.so
extension=bz2.so
extension=ctype.so
extension=curl.so
extension=dom.so
extension=gd.so
extension=gettext.so
extension=iconv.so
extension=intl.so
extension=json.so
extension=mbstring.so
extension=mcrypt.so
extension=mysqli.so
extension=openssl.so
extension=pdo.so
extension=pdo_mysql.so
extension=pdo_sqlite.so
extension=phar.so
extension=soap.so
extension=sockets.so
extension=sqlite3.so
extension=tokenizer.so
extension=xmlreader.so
extension=xmlwriter.so
extension=zip.so
extension=zlib.so

[Zend]
;zend_extension="./ext/zend_extension"