1
0
mirror of synced 2025-01-18 22:41:43 +03:00

New buildCacheEntry way bo build a entry for a cached collection

This commit is contained in:
Asmir Mustafic 2015-01-17 18:35:28 +01:00 committed by Marco Pivetta
parent 1b4eee6d0d
commit e73bd9e9bb
6 changed files with 18 additions and 142 deletions

View File

@ -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);
});

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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]);