Skip to content

Commit

Permalink
Add MultiDeleteCache interface and default CacheProvider implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Benoît Burnichon authored and Ocramius committed Dec 17, 2016
1 parent 9fa5962 commit 900b518
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 1 deletion.
36 changes: 35 additions & 1 deletion lib/Doctrine/Common/Cache/CacheProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
* @author Jonathan Wage <[email protected]>
* @author Roman Borschel <[email protected]>
* @author Fabio B. Silva <[email protected]>
* @author Benoit Burnichon <[email protected]>
*/
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache, MultiDeleteCache
{
const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';

Expand Down Expand Up @@ -132,6 +133,19 @@ public function save($id, $data, $lifeTime = 0)
return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
}

/**
* {@inheritdoc}
*/
public function deleteMultiple(array $keys)
{
$namespacedKeys = array();
foreach ($keys as $key) {
$namespacedKeys[] = $this->getNamespacedId($key);
}

return $this->doDeleteMultiple($namespacedKeys);
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -285,6 +299,26 @@ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
*/
abstract protected function doSave($id, $data, $lifeTime = 0);

/**
* Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it.
*
* @param array $keys Array of keys to delete from cache
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't
*/
protected function doDeleteMultiple(array $keys)
{
$success = true;

foreach ($keys as $key) {
if (!$this->doDelete($key)) {
$success = false;
}
}

return $success;
}

/**
* Deletes a cache entry.
*
Expand Down
9 changes: 9 additions & 0 deletions lib/Doctrine/Common/Cache/MemcachedCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ protected function doSave($id, $data, $lifeTime = 0)
return $this->memcached->set($id, $data, (int) $lifeTime);
}

/**
* {@inheritdoc}
*/
protected function doDeleteMultiple(array $keys)
{
return $this->memcached->deleteMulti($keys)
|| $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
}

/**
* {@inheritdoc}
*/
Expand Down
39 changes: 39 additions & 0 deletions lib/Doctrine/Common/Cache/MultiDeleteCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\Common\Cache;

/**
* Interface for cache drivers that allows to put many items at once.
*
* @link www.doctrine-project.org
* @since 1.7
* @author Benoit Burnichon <[email protected]>
*/
interface MultiDeleteCache
{
/**
* Returns a boolean value indicating if the operation succeeded.
*
* @param array $keys Array of keys to delete from cache
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
function deleteMultiple(array $keys);
}
31 changes: 31 additions & 0 deletions tests/Doctrine/Tests/Common/Cache/CacheProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,35 @@ public function testSaveMultipleNoFail()
'kok' => 'vok',
]);
}

public function testDeleteMultipleNoFail()
{
/* @var $cache \Doctrine\Common\Cache\CacheProvider|\PHPUnit_Framework_MockObject_MockObject */
$cache = $this->getMockForAbstractClass(
'Doctrine\Common\Cache\CacheProvider',
array(),
'',
true,
true,
true,
array('doDelete')
);

$cache
->expects($this->at(1))
->method('doDelete')
->with('[kerr][1]')
->will($this->returnValue(false));

$cache
->expects($this->at(2))
->method('doDelete')
->with('[kok][1]')
->will($this->returnValue(true));

$cache->deleteMultiple(array(
'kerr',
'kok',
));
}
}
12 changes: 12 additions & 0 deletions tests/Doctrine/Tests/Common/Cache/CacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ public function testDeleteAll()
$this->assertFalse($cache->contains('key2'));
}

public function testDeleteMulti()
{
$cache = $this->_getCacheDriver();

$this->assertTrue($cache->save('key1', 1));
$this->assertTrue($cache->save('key2', 1));
$this->assertTrue($cache->deleteMultiple(array('key1', 'key2', 'key3')));
$this->assertFalse($cache->contains('key1'));
$this->assertFalse($cache->contains('key2'));
$this->assertFalse($cache->contains('key3'));
}

/**
* @dataProvider provideCacheIds
*/
Expand Down

0 comments on commit 900b518

Please sign in to comment.