Evict query cache when entities are updated
This commit is contained in:
parent
b49026b657
commit
b431332cef
@ -110,7 +110,9 @@ class CacheConfiguration
|
||||
public function getQueryValidator()
|
||||
{
|
||||
if ($this->queryValidator === null) {
|
||||
$this->queryValidator = new TimestampQueryCacheValidator();
|
||||
$this->queryValidator = new TimestampQueryCacheValidator(
|
||||
$this->cacheFactory->getTimestampRegion()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->queryValidator;
|
||||
|
@ -26,15 +26,49 @@ namespace Doctrine\ORM\Cache;
|
||||
*/
|
||||
class TimestampQueryCacheValidator implements QueryCacheValidator
|
||||
{
|
||||
/**
|
||||
* @var TimestampRegion
|
||||
*/
|
||||
private $timestampRegion;
|
||||
|
||||
/**
|
||||
* @param TimestampRegion $timestampRegion
|
||||
*/
|
||||
public function __construct(TimestampRegion $timestampRegion)
|
||||
{
|
||||
$this->timestampRegion = $timestampRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isValid(QueryCacheKey $key, QueryCacheEntry $entry)
|
||||
{
|
||||
if ($this->regionUpdated($key, $entry)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($key->lifetime == 0) {
|
||||
return 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;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use Doctrine\ORM\Cache\CacheConfiguration;
|
||||
use Doctrine\ORM\Cache\CacheFactory;
|
||||
use Doctrine\ORM\Cache\QueryCacheValidator;
|
||||
use Doctrine\ORM\Cache\Logging\CacheLogger;
|
||||
use Doctrine\ORM\Cache\TimestampRegion;
|
||||
use Doctrine\Tests\DoctrineTestCase;
|
||||
|
||||
/**
|
||||
@ -67,6 +68,11 @@ class CacheConfigTest extends DoctrineTestCase
|
||||
|
||||
public function testSetGetQueryValidator()
|
||||
{
|
||||
$factory = $this->createMock(CacheFactory::class);
|
||||
$factory->method('getTimestampRegion')->willReturn($this->createMock(TimestampRegion::class));
|
||||
|
||||
$this->config->setCacheFactory($factory);
|
||||
|
||||
$validator = $this->createMock(QueryCacheValidator::class);
|
||||
|
||||
$this->assertInstanceOf('Doctrine\ORM\Cache\TimestampQueryCacheValidator', $this->config->getQueryValidator());
|
||||
|
@ -1120,4 +1120,37 @@ class SecondLevelCacheQueryCacheTest extends SecondLevelCacheAbstractTest
|
||||
->setCacheable(true)
|
||||
->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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user