1
0
mirror of synced 2025-02-02 21:41:45 +03:00

Evict query cache when entities are updated

This commit is contained in:
Luís Cobucci 2016-09-02 09:54:14 +00:00 committed by Marco Pivetta
parent bf18aac62d
commit 88567ea395
4 changed files with 78 additions and 4 deletions

View File

@ -110,7 +110,9 @@ class CacheConfiguration
public function getQueryValidator() public function getQueryValidator()
{ {
if ($this->queryValidator === null) { if ($this->queryValidator === null) {
$this->queryValidator = new TimestampQueryCacheValidator(); $this->queryValidator = new TimestampQueryCacheValidator(
$this->cacheFactory->getTimestampRegion()
);
} }
return $this->queryValidator; return $this->queryValidator;

View File

@ -26,15 +26,49 @@ namespace Doctrine\ORM\Cache;
*/ */
class TimestampQueryCacheValidator implements QueryCacheValidator class TimestampQueryCacheValidator implements QueryCacheValidator
{ {
/**
* @var TimestampRegion
*/
private $timestampRegion;
/**
* @param TimestampRegion $timestampRegion
*/
public function __construct(TimestampRegion $timestampRegion)
{
$this->timestampRegion = $timestampRegion;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function isValid(QueryCacheKey $key, QueryCacheEntry $entry) public function isValid(QueryCacheKey $key, QueryCacheEntry $entry)
{ {
if ($this->regionUpdated($key, $entry)) {
return false;
}
if ($key->lifetime == 0) { if ($key->lifetime == 0) {
return true; return true;
} }
return ($entry->time + $key->lifetime) > microtime(true); return ($entry->time + $key->lifetime) > microtime(true);
} }
/**
* @param QueryCacheKey $key
* @param QueryCacheEntry $entry
*
* @return bool
*/
private function regionUpdated(QueryCacheKey $key, QueryCacheEntry $entry)
{
if ($key->timestampKey === null) {
return false;
}
$timestamp = $this->timestampRegion->get($key->timestampKey);
return $timestamp && $timestamp->time > $entry->time;
}
} }

View File

@ -2,8 +2,8 @@
namespace Doctrine\Tests\ORM\Cache; namespace Doctrine\Tests\ORM\Cache;
use Doctrine\Tests\DoctrineTestCase;
use Doctrine\ORM\Cache\CacheConfiguration; use Doctrine\ORM\Cache\CacheConfiguration;
use Doctrine\Tests\DoctrineTestCase;
/** /**
* @group DDC-2183 * @group DDC-2183
@ -64,6 +64,11 @@ class CacheConfigTest extends DoctrineTestCase
public function testSetGetQueryValidator() public function testSetGetQueryValidator()
{ {
$factory = $this->getMock('Doctrine\ORM\Cache\CacheFactory');
$factory->method('getTimestampRegion')->willReturn($this->getMock('Doctrine\ORM\Cache\TimestampRegion'));
$this->config->setCacheFactory($factory);
$validator = $this->getMock('Doctrine\ORM\Cache\QueryCacheValidator'); $validator = $this->getMock('Doctrine\ORM\Cache\QueryCacheValidator');
$this->assertInstanceOf('Doctrine\ORM\Cache\TimestampQueryCacheValidator', $this->config->getQueryValidator()); $this->assertInstanceOf('Doctrine\ORM\Cache\TimestampQueryCacheValidator', $this->config->getQueryValidator());

View File

@ -1035,4 +1035,37 @@ class SecondLevelCacheQueryCacheTest extends SecondLevelCacheAbstractTest
->setCacheable(true) ->setCacheable(true)
->getResult(); ->getResult();
} }
public function testQueryCacheShouldBeEvictedOnTimestampUpdate()
{
$this->loadFixturesCountries();
$this->_em->clear();
$queryCount = $this->getCurrentQueryCount();
$dql = 'SELECT country FROM Doctrine\Tests\Models\Cache\Country country';
$result1 = $this->_em->createQuery($dql)
->setCacheable(true)
->getResult();
$this->assertCount(2, $result1);
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->_em->persist(new Country('France'));
$this->_em->flush();
$this->_em->clear();
$queryCount = $this->getCurrentQueryCount();
$result2 = $this->_em->createQuery($dql)
->setCacheable(true)
->getResult();
$this->assertCount(3, $result2);
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
foreach ($result2 as $entity) {
$this->assertInstanceOf(Country::CLASSNAME, $entity);
}
}
} }