1
0
mirror of synced 2024-12-05 03:06:05 +03:00

[SLC] Support criteria

This commit is contained in:
Fabio B. Silva 2014-02-28 23:22:56 -05:00
parent f5897d4b0b
commit f4c63f8238
5 changed files with 219 additions and 9 deletions

View File

@ -284,7 +284,9 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
*/
protected function getHash($query, $criteria, array $orderBy = null, $limit = null, $offset = null, $timestamp = null)
{
list($params) = $this->persister->expandParameters($criteria);
list($params) = ($criteria instanceof Criteria)
? $this->persister->expandCriteriaParameters($criteria)
: $this->persister->expandParameters($criteria);
return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset . $timestamp);
}
@ -297,6 +299,14 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
return $this->persister->expandParameters($criteria);
}
/**
* {@inheritdoc}
*/
public function expandCriteriaParameters(Criteria $criteria)
{
return $this->persister->expandCriteriaParameters($criteria);
}
/**
* {@inheritdoc}
*/
@ -480,7 +490,36 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
*/
public function loadCriteria(Criteria $criteria)
{
return $this->persister->loadCriteria($criteria);
$query = $this->persister->getSelectSQL($criteria);
$timestamp = $this->timestampRegion->get($this->timestampKey);
$hash = $this->getHash($query, $criteria, null, null, null, $timestamp ? $timestamp->time : null);
$rsm = $this->getResultSetMapping();
$querykey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL);
$queryCache = $this->cache->getQueryCache($this->regionName);
$cacheResult = $queryCache->get($querykey, $rsm);
if ($cacheResult !== null) {
if ($this->cacheLogger) {
$this->cacheLogger->queryCacheHit($this->regionName, $querykey);
}
return $cacheResult;
}
$result = $this->persister->loadCriteria($criteria);
$cached = $queryCache->put($querykey, $rsm, $result);
if ($this->cacheLogger) {
if ($result) {
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
}
if ($cached) {
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
}
}
return $result;
}
/**

View File

@ -829,14 +829,9 @@ class BasicEntityPersister implements EntityPersister
}
/**
* Expands Criteria Parameters by walking the expressions and grabbing all
* parameters and types from it.
*
* @param \Doctrine\Common\Collections\Criteria $criteria
*
* @return array(array(), array())
* {@inheritdoc}
*/
private function expandCriteriaParameters(Criteria $criteria)
public function expandCriteriaParameters(Criteria $criteria)
{
$expression = $criteria->getWhereExpression();

View File

@ -83,6 +83,15 @@ interface EntityPersister
*/
public function expandParameters($criteria);
/**
* Expands Criteria Parameters by walking the expressions and grabbing all parameters and types from it.
*
* @param \Doctrine\Common\Collections\Criteria $criteria
*
* @return array
*/
public function expandCriteriaParameters(Criteria $criteria);
/**
* Gets the SQL WHERE condition for matching a field with a given value.
*

View File

@ -56,6 +56,7 @@ abstract class AbstractEntityPersisterTest extends OrmTestCase
'getInsertSQL',
'getSelectSQL',
'expandParameters',
'expandCriteriaParameters',
'getSelectConditionStatementSQL',
'addInsert',
'executeInserts',
@ -181,6 +182,19 @@ abstract class AbstractEntityPersisterTest extends OrmTestCase
$this->assertEquals(array('name'=>'Foo'), $persister->expandParameters(array('name'=>'Foo')));
}
public function testInvokeExpandCriteriaParameters()
{
$persister = $this->createPersisterDefault();
$criteria = new Criteria();
$this->entityPersister->expects($this->once())
->method('expandCriteriaParameters')
->with($this->equalTo($criteria))
->will($this->returnValue(array('name'=>'Foo')));
$this->assertEquals(array('name'=>'Foo'), $persister->expandCriteriaParameters($criteria));
}
public function testInvokeSelectConditionStatementSQL()
{
$persister = $this->createPersisterDefault();
@ -320,10 +334,18 @@ abstract class AbstractEntityPersisterTest extends OrmTestCase
public function testInvokeLoadCriteria()
{
$rsm = new ResultSetMappingBuilder($this->em);
$persister = $this->createPersisterDefault();
$entity = new Country("Foo");
$criteria = new Criteria();
$this->em->getUnitOfWork()->registerManaged($entity, array('id'=>1), array('id'=>1, 'name'=>'Foo'));
$rsm->addEntityResult(Country::CLASSNAME, 'c');
$this->entityPersister->expects($this->once())
->method('getResultSetMapping')
->will($this->returnValue($rsm));
$this->entityPersister->expects($this->once())
->method('loadCriteria')
->with($this->equalTo($criteria))

View File

@ -0,0 +1,145 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\Cache\State;
use Doctrine\Tests\Models\Cache\Country;
use Doctrine\Common\Collections\Criteria;
/**
* @group DDC-2183
*/
class SecondLevelCacheCriteriaTest extends SecondLevelCacheAbstractTest
{
public function testMatchingPut()
{
$this->evictRegions();
$this->loadFixturesCountries();
$this->evictRegions();
$this->_em->clear();
$this->assertFalse($this->cache->containsEntity(Country::CLASSNAME, $this->countries[0]->getId()));
$repository = $this->_em->getRepository(Country::CLASSNAME);
$queryCount = $this->getCurrentQueryCount();
$name = $this->countries[0]->getName();
$result1 = $repository->matching(new Criteria(
Criteria::expr()->eq('name', $name)
));
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertEquals($this->countries[0]->getId(), $result1[0]->getId());
$this->assertEquals($this->countries[0]->getName(), $result1[0]->getName());
$this->assertTrue($this->cache->containsEntity(Country::CLASSNAME, $this->countries[0]->getId()));
$this->_em->clear();
$result2 = $repository->matching(new Criteria(
Criteria::expr()->eq('name', $name)
));
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertCount(1, $result2);
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\Country', $result2[0]);
$this->assertEquals($result1[0]->getId(), $result2[0]->getId());
$this->assertEquals($result1[0]->getName(), $result2[0]->getName());
}
public function testRepositoryMatching()
{
$this->evictRegions();
$this->loadFixturesCountries();
$this->_em->clear();
$this->assertTrue($this->cache->containsEntity(Country::CLASSNAME, $this->countries[0]->getId()));
$repository = $this->_em->getRepository(Country::CLASSNAME);
$queryCount = $this->getCurrentQueryCount();
$result1 = $repository->matching(new Criteria(
Criteria::expr()->eq('name', $this->countries[0]->getName())
));
$this->assertCount(1, $result1);
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertEquals($this->countries[0]->getId(), $result1[0]->getId());
$this->assertEquals($this->countries[0]->getName(), $result1[0]->getName());
$this->_em->clear();
$result2 = $repository->matching(new Criteria(
Criteria::expr()->eq('name', $this->countries[0]->getName())
));
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertCount(1, $result2);
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\Country', $result2[0]);
$this->assertEquals($this->countries[0]->getId(), $result2[0]->getId());
$this->assertEquals($this->countries[0]->getName(), $result2[0]->getName());
$result3 = $repository->matching(new Criteria(
Criteria::expr()->eq('name', $this->countries[1]->getName())
));
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
$this->assertCount(1, $result3);
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\Country', $result3[0]);
$this->assertEquals($this->countries[1]->getId(), $result3[0]->getId());
$this->assertEquals($this->countries[1]->getName(), $result3[0]->getName());
$result4 = $repository->matching(new Criteria(
Criteria::expr()->eq('name', $this->countries[1]->getName())
));
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
$this->assertCount(1, $result4);
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\Country', $result4[0]);
$this->assertEquals($this->countries[1]->getId(), $result4[0]->getId());
$this->assertEquals($this->countries[1]->getName(), $result4[0]->getName());
}
public function testCollectionMatching()
{
$this->loadFixturesCountries();
$this->loadFixturesStates();
$this->loadFixturesCities();
$this->_em->clear();
$this->secondLevelCacheLogger->clearStats();
$entity = $this->_em->find(State::CLASSNAME, $this->states[0]->getId());
$itemName = $this->states[0]->getCities()->get(0)->getName();
$queryCount = $this->getCurrentQueryCount();
$collection = $entity->getCities();
$matching = $collection->matching(new Criteria(
Criteria::expr()->eq('name', $itemName)
));
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $matching);
$this->assertCount(1, $matching);
$this->_em->clear();
$entity = $this->_em->find(State::CLASSNAME, $this->states[0]->getId());
$queryCount = $this->getCurrentQueryCount();
$collection = $entity->getCities();
$matching = $collection->matching(new Criteria(
Criteria::expr()->eq('name', $itemName)
));
$this->assertEquals($queryCount, $this->getCurrentQueryCount());
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $matching);
$this->assertCount(1, $matching);
}
}