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();
|
$data = array();
|
||||||
|
|
||||||
foreach ($collection as $index => $entity) {
|
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);
|
return new CollectionCacheEntry($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,36 +80,25 @@ class DefaultCollectionHydrator implements CollectionHydrator
|
|||||||
$targetRegion = $targetPersister->getCacheRegion();
|
$targetRegion = $targetPersister->getCacheRegion();
|
||||||
$list = array();
|
$list = array();
|
||||||
|
|
||||||
$keys = array();
|
|
||||||
foreach ($entry->identifiers as $index => $identifier) {
|
|
||||||
$keys[$index] = new EntityCacheKey($assoc['targetEntity'], $identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ($targetRegion instanceof MultiGetRegion) {
|
if ($targetRegion instanceof MultiGetRegion) {
|
||||||
$entityEntries = $targetRegion->getMulti($keys);
|
$entityEntries = $targetRegion->getMulti($entry);
|
||||||
|
|
||||||
if ($entityEntries === null) {
|
if ($entityEntries === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($entityEntries as $index => $entityEntry) {
|
|
||||||
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->data, self::$hints);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
$entityEntries = array();
|
||||||
foreach ($entry->identifiers as $index => $identifier) {
|
foreach ($entry->identifiers as $index => $identifier) {
|
||||||
|
if (null === ($entityEntries[$index] = $targetRegion->get($identifier))) {
|
||||||
$entityEntry = $targetRegion->get(new EntityCacheKey($assoc['targetEntity'], $identifier));
|
|
||||||
|
|
||||||
if ($entityEntry === null) {
|
|
||||||
return null;
|
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) {
|
array_walk($list, function($entity, $index) use ($collection) {
|
||||||
$collection->hydrateSet($index, $entity);
|
$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;
|
namespace Doctrine\ORM\Cache;
|
||||||
|
|
||||||
use Doctrine\ORM\Cache\CacheKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a region that supports multi-get reading.
|
* Defines a region that supports multi-get reading.
|
||||||
*
|
*
|
||||||
@ -36,8 +34,8 @@ interface MultiGetRegion
|
|||||||
* Get all items from the cache indentifed by $keys.
|
* Get all items from the cache indentifed by $keys.
|
||||||
* It returns NULL if some elements can not be found.
|
* 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
|
* @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();
|
$targetHydrator = $targetPersister->getEntityHydrator();
|
||||||
$entry = $this->hydrator->buildCacheEntry($this->targetEntity, $key, $elements);
|
$entry = $this->hydrator->buildCacheEntry($this->targetEntity, $key, $elements);
|
||||||
|
|
||||||
foreach ($entry->identifiers as $index => $identifier) {
|
foreach ($entry->identifiers as $index => $entityKey) {
|
||||||
$entityKey = new EntityCacheKey($this->targetEntity->rootEntityName, $identifier);
|
|
||||||
|
|
||||||
if ($targetRegion->contains($entityKey)) {
|
if ($targetRegion->contains($entityKey)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -26,7 +26,7 @@ use Doctrine\ORM\Cache\CacheKey;
|
|||||||
use Doctrine\ORM\Cache\CacheEntry;
|
use Doctrine\ORM\Cache\CacheEntry;
|
||||||
use Doctrine\Common\Cache\CacheProvider;
|
use Doctrine\Common\Cache\CacheProvider;
|
||||||
use Doctrine\ORM\Cache\MultiGetRegion;
|
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
|
* A cache region that enables the retrieval of multiple elements with one call
|
||||||
@ -39,10 +39,10 @@ class DefaultMultiGetRegion extends DefaultRegion implements MultiGetRegion
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getMulti(array $keys)
|
public function getMulti(CollectionCacheEntry $collection)
|
||||||
{
|
{
|
||||||
$keysToRetrieve = array();
|
$keysToRetrieve = array();
|
||||||
foreach ($keys as $index => $key) {
|
foreach ($collection->identifiers as $index => $key) {
|
||||||
$keysToRetrieve[$index] = $this->name . '_' . $key->hash;
|
$keysToRetrieve[$index] = $this->name . '_' . $key->hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,6 @@ class DefaultMultiGetRegion extends DefaultRegion implements MultiGetRegion
|
|||||||
foreach ($keysToRetrieve as $index => $key) {
|
foreach ($keysToRetrieve as $index => $key) {
|
||||||
$returnableItems[$index] = $items[$key];
|
$returnableItems[$index] = $items[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $returnableItems;
|
return $returnableItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ use Doctrine\Common\Cache\ArrayCache;
|
|||||||
use Doctrine\Tests\Mocks\CacheEntryMock;
|
use Doctrine\Tests\Mocks\CacheEntryMock;
|
||||||
use Doctrine\Tests\Mocks\CacheKeyMock;
|
use Doctrine\Tests\Mocks\CacheKeyMock;
|
||||||
use Doctrine\ORM\Cache\Region\DefaultMultiGetRegion;
|
use Doctrine\ORM\Cache\Region\DefaultMultiGetRegion;
|
||||||
|
use Doctrine\ORM\Cache\CollectionCacheEntry;
|
||||||
|
use Doctrine\ORM\Cache\EntityCacheKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Asmir Mustafic <goetas@gmail.com>
|
* @author Asmir Mustafic <goetas@gmail.com>
|
||||||
@ -31,7 +33,7 @@ class MultiGetRegionTest extends AbstractRegionTest
|
|||||||
$this->region->put($key1, $value1);
|
$this->region->put($key1, $value1);
|
||||||
$this->region->put($key2, $value2);
|
$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($value1, $actual[0]);
|
||||||
$this->assertEquals($value2, $actual[1]);
|
$this->assertEquals($value2, $actual[1]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user