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(cache): add deleteMatching method to remove multiple cache items #4567

Merged
Merged
Show file tree
Hide file tree
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
15 changes: 15 additions & 0 deletions system/Cache/Handlers/BaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Closure;
use CodeIgniter\Cache\CacheInterface;
use Exception;

/**
* Base class for cache handling
Expand Down Expand Up @@ -41,4 +42,18 @@ public function remember(string $key, int $ttl, Closure $callback)

return $value;
}

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @throws Exception
*/
public function deleteMatching(string $pattern)
{
throw new Exception('The deleteMatching method is not implemented.');
}
}
14 changes: 14 additions & 0 deletions system/Cache/Handlers/DummyHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,20 @@ public function delete(string $key)

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @return boolean
*/
public function deleteMatching(string $pattern)
{
return true;
yassinedoghri marked this conversation as resolved.
Show resolved Hide resolved
}

//--------------------------------------------------------------------

/**
* Performs atomic incrementation of a raw stored value.
*
Expand Down
24 changes: 24 additions & 0 deletions system/Cache/Handlers/FileHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,30 @@ public function delete(string $key)

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @return boolean
*/
public function deleteMatching(string $pattern)
{
$success = true;

foreach (glob($this->path . $pattern) as $filename)
{
if (! is_file($filename) || ! @unlink($filename))
{
$success = false;
}
}

return $success;
}

//--------------------------------------------------------------------

/**
* Performs atomic incrementation of a raw stored value.
*
Expand Down
14 changes: 14 additions & 0 deletions system/Cache/Handlers/MemcachedHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,20 @@ public function delete(string $key)

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @throws Exception
*/
public function deleteMatching(string $pattern)
{
throw new Exception('The deleteMatching method is not implemented for Memcached. You must select File, Redis or Predis handlers to use it.');
}

//--------------------------------------------------------------------

/**
* Performs atomic incrementation of a raw stored value.
*
Expand Down
25 changes: 25 additions & 0 deletions system/Cache/Handlers/PredisHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Config\Cache;
use Exception;
use Predis\Client;
use Predis\Collection\Iterator\Keyspace;

/**
* Predis cache handler
Expand Down Expand Up @@ -184,6 +185,30 @@ public function delete(string $key)

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @return boolean
*/
public function deleteMatching(string $pattern)
{
$success = true;

foreach (new Keyspace($this->redis, $pattern) as $key)
{
if ($this->redis->del($key) !== 1)
{
$success = false;
}
}

return $success;
}

//--------------------------------------------------------------------

/**
* Performs atomic incrementation of a raw stored value.
*
Expand Down
28 changes: 28 additions & 0 deletions system/Cache/Handlers/RedisHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,34 @@ public function delete(string $key)

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @return boolean
*/
public function deleteMatching(string $pattern)
{
$success = true;
$iterator = null;

while ($keys = $this->redis->scan($iterator, $pattern))
{
foreach ($keys as $key)
{
if ($this->redis->del($key) !== 1)
{
$success = false;
}
}
}

return $success;
}

//--------------------------------------------------------------------

/**
* Performs atomic incrementation of a raw stored value.
*
Expand Down
17 changes: 17 additions & 0 deletions system/Cache/Handlers/WincacheHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace CodeIgniter\Cache\Handlers;

use Config\Cache;
use Exception;

/**
* Cache handler for WinCache from Microsoft & IIS.
Expand Down Expand Up @@ -113,6 +114,22 @@ public function delete(string $key)

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @throws Exception
*
* @codeCoverageIgnore
*/
public function deleteMatching(string $pattern)
{
throw new Exception('The deleteMatching method is not implemented for Wincache. You must select File, Redis or Predis handlers to use it.');
}

//--------------------------------------------------------------------

/**
* Performs atomic incrementation of a raw stored value.
*
Expand Down
22 changes: 22 additions & 0 deletions system/Test/Mock/MockCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,28 @@ public function delete(string $key)

//--------------------------------------------------------------------

/**
* Deletes items from the cache store matching a given pattern.
*
* @param string $pattern Cache items glob-style pattern
*
* @return boolean
*/
public function deleteMatching(string $pattern)
{
foreach (array_keys($this->cache) as $key)
{
if (fnmatch($pattern, $key))
{
unset($this->cache[$key]);
}
}

return true;
}

//--------------------------------------------------------------------

