Fix CS and update docs
This commit is contained in:
parent
1438a59c00
commit
61bff7d5f6
@ -35,6 +35,7 @@ Index
|
||||
|
||||
- :ref:`@Column <annref_column>`
|
||||
- :ref:`@ColumnResult <annref_column_result>`
|
||||
- :ref:`@Cache <annref_cache>`
|
||||
- :ref:`@ChangeTrackingPolicy <annref_changetrackingpolicy>`
|
||||
- :ref:`@DiscriminatorColumn <annref_discriminatorcolumn>`
|
||||
- :ref:`@DiscriminatorMap <annref_discriminatormap>`
|
||||
@ -152,6 +153,17 @@ Required attributes:
|
||||
|
||||
- **name**: The name of a column in the SELECT clause of a SQL query
|
||||
|
||||
.. _annref_cache:
|
||||
|
||||
@Cache
|
||||
~~~~~~~~~~~~~~
|
||||
Add caching strategy to a root entity or a collection.
|
||||
|
||||
Optional attributes:
|
||||
|
||||
- **usage**: One of ``READ_ONLY``, ``READ_READ_WRITE`` or ``NONSTRICT_READ_WRITE``, By default this is ``READ_ONLY``.
|
||||
- **region**: An specific region name
|
||||
|
||||
.. _annref_changetrackingpolicy:
|
||||
|
||||
@ChangeTrackingPolicy
|
||||
|
@ -155,7 +155,7 @@ Defines contract for concurrently managed data region.
|
||||
*
|
||||
* @return \Doctrine\ORM\Cache\Lock A lock instance or NULL if the lock already exists.
|
||||
*/
|
||||
public function readLock(CacheKey $key);
|
||||
public function lock(CacheKey $key);
|
||||
|
||||
/**
|
||||
* Attempts to read unlock the mapping for the given key.
|
||||
@ -163,9 +163,31 @@ Defines contract for concurrently managed data region.
|
||||
* @param \Doctrine\ORM\Cache\CacheKey $key The key of the item to unlock.
|
||||
* @param \Doctrine\ORM\Cache\Lock $lock The lock previously obtained from readLock
|
||||
*/
|
||||
public function readUnlock(CacheKey $key, Lock $lock);
|
||||
public function unlock(CacheKey $key, Lock $lock);
|
||||
}
|
||||
|
||||
``Doctrine\ORM\Cache\TimestampRegion``
|
||||
|
||||
Tracks the timestamps of the most recent updates to particular entity.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
interface TimestampRegion extends Region
|
||||
{
|
||||
/**
|
||||
* Update an specific key into the cache region.
|
||||
*
|
||||
* @param \Doctrine\ORM\Cache\CacheKey $key The key of the item to lock.
|
||||
*
|
||||
* @throws \Doctrine\ORM\Cache\LockException Indicates a problem accessing the region.
|
||||
*/
|
||||
public function update(CacheKey $key);
|
||||
}
|
||||
|
||||
.. _reference-second-level-cache-mode:
|
||||
|
||||
Caching mode
|
||||
------------
|
||||
|
||||
@ -226,8 +248,8 @@ To enable the second-level-cache, you should provide a cache factory
|
||||
|
||||
<?php
|
||||
|
||||
/* var $config \Doctrine\ORM\Configuration */
|
||||
/* var $cache \Doctrine\Common\Cache */
|
||||
/* var $config \Doctrine\ORM\Cache\RegionsConfiguration */
|
||||
/* var $cache \Doctrine\Common\Cache\CacheProvider */
|
||||
|
||||
$factory = new \Doctrine\ORM\Cache\DefaultCacheFactory($config, $cache);
|
||||
|
||||
@ -235,7 +257,8 @@ To enable the second-level-cache, you should provide a cache factory
|
||||
$config->setSecondLevelCacheEnabled();
|
||||
|
||||
//Cache factory
|
||||
$config->setSecondLevelCacheFactory($factory);
|
||||
$config->getSecondLevelCacheConfiguration()
|
||||
->setCacheFactory($factory);
|
||||
|
||||
|
||||
Cache Factory
|
||||
@ -290,22 +313,22 @@ It allows you to provide a specific implementation of the following components :
|
||||
public function buildQueryCache(EntityManagerInterface $em, $regionName = null);
|
||||
|
||||
/**
|
||||
* Build an entity hidrator
|
||||
* Build an entity hydrator
|
||||
*
|
||||
* @param \Doctrine\ORM\EntityManagerInterface $em The Entity manager.
|
||||
* @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata.
|
||||
*
|
||||
* @return \Doctrine\ORM\Cache\EntityHydrator The built entity hidrator.
|
||||
* @return \Doctrine\ORM\Cache\EntityHydrator The built entity hydrator.
|
||||
*/
|
||||
public function buildEntityHydrator(EntityManagerInterface $em, ClassMetadata $metadata);
|
||||
|
||||
/**
|
||||
* Build a collection hidrator
|
||||
* Build a collection hydrator
|
||||
*
|
||||
* @param \Doctrine\ORM\EntityManagerInterface $em The Entity manager.
|
||||
* @param array $mapping The association mapping.
|
||||
*
|
||||
* @return \Doctrine\ORM\Cache\CollectionHydrator The built collection hidrator.
|
||||
* @return \Doctrine\ORM\Cache\CollectionHydrator The built collection hydrator.
|
||||
*/
|
||||
public function buildCollectionHydrator(EntityManagerInterface $em, array $mapping);
|
||||
|
||||
@ -317,6 +340,13 @@ It allows you to provide a specific implementation of the following components :
|
||||
* @return \Doctrine\ORM\Cache\Region The cache region.
|
||||
*/
|
||||
public function getRegion(array $cache);
|
||||
|
||||
/**
|
||||
* Build timestamp cache region
|
||||
*
|
||||
* @return \Doctrine\ORM\Cache\TimestampRegion The timestamp region.
|
||||
*/
|
||||
public function getTimestampRegion();
|
||||
}
|
||||
|
||||
Region Lifetime
|
||||
@ -328,11 +358,14 @@ To specify a default lifetime for all regions or specify a different lifetime fo
|
||||
|
||||
<?php
|
||||
|
||||
/* var $config \Doctrine\ORM\Configuration /*
|
||||
/* var $config \Doctrine\ORM\Configuration */
|
||||
/* var $cacheConfig \Doctrine\ORM\Configuration */
|
||||
$cacheConfig = $config->getSecondLevelCacheConfiguration();
|
||||
$regionConfig = $cacheConfig->getRegionsConfiguration();
|
||||
|
||||
//Cache Region lifetime
|
||||
$config->setSecondLevelCacheRegionLifetime('my_entity_region', 3600);
|
||||
$config->setSecondLevelCacheDefaultRegionLifetime(7200);
|
||||
$regionConfig->setLifetime('my_entity_region', 3600);
|
||||
$regionConfig->setDefaultLifetime(7200);
|
||||
|
||||
|
||||
Cache Log
|
||||
@ -344,12 +377,14 @@ By providing a cache logger you should be able to get information about all cach
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
/* var $config \Doctrine\ORM\Configuration /*
|
||||
|
||||
/* var $config \Doctrine\ORM\Configuration */
|
||||
$logger = \Doctrine\ORM\Cache\Logging\StatisticsCacheLogger();
|
||||
|
||||
//Cache logger
|
||||
$config->setSecondLevelCacheLogger($logger);
|
||||
$config->setSecondLevelCacheEnabled(true);
|
||||
$config->getSecondLevelCacheConfiguration()
|
||||
->setCacheLogger($logger);
|
||||
|
||||
|
||||
// Collect cache statistics
|
||||
@ -456,8 +491,8 @@ Entity cache definition
|
||||
-----------------------
|
||||
* Entity cache configuration allows you to define the caching strategy and region for an entity.
|
||||
|
||||
* ``usage`` Specifies the caching strategy: ``READ_ONLY``, ``NONSTRICT_READ_WRITE``, ``READ_WRITE``
|
||||
* ``region`` Specifies the name of the second level cache region.
|
||||
* ``usage`` Specifies the caching strategy: ``READ_ONLY``, ``NONSTRICT_READ_WRITE``, ``READ_WRITE``. see :ref:`reference-second-level-cache-mode`
|
||||
* ``region`` Optional value that specifies the name of the second level cache region.
|
||||
|
||||
|
||||
.. configuration-block::
|
||||
@ -729,6 +764,57 @@ The query cache stores the results of the query but as identifiers, entity value
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
|
||||
Cache mode
|
||||
~~~~~~~~~~
|
||||
|
||||
The Cache Mode controls how a particular query interacts with the second-level cache:
|
||||
|
||||
* ``Cache::MODE_GET`` - May read items from the cache, but will not add items.
|
||||
* ``Cache::MODE_PUT`` - Will never read items from the cache, but will add items to the cache as it reads them from the database.
|
||||
* ``Cache::MODE_NORMAL`` - May read items from the cache, and add items to the cache.
|
||||
* ``Cache::MODE_REFRESH`` - The query will never read items from the cache, but will refresh items to the cache as it reads them from the database.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
/** var $em \Doctrine\ORM\EntityManager */
|
||||
// Will refresh the query cache and all entities the cache as it reads from the database.
|
||||
$result1 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
|
||||
->setCacheMode(Cache::MODE_GET)
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
|
||||
.. note::
|
||||
|
||||
The the default query cache mode is ```Cache::MODE_NORMAL```
|
||||
|
||||
|
||||
Using the repository query cache
|
||||
---------------------
|
||||
|
||||
As well as ``Query Cache`` all persister queries store only identifier values for an individual query.
|
||||
All persister use a single timestamps cache region keeps track of the last update for each persister,
|
||||
When a query is loaded from cache, the timestamp region is checked for the last update for that persister.
|
||||
Using the last update timestamps as part of the query key invalidate the cache key when an update occurs.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
// load from database and store cache query key hashing the query + parameters + last timestamp cache region..
|
||||
$entities = $em->getRepository('Entity\Country')->findAll();
|
||||
|
||||
// load from query and entities from cache..
|
||||
$entities = $em->getRepository('Country')->findAll();
|
||||
|
||||
// update the timestamp cache region for Country
|
||||
$em->persist(new Country('zombieland'));
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
|
||||
// Reload the query from database.
|
||||
$entities = $em->getRepository('Country')->findAll();
|
||||
|
||||
Cache API
|
||||
---------
|
||||
@ -785,6 +871,14 @@ Composite primary key
|
||||
private $target;
|
||||
}
|
||||
|
||||
// Supported
|
||||
/** @var $article Article */
|
||||
$article = $this->_em->find("Article", 1);
|
||||
|
||||
// Supported
|
||||
/** @var $article Article */
|
||||
$article = $this->_em->find("Article", $article);
|
||||
|
||||
// Supported
|
||||
$id = array('source' => 1, 'target' => 2);
|
||||
$reference = $this->_em->find("Reference", $id);
|
||||
|
@ -22,7 +22,7 @@ namespace Doctrine\ORM;
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Query\Parameter;
|
||||
use Doctrine\ORM\Cache\QueryCacheKey;
|
||||
use Doctrine\DBAL\Cache\QueryCacheProfile;
|
||||
|
||||
@ -127,7 +127,7 @@ abstract class AbstractQuery
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $cacheable;
|
||||
protected $cacheable = false;
|
||||
|
||||
/**
|
||||
* Second level cache region name.
|
||||
@ -216,7 +216,7 @@ abstract class AbstractQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean TRUE if the query cache and second level cache are anabled, FALSE otherwise.
|
||||
* @return boolean TRUE if the query cache and second level cache are enabled, FALSE otherwise.
|
||||
*/
|
||||
protected function isCacheEnabled()
|
||||
{
|
||||
@ -340,7 +340,7 @@ abstract class AbstractQuery
|
||||
$parameterCollection = new ArrayCollection();
|
||||
|
||||
foreach ($parameters as $key => $value) {
|
||||
$parameter = new Query\Parameter($key, $value);
|
||||
$parameter = new Parameter($key, $value);
|
||||
|
||||
$parameterCollection->add($parameter);
|
||||
}
|
||||
@ -381,7 +381,7 @@ abstract class AbstractQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
$parameter = new Query\Parameter($key, $value, $type);
|
||||
$parameter = new Parameter($key, $value, $type);
|
||||
|
||||
$this->parameters->add($parameter);
|
||||
|
||||
@ -395,10 +395,14 @@ abstract class AbstractQuery
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws \Doctrine\ORM\ORMInvalidArgumentException
|
||||
*/
|
||||
public function processParameterValue($value)
|
||||
{
|
||||
if (is_scalar($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $key => $paramValue) {
|
||||
$paramValue = $this->processParameterValue($paramValue);
|
||||
@ -889,7 +893,7 @@ abstract class AbstractQuery
|
||||
$this->setParameters($parameters);
|
||||
}
|
||||
|
||||
$rsm = $this->_resultSetMapping ?: $this->getResultSetMapping();
|
||||
$rsm = $this->getResultSetMapping();
|
||||
$stmt = $this->_doExecute();
|
||||
|
||||
return $this->_em->newHydrator($this->_hydrationMode)->iterate($stmt, $rsm, $this->_hints);
|
||||
@ -962,7 +966,7 @@ abstract class AbstractQuery
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$rsm = $this->_resultSetMapping ?: $this->getResultSetMapping();
|
||||
$rsm = $this->getResultSetMapping();
|
||||
$data = $this->_em->newHydrator($this->_hydrationMode)->hydrateAll($stmt, $rsm, $this->_hints);
|
||||
|
||||
$setCacheEntry($data);
|
||||
@ -980,13 +984,12 @@ abstract class AbstractQuery
|
||||
*/
|
||||
private function executeUsingQueryCache($parameters = null, $hydrationMode = null)
|
||||
{
|
||||
$rsm = $this->_resultSetMapping ?: $this->getResultSetMapping();
|
||||
$rsm = $this->getResultSetMapping();
|
||||
$querykey = new QueryCacheKey($this->getHash(), $this->lifetime, $this->cacheMode ?: Cache::MODE_NORMAL);
|
||||
$queryCache = $this->_em->getCache()->getQueryCache($this->cacheRegion);
|
||||
$result = $queryCache->get($querykey, $rsm);
|
||||
$result = $queryCache->get($querykey, $rsm, $this->_hints);
|
||||
|
||||
if ($result !== null) {
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
$this->cacheLogger->queryCacheHit($queryCache->getRegion()->getName(), $querykey);
|
||||
}
|
||||
@ -995,14 +998,14 @@ abstract class AbstractQuery
|
||||
}
|
||||
|
||||
$result = $this->executeIgnoreQueryCache($parameters, $hydrationMode);
|
||||
$cached = $queryCache->put($querykey, $rsm, $result);
|
||||
$cached = $queryCache->put($querykey, $rsm, $result, $this->_hints);
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
$this->cacheLogger->queryCacheMiss($queryCache->getRegion()->getName(), $querykey);
|
||||
}
|
||||
|
||||
if ($this->cacheLogger && $cached) {
|
||||
$this->cacheLogger->queryCachePut($queryCache->getRegion()->getName(), $querykey);
|
||||
if ($cached) {
|
||||
$this->cacheLogger->queryCachePut($queryCache->getRegion()->getName(), $querykey);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
@ -1089,15 +1092,18 @@ abstract class AbstractQuery
|
||||
*/
|
||||
protected function getHash()
|
||||
{
|
||||
$hints = $this->getHints();
|
||||
$self = $this;
|
||||
$query = $this->getSQL();
|
||||
$params = array();
|
||||
$hints = $this->getHints();
|
||||
$params = array_map(function(Parameter $parameter) use ($self) {
|
||||
// Small optimization
|
||||
// Does not invoke processParameterValue for scalar values
|
||||
if (is_scalar($value = $parameter->getValue())) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
foreach ($this->parameters as $parameter) {
|
||||
$value = $parameter->getValue();
|
||||
|
||||
$params[$parameter->getName()] = is_scalar($value) ? $value : $this->processParameterValue($value);
|
||||
}
|
||||
return $self->processParameterValue($value);
|
||||
}, $this->parameters->getValues());
|
||||
|
||||
ksort($hints);
|
||||
|
||||
|
@ -51,7 +51,7 @@ interface Cache
|
||||
const MODE_NORMAL = 3;
|
||||
|
||||
/**
|
||||
* The session will never read items from the cache,
|
||||
* The query will never read items from the cache,
|
||||
* but will refresh items to the cache as it reads them from the database.
|
||||
*/
|
||||
const MODE_REFRESH = 4;
|
||||
@ -59,7 +59,7 @@ interface Cache
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param \Doctrine\ORMEntityManagerInterface $em
|
||||
* @param \Doctrine\ORM\EntityManagerInterface $em
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em);
|
||||
|
||||
|
@ -98,7 +98,7 @@ class CacheConfiguration
|
||||
*/
|
||||
public function getRegionsConfiguration()
|
||||
{
|
||||
if ($this->regionsConfig == null) {
|
||||
if ($this->regionsConfig === null) {
|
||||
$this->regionsConfig = new RegionsConfiguration();
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ class CacheConfiguration
|
||||
*/
|
||||
public function getQueryValidator()
|
||||
{
|
||||
if ($this->queryValidator == null) {
|
||||
if ($this->queryValidator === null) {
|
||||
$this->queryValidator = new TimestampQueryCacheValidator();
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ class CacheConfiguration
|
||||
/**
|
||||
* @param string $className
|
||||
*
|
||||
* @throws ORMException If not is a \Doctrine\ORM\Cache
|
||||
* @throws \Doctrine\ORM\ORMException If is not a \Doctrine\ORM\Cache
|
||||
*/
|
||||
public function setCacheClassName($className)
|
||||
{
|
||||
|
@ -23,6 +23,10 @@ namespace Doctrine\ORM\Cache;
|
||||
/**
|
||||
* Cache entry interface
|
||||
*
|
||||
* <b>IMPORTANT NOTE:</b>
|
||||
*
|
||||
* Fields of classes that implement CacheEntry are public for performance reason.
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
|
@ -27,6 +27,8 @@ use Doctrine\ORM\Persisters\CollectionPersister;
|
||||
use Doctrine\ORM\Persisters\EntityPersister;
|
||||
|
||||
/**
|
||||
* Contract for building second level cache regions components.
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
|
@ -26,7 +26,7 @@ use Doctrine\ORM\Cache\CollectionCacheKey;
|
||||
use Doctrine\ORM\Cache\CollectionCacheEntry;
|
||||
|
||||
/**
|
||||
* Hidrator cache entry for collections
|
||||
* Hydrator cache entry for collections
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
@ -46,7 +46,7 @@ interface CollectionHydrator
|
||||
* @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The owning entity metadata.
|
||||
* @param \Doctrine\ORM\Cache\CollectionCacheKey $key The cached collection key.
|
||||
* @param \Doctrine\ORM\Cache\CollectionCacheEntry $entry The cached collection entry.
|
||||
* @param Doctrine\ORM\PersistentCollection $collection The collection to load the cache into.
|
||||
* @param \Doctrine\ORM\PersistentCollection $collection The collection to load the cache into.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
@ -22,10 +22,8 @@ namespace Doctrine\ORM\Cache;
|
||||
|
||||
use Doctrine\ORM\Cache;
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\ORM\Cache\EntityCacheKey;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Cache\CollectionCacheKey;
|
||||
use Doctrine\ORM\Cache\Persister\CachedPersister;
|
||||
use Doctrine\ORM\ORMInvalidArgumentException;
|
||||
|
||||
@ -111,13 +109,12 @@ class DefaultCache implements Cache
|
||||
{
|
||||
$metadata = $this->em->getClassMetadata($className);
|
||||
$persister = $this->uow->getEntityPersister($metadata->rootEntityName);
|
||||
$key = $this->buildEntityCacheKey($metadata, $identifier);
|
||||
|
||||
if ( ! ($persister instanceof CachedPersister)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $persister->getCacheRegion()->contains($key);
|
||||
return $persister->getCacheRegion()->contains($this->buildEntityCacheKey($metadata, $identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,13 +124,12 @@ class DefaultCache implements Cache
|
||||
{
|
||||
$metadata = $this->em->getClassMetadata($className);
|
||||
$persister = $this->uow->getEntityPersister($metadata->rootEntityName);
|
||||
$key = $this->buildEntityCacheKey($metadata, $identifier);
|
||||
|
||||
if ( ! ($persister instanceof CachedPersister)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$persister->getCacheRegion()->evict($key);
|
||||
$persister->getCacheRegion()->evict($this->buildEntityCacheKey($metadata, $identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,13 +172,12 @@ class DefaultCache implements Cache
|
||||
{
|
||||
$metadata = $this->em->getClassMetadata($className);
|
||||
$persister = $this->uow->getCollectionPersister($metadata->getAssociationMapping($association));
|
||||
$key = $this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier);
|
||||
|
||||
if ( ! ($persister instanceof CachedPersister)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $persister->getCacheRegion()->contains($key);
|
||||
return $persister->getCacheRegion()->contains($this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,13 +187,12 @@ class DefaultCache implements Cache
|
||||
{
|
||||
$metadata = $this->em->getClassMetadata($className);
|
||||
$persister = $this->uow->getCollectionPersister($metadata->getAssociationMapping($association));
|
||||
$key = $this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier);
|
||||
|
||||
if ( ! ($persister instanceof CachedPersister)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$persister->getCacheRegion()->evict($key);
|
||||
$persister->getCacheRegion()->evict($this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,17 +20,17 @@
|
||||
|
||||
namespace Doctrine\ORM\Cache;
|
||||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
|
||||
use Doctrine\ORM\Cache;
|
||||
use Doctrine\ORM\Cache\Region;
|
||||
use Doctrine\ORM\Cache\TimestampRegion;
|
||||
|
||||
use Doctrine\ORM\Cache\RegionsConfiguration;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Cache\Region\DefaultRegion;
|
||||
use Doctrine\ORM\Cache\Region\FileLockRegion;
|
||||
use Doctrine\ORM\Cache\Region\UpdateTimestampCache;
|
||||
use Doctrine\Common\Cache\Cache as CacheDriver;
|
||||
use Doctrine\ORM\Persisters\EntityPersister;
|
||||
use Doctrine\ORM\Persisters\CollectionPersister;
|
||||
use Doctrine\ORM\Cache\Persister\ReadOnlyCachedEntityPersister;
|
||||
@ -47,7 +47,7 @@ use Doctrine\ORM\Cache\Persister\NonStrictReadWriteCachedCollectionPersister;
|
||||
class DefaultCacheFactory implements CacheFactory
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\Common\Cache\Cache
|
||||
* @var \Doctrine\Common\Cache\CacheProvider
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
@ -73,9 +73,9 @@ class DefaultCacheFactory implements CacheFactory
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Cache\RegionsConfiguration $cacheConfig
|
||||
* @param \Doctrine\Common\Cache\Cache $cache
|
||||
* @param \Doctrine\Common\Cache\CacheProvider $cache
|
||||
*/
|
||||
public function __construct(RegionsConfiguration $cacheConfig, CacheDriver $cache)
|
||||
public function __construct(RegionsConfiguration $cacheConfig, CacheProvider $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
$this->regionsConfig = $cacheConfig;
|
||||
@ -113,7 +113,6 @@ class DefaultCacheFactory implements CacheFactory
|
||||
$this->timestampRegion = $region;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -202,7 +201,7 @@ class DefaultCacheFactory implements CacheFactory
|
||||
|
||||
if ( ! $this->fileLockRegionDirectory) {
|
||||
throw new \RuntimeException(
|
||||
'To use a "READ_WRITE" cache an implementation of "Doctrine\ORM\Cache\ConcurrentRegion" is required, ' .
|
||||
'If you want to use a "READ_WRITE" cache an implementation of "Doctrine\ORM\Cache\ConcurrentRegion" is required, ' .
|
||||
'The default implementation provided by doctrine is "Doctrine\ORM\Cache\Region\FileLockRegion" if you what to use it please provide a valid directory, DefaultCacheFactory#setFileLockRegionDirectory(). '
|
||||
);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class DefaultQueryCache implements QueryCache
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(QueryCacheKey $key, ResultSetMapping $rsm)
|
||||
public function get(QueryCacheKey $key, ResultSetMapping $rsm, array $hints = array())
|
||||
{
|
||||
if ( ! ($key->cacheMode & Cache::MODE_GET)) {
|
||||
return null;
|
||||
@ -108,13 +108,13 @@ class DefaultQueryCache implements QueryCache
|
||||
}
|
||||
|
||||
$result = array();
|
||||
$entityName = reset($rsm->aliasMap); //@TODO find root entity
|
||||
$entityName = reset($rsm->aliasMap);
|
||||
$hasRelation = ( ! empty($rsm->relationMap));
|
||||
$persister = $this->uow->getEntityPersister($entityName);
|
||||
$region = $persister->getCacheRegion();
|
||||
$regionName = $region->getName();
|
||||
|
||||
// @TODO - move to cache hydration componente
|
||||
// @TODO - move to cache hydration component
|
||||
foreach ($entry->result as $index => $entry) {
|
||||
|
||||
if (($entityEntry = $region->get($entityKey = new EntityCacheKey($entityName, $entry['identifier']))) === null) {
|
||||
@ -204,10 +204,18 @@ class DefaultQueryCache implements QueryCache
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function put(QueryCacheKey $key, ResultSetMapping $rsm, array $result)
|
||||
public function put(QueryCacheKey $key, ResultSetMapping $rsm, $result, array $hints = array())
|
||||
{
|
||||
if ($rsm->scalarMappings) {
|
||||
throw new CacheException("Second level cache does not suport scalar results.");
|
||||
throw new CacheException("Second level cache does not support scalar results.");
|
||||
}
|
||||
|
||||
if (count($rsm->entityMappings) > 1) {
|
||||
throw new CacheException("Second level cache does not support multiple root entities.");
|
||||
}
|
||||
|
||||
if ( ! $rsm->isSelect) {
|
||||
throw new CacheException("Second-level cache query supports only select statements.");
|
||||
}
|
||||
|
||||
if (isset($hints[Query::HINT_FORCE_PARTIAL_LOAD]) && $hints[Query::HINT_FORCE_PARTIAL_LOAD]) {
|
||||
@ -219,7 +227,7 @@ class DefaultQueryCache implements QueryCache
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$entityName = reset($rsm->aliasMap); //@TODO find root entity
|
||||
$entityName = reset($rsm->aliasMap);
|
||||
$hasRelation = ( ! empty($rsm->relationMap));
|
||||
$metadata = $this->em->getClassMetadata($entityName);
|
||||
$persister = $this->uow->getEntityPersister($entityName);
|
||||
@ -246,7 +254,7 @@ class DefaultQueryCache implements QueryCache
|
||||
continue;
|
||||
}
|
||||
|
||||
// @TODO - move to cache hydration componente
|
||||
// @TODO - move to cache hydration components
|
||||
foreach ($rsm->relationMap as $name) {
|
||||
$assoc = $metadata->associationMappings[$name];
|
||||
|
||||
|
@ -25,7 +25,7 @@ use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Cache\EntityCacheEntry;
|
||||
|
||||
/**
|
||||
* Hidrator cache entry for entities
|
||||
* Hydrator cache entry for entities
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
|
@ -145,7 +145,6 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
*/
|
||||
public function loadCollectionCache(PersistentCollection $collection, CollectionCacheKey $key)
|
||||
{
|
||||
|
||||
if (($cache = $this->region->get($key)) === null) {
|
||||
return null;
|
||||
}
|
||||
@ -164,7 +163,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
{
|
||||
$targetPersister = $this->uow->getEntityPersister($this->targetEntity->rootEntityName);
|
||||
$targetRegion = $targetPersister->getCacheRegion();
|
||||
$targetHidrator = $targetPersister->getEntityHydrator();
|
||||
$targetHydrator = $targetPersister->getEntityHydrator();
|
||||
$entry = $this->hydrator->buildCacheEntry($this->targetEntity, $key, $elements);
|
||||
|
||||
foreach ($entry->identifiers as $index => $identifier) {
|
||||
@ -182,7 +181,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
}
|
||||
|
||||
$entity = $elements[$index];
|
||||
$entityEntry = $targetHidrator->buildCacheEntry($class, $entityKey, $entity);
|
||||
$entityEntry = $targetHydrator->buildCacheEntry($class, $entityKey, $entity);
|
||||
|
||||
$targetRegion->put($entityKey, $entityEntry);
|
||||
}
|
||||
|
@ -179,7 +179,6 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
public function exists($entity, array $extraConditions = array())
|
||||
{
|
||||
if (empty($extraConditions)) {
|
||||
|
||||
$key = new EntityCacheKey($this->class->rootEntityName, $this->class->getIdentifierValues($entity));
|
||||
|
||||
if ($this->region->contains($key)) {
|
||||
@ -302,7 +301,6 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
*/
|
||||
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null, array $orderBy = null)
|
||||
{
|
||||
//@TODO - Should throw exception ?
|
||||
if ($entity !== null || $assoc !== null || ! empty($hints) || $lockMode !== 0) {
|
||||
return $this->persister->load($criteria, $entity, $assoc, $hints, $lockMode, $limit, $orderBy);
|
||||
}
|
||||
@ -317,7 +315,6 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$result = $queryCache->get($querykey, $rsm);
|
||||
|
||||
if ($result !== null) {
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
$this->cacheLogger->queryCacheHit($this->regionName, $querykey);
|
||||
}
|
||||
@ -331,12 +328,14 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
|
||||
$cached = $queryCache->put($querykey, $rsm, array($result));
|
||||
|
||||
if ($this->cacheLogger && $result) {
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
|
||||
}
|
||||
if ($this->cacheLogger) {
|
||||
if ($result) {
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
|
||||
}
|
||||
|
||||
if ($this->cacheLogger && $cached) {
|
||||
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
|
||||
if ($cached) {
|
||||
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
@ -356,7 +355,6 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$result = $queryCache->get($querykey, $rsm);
|
||||
|
||||
if ($result !== null) {
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
$this->cacheLogger->queryCacheHit($this->regionName, $querykey);
|
||||
}
|
||||
@ -367,12 +365,14 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$result = $this->persister->loadAll($criteria, $orderBy, $limit, $offset);
|
||||
$cached = $queryCache->put($querykey, $rsm, $result);
|
||||
|
||||
if ($this->cacheLogger && $result) {
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
|
||||
}
|
||||
if ($this->cacheLogger) {
|
||||
if ($result) {
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
|
||||
}
|
||||
|
||||
if ($this->cacheLogger && $cached) {
|
||||
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
|
||||
if ($cached) {
|
||||
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
@ -388,13 +388,11 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$class = $this->class;
|
||||
|
||||
if ($cacheEntry !== null) {
|
||||
|
||||
if ($cacheEntry->class !== $this->class->name) {
|
||||
$class = $this->metadataFactory->getMetadataFor($cacheEntry->class);
|
||||
}
|
||||
|
||||
if (($entity = $this->hydrator->loadCacheEntry($class, $cacheKey, $cacheEntry, $entity)) !== null) {
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
$this->cacheLogger->entityCacheHit($this->regionName, $cacheKey);
|
||||
}
|
||||
@ -419,11 +417,11 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$cacheEntry = $this->hydrator->buildCacheEntry($class, $cacheKey, $entity);
|
||||
$cached = $this->region->put($cacheKey, $cacheEntry);
|
||||
|
||||
if ($this->cacheLogger && $cached) {
|
||||
$this->cacheLogger->entityCachePut($this->regionName, $cacheKey);
|
||||
}
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
if ($cached) {
|
||||
$this->cacheLogger->entityCachePut($this->regionName, $cacheKey);
|
||||
}
|
||||
|
||||
$this->cacheLogger->entityCacheMiss($this->regionName, $cacheKey);
|
||||
}
|
||||
|
||||
@ -453,7 +451,6 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$list = $persister->loadCollectionCache($coll, $key);
|
||||
|
||||
if ($list !== null) {
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
$this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
|
||||
}
|
||||
@ -489,7 +486,6 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$list = $persister->loadCollectionCache($coll, $key);
|
||||
|
||||
if ($list !== null) {
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
$this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
|
||||
|
||||
// Invalidate non initialized collections OR odered collection
|
||||
if ($isDirty && ! $isInitialized || isset($this->association['orderBy'])) {
|
||||
|
||||
$this->persister->update($collection);
|
||||
|
||||
$this->queuedCache['delete'][spl_object_hash($collection)] = $key;
|
||||
|
@ -41,7 +41,6 @@ class NonStrictReadWriteCachedEntityPersister extends AbstractEntityPersister
|
||||
|
||||
if (isset($this->queuedCache['insert'])) {
|
||||
foreach ($this->queuedCache['insert'] as $entity) {
|
||||
|
||||
$class = $this->class;
|
||||
$className = ClassUtils::getClass($entity);
|
||||
|
||||
@ -62,7 +61,6 @@ class NonStrictReadWriteCachedEntityPersister extends AbstractEntityPersister
|
||||
|
||||
if (isset($this->queuedCache['update'])) {
|
||||
foreach ($this->queuedCache['update'] as $entity) {
|
||||
|
||||
$class = $this->class;
|
||||
$className = ClassUtils::getClass($entity);
|
||||
|
||||
|
@ -33,11 +33,6 @@ use Doctrine\ORM\PersistentCollection;
|
||||
*/
|
||||
class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\Cache\ConcurrentRegion
|
||||
*/
|
||||
protected $region;
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Persisters\CollectionPersister $persister The collection persister that will be cached.
|
||||
* @param \Doctrine\ORM\Cache\ConcurrentRegion $region The collection region.
|
||||
|
@ -35,11 +35,6 @@ use Doctrine\ORM\Cache\EntityCacheKey;
|
||||
*/
|
||||
class ReadWriteCachedEntityPersister extends AbstractEntityPersister
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\Cache\ConcurrentRegion
|
||||
*/
|
||||
protected $region;
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Persister\EntityPersister $persister The entity persister to cache.
|
||||
* @param \Doctrine\ORM\Cache\ConcurrentRegion $region The entity cache region.
|
||||
|
@ -39,19 +39,21 @@ interface QueryCache
|
||||
/**
|
||||
* @param \Doctrine\ORM\Cache\QueryCacheKey $key
|
||||
* @param \Doctrine\ORM\Query\ResultSetMapping $rsm
|
||||
* @param array $result
|
||||
* @param mixed $result
|
||||
* @param array $hints
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function put(QueryCacheKey $key, ResultSetMapping $rsm, array $result);
|
||||
public function put(QueryCacheKey $key, ResultSetMapping $rsm, $result, array $hints = array());
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Cache\QueryCacheKey $key
|
||||
* @param \Doctrine\ORM\Query\ResultSetMapping $rsm
|
||||
* @param \Doctrine\ORM\Cache\QueryCacheKey $key
|
||||
* @param \Doctrine\ORM\Query\ResultSetMapping $rsm
|
||||
* @param array $hints
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function get(QueryCacheKey $key, ResultSetMapping $rsm);
|
||||
public function get(QueryCacheKey $key, ResultSetMapping $rsm, array $hints = array());
|
||||
|
||||
/**
|
||||
* @return \Doctrine\ORM\Cache\Region
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
namespace Doctrine\ORM\Cache;
|
||||
|
||||
use Doctrine\ORM\Cache;
|
||||
|
||||
/**
|
||||
* A key that identifies a particular query.
|
||||
*
|
||||
@ -43,7 +45,7 @@ class QueryCacheKey extends CacheKey
|
||||
* @param integer $lifetime Query lifetime
|
||||
* @param integer $cacheMode Query cache mode
|
||||
*/
|
||||
public function __construct($hash, $lifetime = 0, $cacheMode = 3)
|
||||
public function __construct($hash, $lifetime = 0, $cacheMode = Cache::MODE_NORMAL)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
$this->lifetime = $lifetime;
|
||||
|
@ -34,8 +34,6 @@ use Doctrine\Common\Cache\CacheProvider;
|
||||
*/
|
||||
class DefaultRegion implements Region
|
||||
{
|
||||
const ENTRY_KEY = '_entry_';
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Common\Cache\CacheProvider
|
||||
*/
|
||||
@ -86,7 +84,7 @@ class DefaultRegion implements Region
|
||||
*/
|
||||
public function contains(CacheKey $key)
|
||||
{
|
||||
return $this->cache->contains($this->name . self::ENTRY_KEY . $key->hash);
|
||||
return $this->cache->contains($this->name . '_' . $key->hash);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,7 +92,7 @@ class DefaultRegion implements Region
|
||||
*/
|
||||
public function get(CacheKey $key)
|
||||
{
|
||||
return $this->cache->fetch($this->name . self::ENTRY_KEY . $key->hash) ?: null;
|
||||
return $this->cache->fetch($this->name . '_' . $key->hash) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,7 +100,7 @@ class DefaultRegion implements Region
|
||||
*/
|
||||
public function put(CacheKey $key, CacheEntry $entry, Lock $lock = null)
|
||||
{
|
||||
return $this->cache->save($this->name . self::ENTRY_KEY . $key->hash, $entry, $this->lifetime);
|
||||
return $this->cache->save($this->name . '_' . $key->hash, $entry, $this->lifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,7 +108,7 @@ class DefaultRegion implements Region
|
||||
*/
|
||||
public function evict(CacheKey $key)
|
||||
{
|
||||
return $this->cache->delete($this->name . self::ENTRY_KEY . $key->hash);
|
||||
return $this->cache->delete($this->name . '_' . $key->hash);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,9 +77,9 @@ class FileLockRegion implements ConcurrentRegion
|
||||
* param \Doctrine\ORM\Cache\CacheKey $key
|
||||
* param \Doctrine\ORM\Cache\Lock $lock
|
||||
*
|
||||
* return boolean
|
||||
* @return boolean
|
||||
*/
|
||||
private function isLoked(CacheKey $key, Lock $lock = null)
|
||||
private function isLocked(CacheKey $key, Lock $lock = null)
|
||||
{
|
||||
$filename = $this->getLockFileName($key);
|
||||
|
||||
@ -153,7 +153,7 @@ class FileLockRegion implements ConcurrentRegion
|
||||
*/
|
||||
public function contains(CacheKey $key)
|
||||
{
|
||||
if ($this->isLoked($key)) {
|
||||
if ($this->isLocked($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ class FileLockRegion implements ConcurrentRegion
|
||||
*/
|
||||
public function get(CacheKey $key)
|
||||
{
|
||||
if ($this->isLoked($key)) {
|
||||
if ($this->isLocked($key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ class FileLockRegion implements ConcurrentRegion
|
||||
*/
|
||||
public function put(CacheKey $key, CacheEntry $entry, Lock $lock = null)
|
||||
{
|
||||
if ($this->isLoked($key, $lock)) {
|
||||
if ($this->isLocked($key, $lock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ class FileLockRegion implements ConcurrentRegion
|
||||
*/
|
||||
public function evict(CacheKey $key)
|
||||
{
|
||||
if ($this->isLoked($key)) {
|
||||
if ($this->isLocked($key)) {
|
||||
@unlink($this->getLockFileName($key));
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ class FileLockRegion implements ConcurrentRegion
|
||||
*/
|
||||
public function lock(CacheKey $key)
|
||||
{
|
||||
if ($this->isLoked($key)) {
|
||||
if ($this->isLocked($key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ class FileLockRegion implements ConcurrentRegion
|
||||
*/
|
||||
public function unlock(CacheKey $key, Lock $lock)
|
||||
{
|
||||
if ($this->isLoked($key, $lock)) {
|
||||
if ($this->isLocked($key, $lock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -97,11 +97,9 @@ class RegionsConfiguration
|
||||
*/
|
||||
public function getLifetime($regionName)
|
||||
{
|
||||
if (isset($this->lifetimes[$regionName])) {
|
||||
return $this->lifetimes[$regionName];
|
||||
}
|
||||
|
||||
return $this->defaultLifetime;
|
||||
return isset($this->lifetimes[$regionName])
|
||||
? $this->lifetimes[$regionName]
|
||||
: $this->defaultLifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,11 +118,9 @@ class RegionsConfiguration
|
||||
*/
|
||||
public function getLockLifetime($regionName)
|
||||
{
|
||||
if (isset($this->lockLifetimes[$regionName])) {
|
||||
return $this->lockLifetimes[$regionName];
|
||||
}
|
||||
|
||||
return $this->defaultLockLifetime;
|
||||
return isset($this->lockLifetimes[$regionName])
|
||||
? $this->lockLifetimes[$regionName]
|
||||
: $this->defaultLockLifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,12 +29,12 @@ namespace Doctrine\ORM\Cache;
|
||||
class TimestampCacheEntry implements CacheEntry
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
* @var float
|
||||
*/
|
||||
public $time;
|
||||
|
||||
/**
|
||||
* @param array $result
|
||||
* @param float $time
|
||||
*/
|
||||
public function __construct($time = null)
|
||||
{
|
||||
|
@ -82,8 +82,8 @@ class XmlDriver extends FileDriver
|
||||
$metadata->setPrimaryTable($table);
|
||||
|
||||
// Evaluate second level cache
|
||||
if (isset($xmlRoot->{'cache'})) {
|
||||
$metadata->enableCache($this->cacheToArray($xmlRoot->{'cache'}));
|
||||
if (isset($xmlRoot->cache)) {
|
||||
$metadata->enableCache($this->cacheToArray($xmlRoot->cache));
|
||||
}
|
||||
|
||||
// Evaluate named queries
|
||||
@ -356,8 +356,8 @@ class XmlDriver extends FileDriver
|
||||
$metadata->mapOneToOne($mapping);
|
||||
|
||||
// Evaluate second level cache
|
||||
if (isset($oneToOneElement->{'cache'})) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($oneToOneElement->{'cache'}));
|
||||
if (isset($oneToOneElement->cache)) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($oneToOneElement->cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -400,8 +400,8 @@ class XmlDriver extends FileDriver
|
||||
$metadata->mapOneToMany($mapping);
|
||||
|
||||
// Evaluate second level cache
|
||||
if (isset($oneToManyElement->{'cache'})) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($oneToManyElement->{'cache'}));
|
||||
if (isset($oneToManyElement->cache)) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($oneToManyElement->cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -445,8 +445,8 @@ class XmlDriver extends FileDriver
|
||||
$metadata->mapManyToOne($mapping);
|
||||
|
||||
// Evaluate second level cache
|
||||
if (isset($manyToOneElement->{'cache'})) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($manyToOneElement->{'cache'}));
|
||||
if (isset($manyToOneElement->cache)) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($manyToOneElement->cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -515,8 +515,8 @@ class XmlDriver extends FileDriver
|
||||
$metadata->mapManyToMany($mapping);
|
||||
|
||||
// Evaluate second level cache
|
||||
if (isset($manyToManyElement->{'cache'})) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($manyToManyElement->{'cache'}));
|
||||
if (isset($manyToManyElement->cache)) {
|
||||
$metadata->enableAssociationCache($mapping['fieldName'], $this->cacheToArray($manyToManyElement->cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -733,8 +733,16 @@ class XmlDriver extends FileDriver
|
||||
*/
|
||||
private function cacheToArray(SimpleXMLElement $cacheMapping)
|
||||
{
|
||||
$region = isset($cacheMapping['region']) ? (string)$cacheMapping['region'] : null;
|
||||
$usage = isset($cacheMapping['usage']) ? constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . strtoupper($cacheMapping['usage'])) : null;
|
||||
$region = isset($cacheMapping['region']) ? (string) $cacheMapping['region'] : null;
|
||||
$usage = isset($cacheMapping['usage']) ? strtoupper($cacheMapping['usage']) : null;
|
||||
|
||||
if ($usage && ! defined('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage)) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid cache usage "%s"', $usage));
|
||||
}
|
||||
|
||||
if ($usage) {
|
||||
$usage = constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage);
|
||||
}
|
||||
|
||||
return array(
|
||||
'usage' => $usage,
|
||||
|
@ -738,8 +738,16 @@ class YamlDriver extends FileDriver
|
||||
*/
|
||||
private function cacheToArray($cacheMapping)
|
||||
{
|
||||
$region = isset($cacheMapping['region']) ? (string)$cacheMapping['region'] : null;
|
||||
$usage = isset($cacheMapping['usage']) ? constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . strtoupper($cacheMapping['usage'])) : null;
|
||||
$region = isset($cacheMapping['region']) ? (string) $cacheMapping['region'] : null;
|
||||
$usage = isset($cacheMapping['usage']) ? strtoupper($cacheMapping['usage']) : null;
|
||||
|
||||
if ($usage && ! defined('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage)) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid cache usage "%s"', $usage));
|
||||
}
|
||||
|
||||
if ($usage) {
|
||||
$usage = constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage);
|
||||
}
|
||||
|
||||
return array(
|
||||
'usage' => $usage,
|
||||
|
@ -109,7 +109,7 @@ class ORMException extends Exception
|
||||
*
|
||||
* @return \Doctrine\ORM\ORMInvalidArgumentException
|
||||
*/
|
||||
static public function unexpectedAssociationValue($class, $association, $given, $expected)
|
||||
public static function unexpectedAssociationValue($class, $association, $given, $expected)
|
||||
{
|
||||
return new self(sprintf('Found entity of type %s on association %s#%s, but expecting %s', $given, $class, $association, $expected));
|
||||
}
|
||||
|
@ -73,8 +73,6 @@ interface CollectionPersister
|
||||
* @param \Doctrine\ORM\PersistentCollection $collection
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function count(PersistentCollection $collection);
|
||||
|
||||
|
@ -22,7 +22,6 @@ namespace Doctrine\ORM\Persisters;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
|
||||
|
||||
/**
|
||||
* Entity persister interface
|
||||
* Define the behavior that should be implemented by all entity persisters.
|
||||
|
@ -309,7 +309,7 @@ final class Query extends AbstractQuery
|
||||
foreach ($this->parameters as $parameter) {
|
||||
$key = $parameter->getName();
|
||||
$value = $parameter->getValue();
|
||||
$rsm = $this->_resultSetMapping ?: $this->getResultSetMapping();
|
||||
$rsm = $this->getResultSetMapping();
|
||||
|
||||
if ( ! isset($paramMappings[$key])) {
|
||||
throw QueryException::unknownParameter($key);
|
||||
|
@ -43,6 +43,14 @@ class ResultSetMapping
|
||||
*/
|
||||
public $isMixed = false;
|
||||
|
||||
/**
|
||||
* Whether the result is a select statement.
|
||||
*
|
||||
* @ignore
|
||||
* @var boolean
|
||||
*/
|
||||
public $isSelect = true;
|
||||
|
||||
/**
|
||||
* Maps alias names to class names.
|
||||
*
|
||||
|
@ -573,6 +573,7 @@ class SqlWalker implements TreeWalker
|
||||
public function walkUpdateStatement(AST\UpdateStatement $AST)
|
||||
{
|
||||
$this->useSqlTableAliases = false;
|
||||
$this->rsm->isSelect = false;
|
||||
|
||||
return $this->walkUpdateClause($AST->updateClause)
|
||||
. $this->walkWhereClause($AST->whereClause);
|
||||
@ -584,6 +585,7 @@ class SqlWalker implements TreeWalker
|
||||
public function walkDeleteStatement(AST\DeleteStatement $AST)
|
||||
{
|
||||
$this->useSqlTableAliases = false;
|
||||
$this->rsm->isSelect = false;
|
||||
|
||||
return $this->walkDeleteClause($AST->deleteClause)
|
||||
. $this->walkWhereClause($AST->whereClause);
|
||||
|
@ -2539,7 +2539,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$overrideLocalValues = isset($hints[Query::HINT_REFRESH]);
|
||||
|
||||
// If only a specific entity is set to refresh, check that it's the one
|
||||
if(isset($hints[Query::HINT_REFRESH_ENTITY])) {
|
||||
if (isset($hints[Query::HINT_REFRESH_ENTITY])) {
|
||||
$overrideLocalValues = $hints[Query::HINT_REFRESH_ENTITY] === $entity;
|
||||
}
|
||||
|
||||
@ -3255,13 +3255,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
|
||||
foreach ($this->persisters as $persister) {
|
||||
if($persister instanceof CachedPersister) {
|
||||
if ($persister instanceof CachedPersister) {
|
||||
$persister->afterTransactionComplete();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->collectionPersisters as $persister) {
|
||||
if($persister instanceof CachedPersister) {
|
||||
if ($persister instanceof CachedPersister) {
|
||||
$persister->afterTransactionComplete();
|
||||
}
|
||||
}
|
||||
@ -3277,13 +3277,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
|
||||
foreach ($this->persisters as $persister) {
|
||||
if($persister instanceof CachedPersister) {
|
||||
if ($persister instanceof CachedPersister) {
|
||||
$persister->afterTransactionRolledBack();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->collectionPersisters as $persister) {
|
||||
if($persister instanceof CachedPersister) {
|
||||
if ($persister instanceof CachedPersister) {
|
||||
$persister->afterTransactionRolledBack();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class CacheMetadataListener
|
||||
'usage' => ClassMetadata::CACHE_USAGE_NONSTRICT_READ_WRITE
|
||||
);
|
||||
|
||||
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
|
||||
/** @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
|
||||
if (strstr($metadata->name, 'Doctrine\Tests\Models\Cache')) {
|
||||
return;
|
||||
}
|
||||
|
@ -18,13 +18,13 @@ class CacheRegionMock implements Region
|
||||
$this->returns[$method][] = $value;
|
||||
}
|
||||
|
||||
public function getReturn($method, $datault)
|
||||
public function getReturn($method, $default)
|
||||
{
|
||||
if (isset($this->returns[$method]) && ! empty($this->returns[$method])) {
|
||||
return array_shift($this->returns[$method]);
|
||||
}
|
||||
|
||||
return $datault;
|
||||
return $default;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
|
@ -31,7 +31,7 @@ class ConcurrentRegionMock implements ConcurrentRegion
|
||||
if (isset($this->exceptions[$method]) && ! empty($this->exceptions[$method])) {
|
||||
$exception = array_shift($this->exceptions[$method]);
|
||||
|
||||
if($exception != null) {
|
||||
if ($exception != null) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ class DefaultCacheFactoryTest extends OrmTestCase
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
* @expectedExceptionMessage To use a "READ_WRITE" cache an implementation of "Doctrine\ORM\Cache\ConcurrentRegion" is required, The default implementation provided by doctrine is "Doctrine\ORM\Cache\Region\FileLockRegion" if you what to use it please provide a valid directory
|
||||
* @expectedExceptionMessage If you want to use a "READ_WRITE" cache an implementation of "Doctrine\ORM\Cache\ConcurrentRegion" is required, The default implementation provided by doctrine is "Doctrine\ORM\Cache\Region\FileLockRegion" if you what to use it please provide a valid directory
|
||||
*/
|
||||
public function testInvalidFileLockRegionDirectoryException()
|
||||
{
|
||||
|
@ -236,7 +236,7 @@ class DefaultQueryCacheTest extends OrmTestCase
|
||||
|
||||
$rsm->addRootEntityFromClassMetadata(Country::CLASSNAME, 'c');
|
||||
|
||||
$result = $this->queryCache->get($key, $rsm, $entry);
|
||||
$result = $this->queryCache->get($key, $rsm);
|
||||
|
||||
$this->assertCount(2, $result);
|
||||
$this->assertInstanceOf(Country::CLASSNAME, $result[0]);
|
||||
@ -349,7 +349,7 @@ class DefaultQueryCacheTest extends OrmTestCase
|
||||
|
||||
$this->region->addReturn('get', $entry);
|
||||
|
||||
$this->assertNull($this->queryCache->get($key, $rsm, $entry));
|
||||
$this->assertNull($this->queryCache->get($key, $rsm));
|
||||
}
|
||||
|
||||
public function testIgnoreCacheNonPutMode()
|
||||
@ -394,7 +394,7 @@ class DefaultQueryCacheTest extends OrmTestCase
|
||||
|
||||
$rsm->addRootEntityFromClassMetadata(Country::CLASSNAME, 'c');
|
||||
|
||||
$this->assertNull($this->queryCache->get($key, $rsm, $entry));
|
||||
$this->assertNull($this->queryCache->get($key, $rsm));
|
||||
}
|
||||
|
||||
public function testGetShouldIgnoreNonQueryCacheEntryResult()
|
||||
@ -417,7 +417,7 @@ class DefaultQueryCacheTest extends OrmTestCase
|
||||
|
||||
$rsm->addRootEntityFromClassMetadata(Country::CLASSNAME, 'c');
|
||||
|
||||
$this->assertNull($this->queryCache->get($key, $rsm, $entry));
|
||||
$this->assertNull($this->queryCache->get($key, $rsm));
|
||||
}
|
||||
|
||||
public function testGetShouldIgnoreMissingEntityQueryCacheEntry()
|
||||
@ -434,7 +434,7 @@ class DefaultQueryCacheTest extends OrmTestCase
|
||||
|
||||
$rsm->addRootEntityFromClassMetadata(Country::CLASSNAME, 'c');
|
||||
|
||||
$this->assertNull($this->queryCache->get($key, $rsm, $entry));
|
||||
$this->assertNull($this->queryCache->get($key, $rsm));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -463,7 +463,7 @@ class DefaultQueryCacheTest extends OrmTestCase
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\ORM\Cache\CacheException
|
||||
* @expectedExceptionMessage Second level cache does not suport scalar results.
|
||||
* @expectedExceptionMessage Second level cache does not support scalar results.
|
||||
*/
|
||||
public function testScalarResultException()
|
||||
{
|
||||
@ -476,6 +476,22 @@ class DefaultQueryCacheTest extends OrmTestCase
|
||||
$this->queryCache->put($key, $rsm, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\ORM\Cache\CacheException
|
||||
* @expectedExceptionMessage Second level cache does not support multiple root entities.
|
||||
*/
|
||||
public function testSuportMultipleRootEntitiesException()
|
||||
{
|
||||
$result = array();
|
||||
$key = new QueryCacheKey('query.key1', 0);
|
||||
$rsm = new ResultSetMappingBuilder($this->em);
|
||||
|
||||
$rsm->addEntityResult('Doctrine\Tests\Models\Cache\City', 'e1');
|
||||
$rsm->addEntityResult('Doctrine\Tests\Models\Cache\State', 'e2');
|
||||
|
||||
$this->queryCache->put($key, $rsm, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\ORM\Cache\CacheException
|
||||
* @expectedExceptionMessage Entity "Doctrine\Tests\Models\Generic\BooleanModel" not configured as part of the second-level cache.
|
||||
|
@ -8,7 +8,6 @@ use Doctrine\ORM\Cache\ConcurrentRegion;
|
||||
use Doctrine\Tests\Mocks\CacheEntryMock;
|
||||
use Doctrine\Tests\Mocks\CacheKeyMock;
|
||||
use Doctrine\ORM\Cache\CacheKey;
|
||||
use Doctrine\ORM\Cache\Lock;
|
||||
|
||||
use RecursiveIteratorIterator;
|
||||
use RecursiveDirectoryIterator;
|
||||
|
@ -18,8 +18,6 @@ use Doctrine\Tests\Models\Cache\Bar;
|
||||
use Doctrine\Tests\Models\Cache\AttractionContactInfo;
|
||||
use Doctrine\Tests\Models\Cache\AttractionLocationInfo;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-2183
|
||||
*/
|
||||
|
@ -2,14 +2,13 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
|
||||
use Doctrine\Tests\Models\Cache\City;
|
||||
use Doctrine\Tests\Models\Cache\Flight;
|
||||
|
||||
/**
|
||||
* @group DDC-2183
|
||||
*/
|
||||
class SecondLevelCacheCompositPrimaryKeyTest extends SecondLevelCacheAbstractTest
|
||||
class SecondLevelCacheCompositePrimaryKeyTest extends SecondLevelCacheAbstractTest
|
||||
{
|
||||
public function testPutAndLoadCompositPrimaryKeyEntities()
|
||||
{
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
|
||||
use Doctrine\Tests\Models\Cache\City;
|
||||
use Doctrine\Tests\Models\Cache\State;
|
||||
use Doctrine\Tests\Models\Cache\Travel;
|
||||
|
@ -7,7 +7,6 @@ use Doctrine\Tests\Models\Cache\AttractionInfo;
|
||||
use Doctrine\Tests\Models\Cache\AttractionContactInfo;
|
||||
use Doctrine\Tests\Models\Cache\AttractionLocationInfo;
|
||||
|
||||
|
||||
/**
|
||||
* @group DDC-2183
|
||||
*/
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
|
||||
use Doctrine\Tests\Models\Cache\City;
|
||||
use Doctrine\Tests\Models\Cache\State;
|
||||
use Doctrine\Tests\Models\Cache\Travel;
|
||||
|
@ -9,6 +9,7 @@ use Doctrine\Tests\Models\Cache\City;
|
||||
use Doctrine\ORM\Cache\QueryCacheKey;
|
||||
use Doctrine\ORM\Cache\EntityCacheKey;
|
||||
use Doctrine\ORM\Cache\EntityCacheEntry;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\Cache;
|
||||
|
||||
/**
|
||||
@ -840,4 +841,26 @@ class SecondLevelCacheQueryCacheTest extends SecondLevelCacheAbstractTest
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Doctrine\ORM\Cache\CacheException
|
||||
* @expectedExceptionMessage Second-level cache query supports only select statements.
|
||||
*/
|
||||
public function testNonCacheableQueryDeleteStatementException()
|
||||
{
|
||||
$this->_em->createQuery('DELETE Doctrine\Tests\Models\Cache\Country u WHERE u.id = 4')
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Doctrine\ORM\Cache\CacheException
|
||||
* @expectedExceptionMessage Second-level cache query supports only select statements.
|
||||
*/
|
||||
public function testNonCacheableQueryUpdateStatementException()
|
||||
{
|
||||
$this->_em->createQuery('UPDATE Doctrine\Tests\Models\Cache\Country u SET u.name = NULL WHERE u.id = 4')
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
}
|
||||
}
|
@ -9,8 +9,6 @@ use Doctrine\Tests\Models\Cache\State;
|
||||
use Doctrine\Tests\Models\Cache\City;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-2183
|
||||
* @group performance
|
||||
|
@ -10,7 +10,6 @@ use Doctrine\ORM\Cache\DefaultCacheFactory;
|
||||
*/
|
||||
abstract class OrmTestCase extends DoctrineTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* The metadata cache that is shared between all ORM tests (except functional tests).
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user