2013-02-13 20:42:13 -02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Doctrine\Tests\ORM\Cache;
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
use Doctrine\Common\Collections\Collection;
|
|
|
|
use Doctrine\ORM\Cache\EntityCacheKey;
|
|
|
|
use Doctrine\ORM\Cache\QueryCache;
|
2016-05-11 01:55:12 +07:00
|
|
|
use Doctrine\Tests\Mocks\TimestampRegionMock;
|
2013-02-13 20:42:13 -02:00
|
|
|
use Doctrine\Tests\OrmTestCase;
|
|
|
|
use Doctrine\Tests\Mocks\CacheRegionMock;
|
|
|
|
use Doctrine\ORM\Cache\DefaultQueryCache;
|
|
|
|
use Doctrine\ORM\Cache\QueryCacheKey;
|
|
|
|
use Doctrine\ORM\Cache\QueryCacheEntry;
|
|
|
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
|
|
|
use Doctrine\Tests\Models\Cache\Country;
|
|
|
|
use Doctrine\Tests\Models\Cache\City;
|
|
|
|
use Doctrine\Tests\Models\Cache\State;
|
2016-06-16 10:05:56 -04:00
|
|
|
use Doctrine\Tests\Models\Cache\Restaurant;
|
2013-02-13 20:42:13 -02:00
|
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
|
|
use Doctrine\Tests\Models\Generic\BooleanModel;
|
|
|
|
use Doctrine\ORM\Cache\EntityCacheEntry;
|
|
|
|
use Doctrine\ORM\Cache;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @group DDC-2183
|
|
|
|
*/
|
|
|
|
class DefaultQueryCacheTest extends OrmTestCase
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var \Doctrine\ORM\Cache\DefaultQueryCache
|
|
|
|
*/
|
|
|
|
private $queryCache;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var \Doctrine\ORM\EntityManager
|
|
|
|
*/
|
|
|
|
private $em;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var \Doctrine\Tests\Mocks\CacheRegionMock
|
|
|
|
*/
|
|
|
|
private $region;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var \Doctrine\Tests\ORM\Cache\CacheFactoryDefaultQueryCacheTest
|
|
|
|
*/
|
|
|
|
private $cacheFactory;
|
|
|
|
|
|
|
|
protected function setUp()
|
|
|
|
{
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
$this->enableSecondLevelCache();
|
|
|
|
|
|
|
|
$this->em = $this->_getTestEntityManager();
|
|
|
|
$this->region = new CacheRegionMock();
|
|
|
|
$this->queryCache = new DefaultQueryCache($this->em, $this->region);
|
|
|
|
$this->cacheFactory = new CacheFactoryDefaultQueryCacheTest($this->queryCache, $this->region);
|
|
|
|
|
2013-10-03 13:55:55 -04:00
|
|
|
$this->em->getConfiguration()
|
|
|
|
->getSecondLevelCacheConfiguration()
|
|
|
|
->setCacheFactory($this->cacheFactory);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testImplementQueryCache()
|
|
|
|
{
|
2016-12-08 18:01:04 +01:00
|
|
|
$this->assertInstanceOf(QueryCache::class, $this->queryCache);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetRegion()
|
|
|
|
{
|
|
|
|
$this->assertSame($this->region, $this->queryCache->getRegion());
|
|
|
|
}
|
2016-06-16 10:05:56 -04:00
|
|
|
|
2013-02-13 20:42:13 -02:00
|
|
|
public function testClearShouldEvictRegion()
|
|
|
|
{
|
|
|
|
$this->queryCache->clear();
|
|
|
|
|
|
|
|
$this->assertArrayHasKey('evictAll', $this->region->calls);
|
|
|
|
$this->assertCount(1, $this->region->calls['evictAll']);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testPutBasicQueryResult()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$metadata = $this->em->getClassMetadata(Country::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$name = "Country $i";
|
|
|
|
$entity = new Country($name);
|
|
|
|
$result[] = $entity;
|
|
|
|
|
|
|
|
$metadata->setFieldValue($entity, 'id', $i);
|
2016-12-07 23:33:41 +01:00
|
|
|
$this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertTrue($this->queryCache->put($key, $rsm, $result));
|
|
|
|
$this->assertArrayHasKey('put', $this->region->calls);
|
|
|
|
$this->assertCount(5, $this->region->calls['put']);
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
|
|
|
|
$this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][4]['key']);
|
|
|
|
|
|
|
|
$this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][0]['entry']);
|
|
|
|
$this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][1]['entry']);
|
|
|
|
$this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][2]['entry']);
|
|
|
|
$this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][3]['entry']);
|
|
|
|
$this->assertInstanceOf(QueryCacheEntry::class, $this->region->calls['put'][4]['entry']);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testPutToOneAssociationQueryResult()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$uow = $this->em->getUnitOfWork();
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$cityClass = $this->em->getClassMetadata(City::class);
|
|
|
|
$stateClass = $this->em->getClassMetadata(State::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(City::class, 'c');
|
|
|
|
$rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
|
2016-12-07 23:33:41 +01:00
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$state = new State("State $i");
|
|
|
|
$city = new City("City $i", $state);
|
|
|
|
$result[] = $city;
|
|
|
|
|
|
|
|
$cityClass->setFieldValue($city, 'id', $i);
|
|
|
|
$stateClass->setFieldValue($state, 'id', $i*2);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$uow->registerManaged($state, ['id' => $state->getId()], ['name' => $city->getName()]);
|
|
|
|
$uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => $state]);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertTrue($this->queryCache->put($key, $rsm, $result));
|
|
|
|
$this->assertArrayHasKey('put', $this->region->calls);
|
|
|
|
$this->assertCount(9, $this->region->calls['put']);
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][4]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][5]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][6]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][7]['key']);
|
|
|
|
$this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][8]['key']);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
2015-07-06 14:18:38 +02:00
|
|
|
public function testPutToOneAssociation2LevelsQueryResult()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2015-07-06 14:18:38 +02:00
|
|
|
$uow = $this->em->getUnitOfWork();
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$cityClass = $this->em->getClassMetadata(City::class);
|
|
|
|
$stateClass = $this->em->getClassMetadata(State::class);
|
|
|
|
$countryClass = $this->em->getClassMetadata(Country::class);
|
2015-07-06 14:18:38 +02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(City::class, 'c');
|
|
|
|
$rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
|
2016-12-07 23:33:41 +01:00
|
|
|
);
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addJoinedEntityFromClassMetadata(Country::class, 'co', 's', 'country', ['id'=>'country_id', 'name'=>'country_name']
|
2016-12-07 23:33:41 +01:00
|
|
|
);
|
2015-07-06 14:18:38 +02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$country = new Country("Country $i");
|
|
|
|
$state = new State("State $i", $country);
|
|
|
|
$city = new City("City $i", $state);
|
|
|
|
|
|
|
|
$result[] = $city;
|
|
|
|
|
|
|
|
$cityClass->setFieldValue($city, 'id', $i);
|
|
|
|
$stateClass->setFieldValue($state, 'id', $i*2);
|
|
|
|
$countryClass->setFieldValue($country, 'id', $i*3);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$uow->registerManaged($country, ['id' => $country->getId()], ['name' => $country->getName()]);
|
|
|
|
$uow->registerManaged($state, ['id' => $state->getId()], ['name' => $state->getName(), 'country' => $country]
|
|
|
|
);
|
|
|
|
$uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => $state]);
|
2015-07-06 14:18:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertTrue($this->queryCache->put($key, $rsm, $result));
|
|
|
|
$this->assertArrayHasKey('put', $this->region->calls);
|
2016-06-16 10:05:56 -04:00
|
|
|
$this->assertCount(13, $this->region->calls['put']);
|
2015-07-06 14:18:38 +02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][4]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][5]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][6]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][7]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][8]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][9]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][10]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][11]['key']);
|
|
|
|
$this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][12]['key']);
|
2015-07-06 14:18:38 +02:00
|
|
|
}
|
|
|
|
|
2013-02-13 20:42:13 -02:00
|
|
|
public function testPutToOneAssociationNullQueryResult()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$uow = $this->em->getUnitOfWork();
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$cityClass = $this->em->getClassMetadata(City::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(City::class, 'c');
|
|
|
|
$rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
|
2016-12-07 23:33:41 +01:00
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$city = new City("City $i", null);
|
|
|
|
$result[] = $city;
|
|
|
|
|
|
|
|
$cityClass->setFieldValue($city, 'id', $i);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => null]);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertTrue($this->queryCache->put($key, $rsm, $result));
|
|
|
|
$this->assertArrayHasKey('put', $this->region->calls);
|
|
|
|
$this->assertCount(5, $this->region->calls['put']);
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
|
|
|
|
$this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
|
|
|
|
$this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][4]['key']);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testPutToManyAssociationQueryResult()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$uow = $this->em->getUnitOfWork();
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$cityClass = $this->em->getClassMetadata(City::class);
|
|
|
|
$stateClass = $this->em->getClassMetadata(State::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(State::class, 's');
|
|
|
|
$rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', ['id'=>'c_id', 'name'=>'c_name']);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$state = new State("State $i");
|
|
|
|
$city1 = new City("City 1", $state);
|
|
|
|
$city2 = new City("City 2", $state);
|
|
|
|
$result[] = $state;
|
|
|
|
|
|
|
|
$cityClass->setFieldValue($city1, 'id', $i + 11);
|
|
|
|
$cityClass->setFieldValue($city2, 'id', $i + 22);
|
|
|
|
$stateClass->setFieldValue($state, 'id', $i);
|
|
|
|
|
|
|
|
$state->addCity($city1);
|
|
|
|
$state->addCity($city2);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$uow->registerManaged($city1, ['id' => $city1->getId()], ['name' => $city1->getName(), 'state' => $state]
|
|
|
|
);
|
|
|
|
$uow->registerManaged($city2, ['id' => $city2->getId()], ['name' => $city2->getName(), 'state' => $state]
|
|
|
|
);
|
|
|
|
$uow->registerManaged($state, ['id' => $state->getId()], ['name' => $state->getName(), 'cities' => $state->getCities()]
|
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertTrue($this->queryCache->put($key, $rsm, $result));
|
|
|
|
$this->assertArrayHasKey('put', $this->region->calls);
|
|
|
|
$this->assertCount(13, $this->region->calls['put']);
|
|
|
|
}
|
|
|
|
|
2013-12-16 15:55:54 -05:00
|
|
|
public function testGetBasicQueryResult()
|
2013-02-13 20:42:13 -02:00
|
|
|
{
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
2016-12-07 23:33:41 +01:00
|
|
|
$entry = new QueryCacheEntry(
|
|
|
|
[
|
|
|
|
['identifier' => ['id' => 1]],
|
|
|
|
['identifier' => ['id' => 2]]
|
|
|
|
]
|
2013-02-13 20:42:13 -02:00
|
|
|
);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$data = [
|
|
|
|
['id'=>1, 'name' => 'Foo'],
|
|
|
|
['id'=>2, 'name' => 'Bar']
|
|
|
|
];
|
|
|
|
|
2013-02-13 20:42:13 -02:00
|
|
|
$this->region->addReturn('get', $entry);
|
2016-05-20 13:42:13 +03:00
|
|
|
|
|
|
|
$this->region->addReturn(
|
|
|
|
'getMultiple',
|
|
|
|
[
|
|
|
|
new EntityCacheEntry(Country::class, $data[0]),
|
|
|
|
new EntityCacheEntry(Country::class, $data[1])
|
|
|
|
]
|
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2013-10-07 18:53:32 -04:00
|
|
|
$result = $this->queryCache->get($key, $rsm);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$this->assertCount(2, $result);
|
2016-12-08 18:01:04 +01:00
|
|
|
$this->assertInstanceOf(Country::class, $result[0]);
|
|
|
|
$this->assertInstanceOf(Country::class, $result[1]);
|
2013-02-13 20:42:13 -02:00
|
|
|
$this->assertEquals(1, $result[0]->getId());
|
|
|
|
$this->assertEquals(2, $result[1]->getId());
|
|
|
|
$this->assertEquals('Foo', $result[0]->getName());
|
|
|
|
$this->assertEquals('Bar', $result[1]->getName());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCancelPutResultIfEntityPutFails()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$metadata = $this->em->getClassMetadata(Country::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$name = "Country $i";
|
|
|
|
$entity = new Country($name);
|
|
|
|
$result[] = $entity;
|
|
|
|
|
|
|
|
$metadata->setFieldValue($entity, 'id', $i);
|
2016-12-07 23:33:41 +01:00
|
|
|
$this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->region->addReturn('put', false);
|
|
|
|
|
|
|
|
$this->assertFalse($this->queryCache->put($key, $rsm, $result));
|
|
|
|
$this->assertArrayHasKey('put', $this->region->calls);
|
|
|
|
$this->assertCount(1, $this->region->calls['put']);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCancelPutResultIfAssociationEntityPutFails()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$uow = $this->em->getUnitOfWork();
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$cityClass = $this->em->getClassMetadata(City::class);
|
|
|
|
$stateClass = $this->em->getClassMetadata(State::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(City::class, 'c');
|
|
|
|
$rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
|
2016-12-07 23:33:41 +01:00
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$state = new State("State 1");
|
|
|
|
$city = new City("City 2", $state);
|
|
|
|
$result[] = $city;
|
|
|
|
|
|
|
|
$cityClass->setFieldValue($city, 'id', 1);
|
|
|
|
$stateClass->setFieldValue($state, 'id', 11);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$uow->registerManaged($state, ['id' => $state->getId()], ['name' => $city->getName()]);
|
|
|
|
$uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => $state]);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$this->region->addReturn('put', true); // put root entity
|
|
|
|
$this->region->addReturn('put', false); // association fails
|
|
|
|
|
|
|
|
$this->assertFalse($this->queryCache->put($key, $rsm, $result));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCancelPutToManyAssociationQueryResult()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$uow = $this->em->getUnitOfWork();
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$cityClass = $this->em->getClassMetadata(City::class);
|
|
|
|
$stateClass = $this->em->getClassMetadata(State::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(State::class, 's');
|
|
|
|
$rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', ['id'=>'c_id', 'name'=>'c_name']);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$state = new State("State");
|
|
|
|
$city1 = new City("City 1", $state);
|
|
|
|
$city2 = new City("City 2", $state);
|
|
|
|
$result[] = $state;
|
|
|
|
|
|
|
|
$stateClass->setFieldValue($state, 'id', 1);
|
|
|
|
$cityClass->setFieldValue($city1, 'id', 11);
|
|
|
|
$cityClass->setFieldValue($city2, 'id', 22);
|
|
|
|
|
|
|
|
$state->addCity($city1);
|
|
|
|
$state->addCity($city2);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$uow->registerManaged($city1, ['id' => $city1->getId()], ['name' => $city1->getName(), 'state' => $state]);
|
|
|
|
$uow->registerManaged($city2, ['id' => $city2->getId()], ['name' => $city2->getName(), 'state' => $state]);
|
|
|
|
$uow->registerManaged($state, ['id' => $state->getId()], ['name' => $state->getName(), 'cities' => $state->getCities()]
|
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$this->region->addReturn('put', true); // put root entity
|
|
|
|
$this->region->addReturn('put', false); // collection association fails
|
|
|
|
|
|
|
|
$this->assertFalse($this->queryCache->put($key, $rsm, $result));
|
|
|
|
$this->assertArrayHasKey('put', $this->region->calls);
|
|
|
|
$this->assertCount(2, $this->region->calls['put']);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testIgnoreCacheNonGetMode()
|
|
|
|
{
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
$key = new QueryCacheKey('query.key1', 0, Cache::MODE_PUT);
|
2016-12-07 23:33:41 +01:00
|
|
|
$entry = new QueryCacheEntry(
|
|
|
|
[
|
|
|
|
['identifier' => ['id' => 1]],
|
|
|
|
['identifier' => ['id' => 2]]
|
|
|
|
]
|
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$this->region->addReturn('get', $entry);
|
|
|
|
|
2013-10-07 18:53:32 -04:00
|
|
|
$this->assertNull($this->queryCache->get($key, $rsm));
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testIgnoreCacheNonPutMode()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$metadata = $this->em->getClassMetadata(Country::class);
|
2013-02-13 20:42:13 -02:00
|
|
|
$key = new QueryCacheKey('query.key1', 0, Cache::MODE_GET);
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$name = "Country $i";
|
|
|
|
$entity = new Country($name);
|
|
|
|
$result[] = $entity;
|
|
|
|
|
|
|
|
$metadata->setFieldValue($entity, 'id', $i);
|
2016-12-07 23:33:41 +01:00
|
|
|
$this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertFalse($this->queryCache->put($key, $rsm, $result));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetShouldIgnoreOldQueryCacheEntryResult()
|
|
|
|
{
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
$key = new QueryCacheKey('query.key1', 50);
|
2016-12-07 23:33:41 +01:00
|
|
|
$entry = new QueryCacheEntry(
|
|
|
|
[
|
|
|
|
['identifier' => ['id' => 1]],
|
|
|
|
['identifier' => ['id' => 2]]
|
|
|
|
]
|
2013-02-13 20:42:13 -02:00
|
|
|
);
|
2016-12-07 23:33:41 +01:00
|
|
|
$entities = [
|
|
|
|
['id'=>1, 'name' => 'Foo'],
|
|
|
|
['id'=>2, 'name' => 'Bar']
|
|
|
|
];
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-09-02 09:53:41 +00:00
|
|
|
$entry->time = microtime(true) - 100;
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$this->region->addReturn('get', $entry);
|
2016-05-20 13:42:13 +03:00
|
|
|
|
|
|
|
$this->region->addReturn(
|
|
|
|
'getMultiple',
|
|
|
|
[
|
|
|
|
new EntityCacheEntry(Country::class, $entities[0]),
|
|
|
|
new EntityCacheEntry(Country::class, $entities[1])
|
|
|
|
]
|
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2013-10-07 18:53:32 -04:00
|
|
|
$this->assertNull($this->queryCache->get($key, $rsm));
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetShouldIgnoreNonQueryCacheEntryResult()
|
|
|
|
{
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
2016-12-07 23:33:41 +01:00
|
|
|
$entry = new \ArrayObject(
|
|
|
|
[
|
|
|
|
['identifier' => ['id' => 1]],
|
|
|
|
['identifier' => ['id' => 2]]
|
|
|
|
]
|
2013-02-13 20:42:13 -02:00
|
|
|
);
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$data = [
|
|
|
|
['id'=>1, 'name' => 'Foo'],
|
|
|
|
['id'=>2, 'name' => 'Bar']
|
|
|
|
];
|
|
|
|
|
2013-02-13 20:42:13 -02:00
|
|
|
$this->region->addReturn('get', $entry);
|
2016-05-20 13:42:13 +03:00
|
|
|
|
|
|
|
$this->region->addReturn(
|
|
|
|
'getMultiple',
|
|
|
|
[
|
|
|
|
new EntityCacheEntry(Country::class, $data[0]),
|
|
|
|
new EntityCacheEntry(Country::class, $data[1])
|
|
|
|
]
|
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2013-10-07 18:53:32 -04:00
|
|
|
$this->assertNull($this->queryCache->get($key, $rsm));
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetShouldIgnoreMissingEntityQueryCacheEntry()
|
|
|
|
{
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
2016-12-07 23:33:41 +01:00
|
|
|
$entry = new QueryCacheEntry(
|
|
|
|
[
|
|
|
|
['identifier' => ['id' => 1]],
|
|
|
|
['identifier' => ['id' => 2]]
|
|
|
|
]
|
|
|
|
);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$this->region->addReturn('get', $entry);
|
2016-05-20 13:42:13 +03:00
|
|
|
$this->region->addReturn('getMultiple', [null]);
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(Country::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
2013-10-07 18:53:32 -04:00
|
|
|
$this->assertNull($this->queryCache->get($key, $rsm));
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
2016-06-16 10:05:56 -04:00
|
|
|
public function testGetAssociationValue()
|
|
|
|
{
|
|
|
|
$reflection = new \ReflectionMethod($this->queryCache, 'getAssociationValue');
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
|
|
|
|
$reflection->setAccessible(true);
|
|
|
|
|
|
|
|
$germany = new Country("Germany");
|
|
|
|
$bavaria = new State("Bavaria", $germany);
|
|
|
|
$wurzburg = new City("Würzburg", $bavaria);
|
|
|
|
$munich = new City("Munich", $bavaria);
|
|
|
|
|
|
|
|
$bavaria->addCity($munich);
|
|
|
|
$bavaria->addCity($wurzburg);
|
|
|
|
|
|
|
|
$munich->addAttraction(new Restaurant('Reinstoff', $munich));
|
|
|
|
$munich->addAttraction(new Restaurant('Schneider Weisse', $munich));
|
|
|
|
$wurzburg->addAttraction(new Restaurant('Fischers Fritz', $wurzburg));
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(State::class, 's');
|
|
|
|
$rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', [
|
2016-06-16 10:05:56 -04:00
|
|
|
'id' => 'c_id',
|
|
|
|
'name' => 'c_name'
|
2016-12-07 23:33:41 +01:00
|
|
|
]
|
|
|
|
);
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addJoinedEntityFromClassMetadata(Restaurant::class, 'a', 'c', 'attractions', [
|
2016-06-16 10:05:56 -04:00
|
|
|
'id' => 'a_id',
|
|
|
|
'name' => 'a_name'
|
2016-12-07 23:33:41 +01:00
|
|
|
]
|
|
|
|
);
|
2016-06-16 10:05:56 -04:00
|
|
|
|
|
|
|
$cities = $reflection->invoke($this->queryCache, $rsm, 'c', $bavaria);
|
|
|
|
$attractions = $reflection->invoke($this->queryCache, $rsm, 'a', $bavaria);
|
|
|
|
|
|
|
|
$this->assertCount(2, $cities);
|
|
|
|
$this->assertCount(2, $attractions);
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$this->assertInstanceOf(Collection::class, $cities);
|
|
|
|
$this->assertInstanceOf(Collection::class, $attractions[0]);
|
|
|
|
$this->assertInstanceOf(Collection::class, $attractions[1]);
|
2016-06-16 10:05:56 -04:00
|
|
|
|
|
|
|
$this->assertCount(2, $attractions[0]);
|
|
|
|
$this->assertCount(1, $attractions[1]);
|
|
|
|
}
|
|
|
|
|
2013-02-13 20:42:13 -02:00
|
|
|
/**
|
|
|
|
* @expectedException Doctrine\ORM\Cache\CacheException
|
2013-10-07 18:53:32 -04:00
|
|
|
* @expectedExceptionMessage Second level cache does not support scalar results.
|
2013-02-13 20:42:13 -02:00
|
|
|
*/
|
|
|
|
public function testScalarResultException()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
|
2015-11-06 15:23:16 +00:00
|
|
|
$rsm->addScalarResult('id', 'u', 'integer');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
$this->queryCache->put($key, $rsm, $result);
|
|
|
|
}
|
|
|
|
|
2013-10-07 18:53:32 -04:00
|
|
|
/**
|
|
|
|
* @expectedException Doctrine\ORM\Cache\CacheException
|
|
|
|
* @expectedExceptionMessage Second level cache does not support multiple root entities.
|
|
|
|
*/
|
2013-12-16 15:55:54 -05:00
|
|
|
public function testSupportMultipleRootEntitiesException()
|
2013-10-07 18:53:32 -04:00
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-10-07 18:53:32 -04:00
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
|
|
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addEntityResult(City::class, 'e1');
|
|
|
|
$rsm->addEntityResult(State::class, 'e2');
|
2013-10-07 18:53:32 -04:00
|
|
|
|
|
|
|
$this->queryCache->put($key, $rsm, $result);
|
|
|
|
}
|
|
|
|
|
2013-02-13 20:42:13 -02:00
|
|
|
/**
|
|
|
|
* @expectedException Doctrine\ORM\Cache\CacheException
|
|
|
|
* @expectedExceptionMessage Entity "Doctrine\Tests\Models\Generic\BooleanModel" not configured as part of the second-level cache.
|
|
|
|
*/
|
|
|
|
public function testNotCacheableEntityException()
|
|
|
|
{
|
2016-12-07 23:33:41 +01:00
|
|
|
$result = [];
|
2013-02-13 20:42:13 -02:00
|
|
|
$key = new QueryCacheKey('query.key1', 0);
|
|
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
2016-12-08 18:01:04 +01:00
|
|
|
$rsm->addRootEntityFromClassMetadata(BooleanModel::class, 'c');
|
2013-02-13 20:42:13 -02:00
|
|
|
|
|
|
|
for ($i = 0; $i < 4; $i++) {
|
|
|
|
$entity = new BooleanModel();
|
|
|
|
$boolean = ($i % 2 === 0);
|
|
|
|
|
|
|
|
$entity->id = $i;
|
|
|
|
$entity->booleanField = $boolean;
|
|
|
|
$result[] = $entity;
|
|
|
|
|
2016-12-07 23:33:41 +01:00
|
|
|
$this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['booleanField' => $boolean]);
|
2013-02-13 20:42:13 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertFalse($this->queryCache->put($key, $rsm, $result));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-05-11 01:55:12 +07:00
|
|
|
class CacheFactoryDefaultQueryCacheTest extends Cache\DefaultCacheFactory
|
2013-02-13 20:42:13 -02:00
|
|
|
{
|
|
|
|
private $queryCache;
|
|
|
|
private $region;
|
|
|
|
|
|
|
|
public function __construct(DefaultQueryCache $queryCache, CacheRegionMock $region)
|
|
|
|
{
|
|
|
|
$this->queryCache = $queryCache;
|
|
|
|
$this->region = $region;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildQueryCache(EntityManagerInterface $em, $regionName = null)
|
|
|
|
{
|
|
|
|
return $this->queryCache;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRegion(array $cache)
|
|
|
|
{
|
|
|
|
return $this->region;
|
|
|
|
}
|
2013-10-03 23:02:42 -04:00
|
|
|
|
|
|
|
public function getTimestampRegion()
|
|
|
|
{
|
2016-05-11 01:55:12 +07:00
|
|
|
return new TimestampRegionMock();
|
2013-10-03 23:02:42 -04:00
|
|
|
}
|
2015-07-06 14:18:38 +02:00
|
|
|
}
|