[2.0] DDC-125 - Query Hints are now included in both QueryCache and ResultCache - QueryCache now also uses firstResult and maxResults for the cache key - ResultCache was fixed to use "getSql()" instead of "getDql()"
This commit is contained in:
parent
ca23555c3e
commit
04832e2789
@ -488,7 +488,7 @@ abstract class AbstractQuery
|
||||
|
||||
// Check result cache
|
||||
if ($this->_useResultCache && $cacheDriver = $this->getResultCacheDriver()) {
|
||||
$id = $this->getResultCacheId($params);
|
||||
$id = $this->_getResultCacheId($params);
|
||||
$cached = $this->_expireResultCache ? false : $cacheDriver->fetch($id);
|
||||
|
||||
if ($cached === false) {
|
||||
@ -541,12 +541,14 @@ abstract class AbstractQuery
|
||||
* @param array $params
|
||||
* @return string $id
|
||||
*/
|
||||
public function getResultCacheId(array $params)
|
||||
protected function _getResultCacheId(array $params)
|
||||
{
|
||||
if ($this->_resultCacheId) {
|
||||
return $this->_resultCacheId;
|
||||
} else {
|
||||
return md5($this->getDql() . var_export($params, true));
|
||||
$sql = $this->getSql();
|
||||
ksort($this->_hints);
|
||||
return md5(implode(";", (array)$sql) . var_export($params, true) . var_export($this->_hints, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,11 +173,7 @@ final class Query extends AbstractQuery
|
||||
{
|
||||
// Check query cache
|
||||
if ($queryCache = $this->getQueryCacheDriver()) {
|
||||
// Calculate hash for dql query.
|
||||
// TODO: Probably need to include query hints in hash calculation, because query hints
|
||||
// can have influence on the SQL.
|
||||
// TODO: Include _maxResults and _firstResult in hash calculation
|
||||
$hash = md5($this->getDql() . 'DOCTRINE_QUERY_CACHE_SALT');
|
||||
$hash = $this->_getQueryCacheId();
|
||||
$cached = ($this->_expireQueryCache) ? false : $queryCache->fetch($hash);
|
||||
|
||||
if ($cached === false) {
|
||||
@ -438,4 +434,21 @@ final class Query extends AbstractQuery
|
||||
$this->setHint(self::HINT_INTERNAL_ITERATION, true);
|
||||
return parent::iterate($params, $hydrationMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a cache id for the query cache - reusing the Result-Cache-Id generator.
|
||||
*
|
||||
* The query cache
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getQueryCacheId()
|
||||
{
|
||||
ksort($this->_hints);
|
||||
|
||||
return md5(
|
||||
$this->getDql() . var_export($this->_hints, true) .
|
||||
'firstResult='.$this->_firstResult.'&maxResult='.$this->_maxResults.'DOCTRINE_QUERY_CACHE_SALT'
|
||||
);
|
||||
}
|
||||
}
|
@ -19,38 +19,101 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testQueryCache()
|
||||
public function testQueryCache_DependsOnHints()
|
||||
{
|
||||
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
|
||||
|
||||
$cache = new ArrayCache();
|
||||
$query->setQueryCacheDriver($cache);
|
||||
|
||||
$query->getResult();
|
||||
$this->assertEquals(1, count($cache->getIds()));
|
||||
|
||||
$query->setHint('foo', 'bar');
|
||||
|
||||
$query->getResult();
|
||||
$this->assertEquals(2, count($cache->getIds()));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <type> $query
|
||||
* @depends testQueryCache_DependsOnHints
|
||||
*/
|
||||
public function testQueryCache_DependsOnFirstResult($query)
|
||||
{
|
||||
$cache = $query->getQueryCacheDriver();
|
||||
$cacheCount = count($cache->getIds());
|
||||
|
||||
$query->setFirstResult(10);
|
||||
|
||||
$query->getResult();
|
||||
$this->assertEquals($cacheCount + 1, count($cache->getIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <type> $query
|
||||
* @depends testQueryCache_DependsOnHints
|
||||
*/
|
||||
public function testQueryCache_DependsOnMaxResults($query)
|
||||
{
|
||||
$cache = $query->getQueryCacheDriver();
|
||||
$cacheCount = count($cache->getIds());
|
||||
|
||||
$query->setMaxResults(10);
|
||||
|
||||
$query->getResult();
|
||||
$this->assertEquals($cacheCount + 1, count($cache->getIds()));
|
||||
}
|
||||
|
||||
public function testQueryCache_NoHitSaveParserResult()
|
||||
{
|
||||
$this->_em->getConfiguration()->setQueryCacheImpl(null);
|
||||
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Roman';
|
||||
$user->username = 'romanb';
|
||||
$user->status = 'dev';
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
|
||||
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
|
||||
$cache = new ArrayCache;
|
||||
|
||||
$cache = $this->getMock('Doctrine\Common\Cache\AbstractCache', array('_doFetch', '_doContains', '_doSave', '_doDelete', 'getIds'));
|
||||
$cache->expects($this->at(0))
|
||||
->method('_doFetch')
|
||||
->with($this->isType('string'))
|
||||
->will($this->returnValue(false));
|
||||
$cache->expects($this->at(1))
|
||||
->method('_doSave')
|
||||
->with($this->isType('string'), $this->isInstanceOf('Doctrine\ORM\Query\ParserResult'), $this->equalTo(null));
|
||||
|
||||
$query->setQueryCacheDriver($cache);
|
||||
|
||||
$users = $query->getResult();
|
||||
}
|
||||
|
||||
$this->assertTrue($cache->contains(md5('select ux from Doctrine\Tests\Models\CMS\CmsUser uxDOCTRINE_QUERY_CACHE_SALT')));
|
||||
$this->assertEquals(1, count($users));
|
||||
$this->assertEquals('Roman', $users[0]->name);
|
||||
public function testQueryCache_HitDoesNotSaveParserResult()
|
||||
{
|
||||
$this->_em->getConfiguration()->setQueryCacheImpl(null);
|
||||
|
||||
$this->_em->clear();
|
||||
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
|
||||
|
||||
$query2 = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
|
||||
$query2->setQueryCacheDriver($cache);
|
||||
$sqlExecMock = $this->getMock('Doctrine\ORM\Query\Exec\AbstractSqlExecutor', array('execute'));
|
||||
$sqlExecMock->expects($this->once())
|
||||
->method('execute')
|
||||
->will($this->returnValue( 10 ));
|
||||
|
||||
$users = $query2->getResult();
|
||||
$parserResultMock = $this->getMock('Doctrine\ORM\Query\ParserResult');
|
||||
$parserResultMock->expects($this->once())
|
||||
->method('getSqlExecutor')
|
||||
->will($this->returnValue($sqlExecMock));
|
||||
|
||||
$this->assertTrue($cache->contains(md5('select ux from Doctrine\Tests\Models\CMS\CmsUser uxDOCTRINE_QUERY_CACHE_SALT')));
|
||||
$this->assertEquals(1, count($users));
|
||||
$this->assertEquals('Roman', $users[0]->name);
|
||||
$cache = $this->getMock('Doctrine\Common\Cache\AbstractCache', array('_doFetch', '_doContains', '_doSave', '_doDelete', 'getIds'));
|
||||
$cache->expects($this->once())
|
||||
->method('_doFetch')
|
||||
->with($this->isType('string'))
|
||||
->will($this->returnValue($parserResultMock));
|
||||
$cache->expects($this->never())
|
||||
->method('_doSave');
|
||||
|
||||
$query->setQueryCacheDriver($cache);
|
||||
|
||||
$users = $query->getResult();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,23 +30,27 @@ class ResultCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
|
||||
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
|
||||
$cache = new ArrayCache;
|
||||
$query->setResultCacheDriver($cache);
|
||||
|
||||
$cache = new ArrayCache();
|
||||
|
||||
$query->setResultCacheDriver($cache)->setResultCacheId('my_cache_id');
|
||||
|
||||
$this->assertFalse($cache->contains('my_cache_id'));
|
||||
|
||||
$users = $query->getResult();
|
||||
|
||||
$this->assertTrue($cache->contains($query->getResultCacheId(array())));
|
||||
$this->assertTrue($cache->contains('my_cache_id'));
|
||||
$this->assertEquals(1, count($users));
|
||||
$this->assertEquals('Roman', $users[0]->name);
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$query2 = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
|
||||
$query2->setResultCacheDriver($cache);
|
||||
$query2->setResultCacheDriver($cache)->setResultCacheId('my_cache_id');
|
||||
|
||||
$users = $query2->getResult();
|
||||
|
||||
$this->assertTrue($cache->contains($query->getResultCacheId(array())));
|
||||
$this->assertTrue($cache->contains('my_cache_id'));
|
||||
$this->assertEquals(1, count($users));
|
||||
$this->assertEquals('Roman', $users[0]->name);
|
||||
}
|
||||
@ -58,6 +62,9 @@ class ResultCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
|
||||
$query->setResultCacheDriver($cache);
|
||||
$query->setResultCacheId('testing_result_cache_id');
|
||||
|
||||
$this->assertFalse($cache->contains('testing_result_cache_id'));
|
||||
|
||||
$users = $query->getResult();
|
||||
|
||||
$this->assertTrue($cache->contains('testing_result_cache_id'));
|
||||
@ -77,4 +84,51 @@ class ResultCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->_em->getConfiguration()->setResultCacheImpl(null);
|
||||
}
|
||||
|
||||
public function testNativeQueryResultCaching()
|
||||
{
|
||||
$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
|
||||
$rsm->addScalarResult('id', 'u');
|
||||
$query = $this->_em->createNativeQuery('select u.id FROM cms_users u WHERE u.id = ?', $rsm);
|
||||
$query->setParameter(1, 10);
|
||||
|
||||
$cache = new ArrayCache();
|
||||
$query->setResultCacheDriver($cache)->useResultCache(true);
|
||||
|
||||
$this->assertEquals(0, count($cache->getIds()));
|
||||
$query->getResult();
|
||||
$this->assertEquals(1, count($cache->getIds()));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <type> $query
|
||||
* @depends testNativeQueryResultCaching
|
||||
*/
|
||||
public function testResultCacheDependsOnQueryHints($query)
|
||||
{
|
||||
$cache = $query->getResultCacheDriver();
|
||||
$cacheCount = count($cache->getIds());
|
||||
|
||||
$query->setHint('foo', 'bar');
|
||||
$query->getResult();
|
||||
|
||||
$this->assertEquals($cacheCount + 1, count($cache->getIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <type> $query
|
||||
* @depends testNativeQueryResultCaching
|
||||
*/
|
||||
public function testResultCacheDependsOnParameters($query)
|
||||
{
|
||||
$cache = $query->getResultCacheDriver();
|
||||
$cacheCount = count($cache->getIds());
|
||||
|
||||
$query->setParameter(1, 50);
|
||||
$query->getResult();
|
||||
|
||||
$this->assertEquals($cacheCount + 1, count($cache->getIds()));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user