New buildCacheEntry way bo build a entry for a cached collection
This commit is contained in:
parent
1b4eee6d0d
commit
e73bd9e9bb
@ -65,9 +65,8 @@ class DefaultCollectionHydrator implements CollectionHydrator
|
||||
$data = array();
|
||||
|
||||
foreach ($collection as $index => $entity) {
|
||||
$data[$index] = $this->uow->getEntityIdentifier($entity);
|
||||
$data[$index] = new EntityCacheKey($metadata->name, $this->uow->getEntityIdentifier($entity));
|
||||
}
|
||||
|
||||
return new CollectionCacheEntry($data);
|
||||
}
|
||||
|
||||
@ -81,36 +80,25 @@ class DefaultCollectionHydrator implements CollectionHydrator
|
||||
$targetRegion = $targetPersister->getCacheRegion();
|
||||
$list = array();
|
||||
|
||||
$keys = array();
|
||||
foreach ($entry->identifiers as $index => $identifier) {
|
||||
$keys[$index] = new EntityCacheKey($assoc['targetEntity'], $identifier);
|
||||
}
|
||||
|
||||
|
||||
if ($targetRegion instanceof MultiGetRegion) {
|
||||
$entityEntries = $targetRegion->getMulti($keys);
|
||||
$entityEntries = $targetRegion->getMulti($entry);
|
||||
|
||||
if ($entityEntries === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($entityEntries as $index => $entityEntry) {
|
||||
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->data, self::$hints);
|
||||
}
|
||||
|
||||
} else {
|
||||
$entityEntries = array();
|
||||
foreach ($entry->identifiers as $index => $identifier) {
|
||||
|
||||
$entityEntry = $targetRegion->get(new EntityCacheKey($assoc['targetEntity'], $identifier));
|
||||
|
||||
if ($entityEntry === null) {
|
||||
if (null === ($entityEntries[$index] = $targetRegion->get($identifier))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->resolveAssociationEntries($this->em), self::$hints);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($entityEntries as $index => $entityEntry) {
|
||||
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->data, self::$hints);
|
||||
}
|
||||
|
||||
array_walk($list, function($entity, $index) use ($collection) {
|
||||
$collection->hydrateSet($index, $entity);
|
||||
});
|
||||
|
@ -1,110 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Cache;
|
||||
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
* Collection hydrator that expects a target region to be instance of {Doctrine\ORM\Cache\MultiGetRegion},
|
||||
* to enable loading the entire collection with one cache request.
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Asmir Mustafic <goetas@gmail.com>
|
||||
*/
|
||||
class MultiGetCollectionHydrator implements CollectionHydrator
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\UnitOfWork
|
||||
*/
|
||||
private $uow;
|
||||
|
||||
/**
|
||||
* @var MultiGetRegion
|
||||
*/
|
||||
private $targetRegion;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $hints = array(Query::HINT_CACHE_ENABLED => true);
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\EntityManagerInterface $em The entity manager.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em, MultiGetRegion $targetRegion)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->uow = $em->getUnitOfWork();
|
||||
$this->targetRegion = $targetRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildCacheEntry(ClassMetadata $metadata, CollectionCacheKey $key, $collection)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
foreach ($collection as $index => $entity) {
|
||||
$data[$index] = $this->uow->getEntityIdentifier($entity);
|
||||
}
|
||||
|
||||
return new CollectionCacheEntry($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadCacheEntry(ClassMetadata $metadata, CollectionCacheKey $key, CollectionCacheEntry $entry, PersistentCollection $collection)
|
||||
{
|
||||
$assoc = $metadata->associationMappings[$key->association];
|
||||
$list = array();
|
||||
|
||||
$keys = array();
|
||||
foreach ($entry->identifiers as $index => $identifier) {
|
||||
$keys[$index] = new EntityCacheKey($assoc['targetEntity'], $identifier);
|
||||
}
|
||||
|
||||
$entityEntries = $this->targetRegion->getMulti($keys);
|
||||
|
||||
if ($entityEntries === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($entityEntries as $index => $entityEntry) {
|
||||
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->data, self::$hints);
|
||||
}
|
||||
|
||||
array_walk($list, function ($entity, $index) use ($collection) {
|
||||
$collection->hydrateSet($index, $entity);
|
||||
});
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -20,8 +20,6 @@
|
||||
|
||||
namespace Doctrine\ORM\Cache;
|
||||
|
||||
use Doctrine\ORM\Cache\CacheKey;
|
||||
|
||||
/**
|
||||
* Defines a region that supports multi-get reading.
|
||||
*
|
||||
@ -36,8 +34,8 @@ interface MultiGetRegion
|
||||
* Get all items from the cache indentifed by $keys.
|
||||
* It returns NULL if some elements can not be found.
|
||||
*
|
||||
* @param CacheKey[] $key The keys of the items to be retrieved.
|
||||
* @param CollectionCacheEntry[] $collection The collection of the items to be retrieved.
|
||||
* @return array The cached entries or NULL if one or more entries can not be found
|
||||
*/
|
||||
public function getMulti(array $keys);
|
||||
public function getMulti(CollectionCacheEntry $collection);
|
||||
}
|
||||
|
@ -167,8 +167,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
$targetHydrator = $targetPersister->getEntityHydrator();
|
||||
$entry = $this->hydrator->buildCacheEntry($this->targetEntity, $key, $elements);
|
||||
|
||||
foreach ($entry->identifiers as $index => $identifier) {
|
||||
$entityKey = new EntityCacheKey($this->targetEntity->rootEntityName, $identifier);
|
||||
foreach ($entry->identifiers as $index => $entityKey) {
|
||||
|
||||
if ($targetRegion->contains($entityKey)) {
|
||||
continue;
|
||||
|
@ -26,7 +26,7 @@ use Doctrine\ORM\Cache\CacheKey;
|
||||
use Doctrine\ORM\Cache\CacheEntry;
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Doctrine\ORM\Cache\MultiGetRegion;
|
||||
use Doctrine\Common\Cache\CacheMultiGet;
|
||||
use Doctrine\ORM\Cache\CollectionCacheEntry;
|
||||
|
||||
/**
|
||||
* A cache region that enables the retrieval of multiple elements with one call
|
||||
@ -39,10 +39,10 @@ class DefaultMultiGetRegion extends DefaultRegion implements MultiGetRegion
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMulti(array $keys)
|
||||
public function getMulti(CollectionCacheEntry $collection)
|
||||
{
|
||||
$keysToRetrieve = array();
|
||||
foreach ($keys as $index => $key) {
|
||||
foreach ($collection->identifiers as $index => $key) {
|
||||
$keysToRetrieve[$index] = $this->name . '_' . $key->hash;
|
||||
}
|
||||
|
||||
@ -55,7 +55,6 @@ class DefaultMultiGetRegion extends DefaultRegion implements MultiGetRegion
|
||||
foreach ($keysToRetrieve as $index => $key) {
|
||||
$returnableItems[$index] = $items[$key];
|
||||
}
|
||||
|
||||
return $returnableItems;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Tests\Mocks\CacheEntryMock;
|
||||
use Doctrine\Tests\Mocks\CacheKeyMock;
|
||||
use Doctrine\ORM\Cache\Region\DefaultMultiGetRegion;
|
||||
use Doctrine\ORM\Cache\CollectionCacheEntry;
|
||||
use Doctrine\ORM\Cache\EntityCacheKey;
|
||||
|
||||
/**
|
||||
* @author Asmir Mustafic <goetas@gmail.com>
|
||||
@ -21,7 +23,7 @@ class MultiGetRegionTest extends AbstractRegionTest
|
||||
{
|
||||
$key1 = new CacheKeyMock('key.1');
|
||||
$value1 = new CacheEntryMock(array('id'=>1, 'name' => 'bar'));
|
||||
|
||||
|
||||
$key2 = new CacheKeyMock('key.2');
|
||||
$value2 = new CacheEntryMock(array('id'=>2, 'name' => 'bar'));
|
||||
|
||||
@ -31,7 +33,7 @@ class MultiGetRegionTest extends AbstractRegionTest
|
||||
$this->region->put($key1, $value1);
|
||||
$this->region->put($key2, $value2);
|
||||
|
||||
$actual = $this->region->getMulti(array($key1, $key2));
|
||||
$actual = $this->region->getMulti(new CollectionCacheEntry(array($key1, $key2)));
|
||||
|
||||
$this->assertEquals($value1, $actual[0]);
|
||||
$this->assertEquals($value2, $actual[1]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user