/**
* Performs atomic incrementation of a raw stored value.
*
Expand Down
5 changes: 5 additions & 0 deletions tests/system/Cache/Handlers/DummyHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public function testDelete()
$this->assertTrue($this->dummyHandler->delete('key'));
}

public function testDeleteMatching()
{
$this->assertTrue($this->dummyHandler->deleteMatching('key*'));
}

public function testIncrement()
{
$this->assertTrue($this->dummyHandler->increment('key'));
Expand Down
22 changes: 22 additions & 0 deletions tests/system/Cache/Handlers/FileHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ class FileHandlerTest extends CIUnitTestCase
private static $key1 = 'key1';
private static $key2 = 'key2';
private static $key3 = 'key3';
private static $key4 = 'another_key';

private static function getKeyArray()
{
return [
self::$key1,
self::$key2,
self::$key3,
self::$key4,
];
}

Expand Down Expand Up @@ -133,6 +135,26 @@ public function testDelete()
$this->assertFalse($this->fileHandler->delete(self::$dummy));
}

public function testDeleteMatching()
{
$this->fileHandler->save(self::$key1, 'value');
$this->fileHandler->save(self::$key2, 'value2');
$this->fileHandler->save(self::$key3, 'value3');
$this->fileHandler->save(self::$key4, 'value4');

$this->assertSame('value', $this->fileHandler->get(self::$key1));
$this->assertSame('value2', $this->fileHandler->get(self::$key2));
$this->assertSame('value3', $this->fileHandler->get(self::$key3));
$this->assertSame('value4', $this->fileHandler->get(self::$key4));

$this->assertTrue($this->fileHandler->deleteMatching('key*'));

$this->assertNull($this->fileHandler->get(self::$key1));
$this->assertNull($this->fileHandler->get(self::$key2));
$this->assertNull($this->fileHandler->get(self::$key3));
$this->assertSame('value4', $this->fileHandler->get(self::$key4));
}

public function testIncrement()
{
$this->fileHandler->save(self::$key1, 1);
Expand Down
9 changes: 9 additions & 0 deletions tests/system/Cache/Handlers/MemcachedHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use CodeIgniter\CLI\CLI;
use CodeIgniter\Test\CIUnitTestCase;
use Config\Cache;
use Exception;

class MemcachedHandlerTest extends CIUnitTestCase
{
Expand Down Expand Up @@ -89,6 +90,14 @@ public function testDelete()
$this->assertFalse($this->memcachedHandler->delete(self::$dummy));
}

public function testDeleteMatching()
{
// Not implemented for Memcached, should throw an exception
$this->expectException(Exception::class);

$this->memcachedHandler->deleteMatching('key*');
}

public function testIncrement()
{
$this->memcachedHandler->save(self::$key1, 1);
Expand Down
23 changes: 23 additions & 0 deletions tests/system/Cache/Handlers/PredisHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ class PredisHandlerTest extends CIUnitTestCase
private static $key1 = 'key1';
private static $key2 = 'key2';
private static $key3 = 'key3';
private static $key4 = 'another_key';

private static function getKeyArray()
{
return [
self::$key1,
self::$key2,
self::$key3,
self::$key4,
];
}

Expand Down Expand Up @@ -97,6 +100,26 @@ public function testDelete()
$this->assertFalse($this->PredisHandler->delete(self::$dummy));
}

public function testDeleteMatching()
{
$this->PredisHandler->save(self::$key1, 'value');
$this->PredisHandler->save(self::$key2, 'value2');
$this->PredisHandler->save(self::$key3, 'value3');
$this->PredisHandler->save(self::$key4, 'value4');

$this->assertSame('value', $this->PredisHandler->get(self::$key1));
$this->assertSame('value2', $this->PredisHandler->get(self::$key2));
$this->assertSame('value3', $this->PredisHandler->get(self::$key3));
$this->assertSame('value4', $this->PredisHandler->get(self::$key4));

$this->assertTrue($this->PredisHandler->deleteMatching('key*'));

$this->assertNull($this->PredisHandler->get(self::$key1));
$this->assertNull($this->PredisHandler->get(self::$key2));
$this->assertNull($this->PredisHandler->get(self::$key3));
$this->assertSame('value4', $this->PredisHandler->get(self::$key4));
}

public function testClean()
{
$this->PredisHandler->save(self::$key1, 1);
Expand Down
23 changes: 23 additions & 0 deletions tests/system/Cache/Handlers/RedisHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ class RedisHandlerTest extends CIUnitTestCase
private static $key1 = 'key1';
private static $key2 = 'key2';
private static $key3 = 'key3';
private static $key4 = 'another_key';

private static function getKeyArray()
{
return [
self::$key1,
self::$key2,
self::$key3,
self::$key4,
];
}

Expand Down Expand Up @@ -97,6 +100,26 @@ public function testDelete()
$this->assertFalse($this->redisHandler->delete(self::$dummy));
}

public function testDeleteMatching()
{
$this->redisHandler->save(self::$key1, 'value');
$this->redisHandler->save(self::$key2, 'value2');
$this->redisHandler->save(self::$key3, 'value3');
$this->redisHandler->save(self::$key4, 'value4');

$this->assertSame('value', $this->redisHandler->get(self::$key1));
$this->assertSame('value2', $this->redisHandler->get(self::$key2));
$this->assertSame('value3', $this->redisHandler->get(self::$key3));
$this->assertSame('value4', $this->redisHandler->get(self::$key4));

$this->assertTrue($this->redisHandler->deleteMatching('key*'));

$this->assertNull($this->redisHandler->get(self::$key1));
$this->assertNull($this->redisHandler->get(self::$key2));
$this->assertNull($this->redisHandler->get(self::$key3));
$this->assertSame('value4', $this->redisHandler->get(self::$key4));
}

//FIXME: I don't like all Hash logic very much. It's wasting memory.
//public function testIncrement()
//{
Expand Down
Loading