From 1bfa8f0fc322d3cd5702eb57385915e415d7988f Mon Sep 17 00:00:00 2001 From: fabios Date: Thu, 3 Oct 2013 13:55:55 -0400 Subject: [PATCH] Extract cache config --- doctrine-mapping.xsd | 10 +- lib/Doctrine/ORM/AbstractQuery.php | 7 +- lib/Doctrine/ORM/Cache/CacheConfiguration.php | 159 ++++++++++++ lib/Doctrine/ORM/Cache/CacheFactory.php | 8 +- lib/Doctrine/ORM/Cache/DefaultCache.php | 4 +- .../ORM/Cache/DefaultCacheFactory.php | 18 +- .../ORM/Cache/DefaultCollectionHydrator.php | 2 +- .../ORM/Cache/DefaultEntityHydrator.php | 2 +- lib/Doctrine/ORM/Cache/DefaultQueryCache.php | 4 +- .../Persister/AbstractCollectionPersister.php | 13 +- .../Persister/AbstractEntityPersister.php | 19 +- ...onStrictReadWriteCachedEntityPersister.php | 4 +- .../ORM/Cache/RegionsConfiguration.php | 138 +++++++++++ lib/Doctrine/ORM/Configuration.php | 232 +++++------------- lib/Doctrine/ORM/EntityManager.php | 2 +- lib/Doctrine/ORM/UnitOfWork.php | 6 +- .../Tests/ORM/Cache/CacheConfigTest.php | 82 +++++++ .../ORM/Cache/DefaultCacheFactoryTest.php | 21 +- .../Tests/ORM/Cache/DefaultQueryCacheTest.php | 4 +- .../Doctrine/Tests/ORM/ConfigurationTest.php | 13 +- .../SecondLevelCacheConcurrentTest.php | 4 +- .../Doctrine/Tests/OrmFunctionalTestCase.php | 16 +- tests/Doctrine/Tests/OrmTestCase.php | 11 +- 23 files changed, 532 insertions(+), 247 deletions(-) create mode 100644 lib/Doctrine/ORM/Cache/CacheConfiguration.php create mode 100644 lib/Doctrine/ORM/Cache/RegionsConfiguration.php create mode 100644 tests/Doctrine/Tests/ORM/Cache/CacheConfigTest.php diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index 493bfa128..345fe4898 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -167,7 +167,7 @@ - + @@ -459,7 +459,7 @@ - + @@ -477,7 +477,7 @@ - + @@ -493,7 +493,7 @@ - + @@ -512,7 +512,7 @@ - + diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index ae366e930..cfc3e22dd 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -162,7 +162,12 @@ abstract class AbstractQuery { $this->_em = $em; $this->parameters = new ArrayCollection(); - $this->cacheLogger = $em->getConfiguration()->getSecondLevelCacheLogger(); + + if ($this->_em->getConfiguration()->isSecondLevelCacheEnabled()) { + $this->cacheLogger = $em->getConfiguration() + ->getSecondLevelCacheConfiguration() + ->getCacheLogger(); + } } /** diff --git a/lib/Doctrine/ORM/Cache/CacheConfiguration.php b/lib/Doctrine/ORM/Cache/CacheConfiguration.php new file mode 100644 index 000000000..78540f3f7 --- /dev/null +++ b/lib/Doctrine/ORM/Cache/CacheConfiguration.php @@ -0,0 +1,159 @@ +. + */ + +namespace Doctrine\ORM\Cache; + +use Doctrine\ORM\ORMException; +use Doctrine\ORM\Cache\CacheFactory; +use Doctrine\ORM\Cache\Logging\CacheLogger; +use Doctrine\ORM\Cache\QueryCacheValidator; +use Doctrine\ORM\Cache\TimestampQueryCacheValidator; + +/** + * Configuration container for second-level cache. + * + * @since 2.5 + * @author Fabio B. Silva + */ +class CacheConfiguration +{ + /** + * @var \Doctrine\ORM\Cache\CacheFactory + */ + private $cacheFactory; + + /** + * @var \Doctrine\ORM\Cache\RegionsConfiguration + */ + private $regionsConfig; + + /** + * @var \Doctrine\ORM\Cache\Logging\CacheLogger + */ + private $cacheLogger; + + /** + * @var \Doctrine\ORM\Cache\QueryCacheValidator + */ + private $queryValidator; + + /** + * @var string + */ + private $cacheClassName = 'Doctrine\ORM\Cache\DefaultCache'; + + /** + * @return \Doctrine\ORM\Cache\CacheFactory|null + */ + public function getCacheFactory() + { + return $this->cacheFactory; + } + + /** + * @param \Doctrine\ORM\Cache\CacheFactory $factory + * + * @return void + */ + public function setCacheFactory(CacheFactory $factory) + { + $this->cacheFactory = $factory; + } + + /** + * @return \Doctrine\ORM\Cache\Logging\CacheLogger|null + */ + public function getCacheLogger() + { + return $this->cacheLogger; + } + + /** + * @param \Doctrine\ORM\Cache\Logging\CacheLogger $logger + */ + public function setCacheLogger(CacheLogger $logger) + { + $this->cacheLogger = $logger; + } + + /** + * @return \Doctrine\ORM\Cache\QueryCacheValidator + */ + public function getRegionsConfiguration() + { + if ($this->regionsConfig == null) { + $this->regionsConfig = new RegionsConfiguration(); + } + + return $this->regionsConfig; + } + + /** + * @param \Doctrine\ORM\Cache\RegionsConfiguration $regionsConfig + */ + public function setRegionsConfiguration(RegionsConfiguration $regionsConfig) + { + $this->regionsConfig = $regionsConfig; + } + + /** + * @return \Doctrine\ORM\Cache\QueryCacheValidator + */ + public function getQueryValidator() + { + if ($this->queryValidator == null) { + $this->queryValidator = new TimestampQueryCacheValidator(); + } + + return $this->queryValidator; + } + + /** + * @param \Doctrine\ORM\Cache\QueryCacheValidator $validator + */ + public function setQueryValidator(QueryCacheValidator $validator) + { + $this->queryValidator = $validator; + } + + /** + * @param string $className + * + * @throws ORMException If not is a \Doctrine\ORM\Cache + */ + public function setCacheClassName($className) + { + $reflectionClass = new \ReflectionClass($className); + + if ( ! $reflectionClass->implementsInterface('Doctrine\ORM\Cache')) { + throw ORMException::invalidSecondLevelCache($className); + } + + $this->cacheClassName = $className; + } + + /** + * @return string A \Doctrine\ORM\Cache class name + */ + public function getCacheClassName() + { + return $this->cacheClassName; + } +} diff --git a/lib/Doctrine/ORM/Cache/CacheFactory.php b/lib/Doctrine/ORM/Cache/CacheFactory.php index 89d54d43f..77bcb24a6 100644 --- a/lib/Doctrine/ORM/Cache/CacheFactory.php +++ b/lib/Doctrine/ORM/Cache/CacheFactory.php @@ -65,22 +65,22 @@ interface CacheFactory 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); diff --git a/lib/Doctrine/ORM/Cache/DefaultCache.php b/lib/Doctrine/ORM/Cache/DefaultCache.php index 92f0c6396..1e76653d9 100644 --- a/lib/Doctrine/ORM/Cache/DefaultCache.php +++ b/lib/Doctrine/ORM/Cache/DefaultCache.php @@ -69,7 +69,9 @@ class DefaultCache implements Cache { $this->em = $em; $this->uow = $em->getUnitOfWork(); - $this->cacheFactory = $em->getConfiguration()->getSecondLevelCacheFactory(); + $this->cacheFactory = $em->getConfiguration() + ->getSecondLevelCacheConfiguration() + ->getCacheFactory(); } /** diff --git a/lib/Doctrine/ORM/Cache/DefaultCacheFactory.php b/lib/Doctrine/ORM/Cache/DefaultCacheFactory.php index 5ce9b5b7a..360a97210 100644 --- a/lib/Doctrine/ORM/Cache/DefaultCacheFactory.php +++ b/lib/Doctrine/ORM/Cache/DefaultCacheFactory.php @@ -22,7 +22,7 @@ namespace Doctrine\ORM\Cache; use Doctrine\ORM\Cache; use Doctrine\ORM\Cache\Region; -use Doctrine\ORM\Configuration; +use Doctrine\ORM\Cache\RegionsConfiguration; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Cache\Region\DefaultRegion; @@ -50,9 +50,9 @@ class DefaultCacheFactory implements CacheFactory private $cache; /** - * @var \Doctrine\ORM\Configuration + * @var \Doctrine\ORM\Cache\RegionsConfiguration */ - private $configuration; + private $regionsConfig; /** * @var array @@ -65,13 +65,13 @@ class DefaultCacheFactory implements CacheFactory private $fileLockRegionDirectory; /** - * @param \Doctrine\ORM\Configuration $configuration - * @param \Doctrine\Common\Cache\Cache $cache + * @param \Doctrine\ORM\Cache\RegionsConfiguration $cacheConfig + * @param \Doctrine\Common\Cache\Cache $cache */ - public function __construct(Configuration $configuration, CacheDriver $cache) + public function __construct(RegionsConfiguration $cacheConfig, CacheDriver $cache) { $this->cache = $cache; - $this->configuration = $configuration; + $this->regionsConfig = $cacheConfig; } /** @@ -181,7 +181,7 @@ class DefaultCacheFactory implements CacheFactory } $region = new DefaultRegion($cache['region'], clone $this->cache, array( - 'lifetime' => $this->configuration->getSecondLevelCacheRegionLifetime($cache['region']) + 'lifetime' => $this->regionsConfig->getLifetime($cache['region']) )); if ($cache['usage'] === ClassMetadata::CACHE_USAGE_READ_WRITE) { @@ -194,7 +194,7 @@ class DefaultCacheFactory implements CacheFactory } $directory = $this->fileLockRegionDirectory . DIRECTORY_SEPARATOR . $cache['region']; - $region = new FileLockRegion($region, $directory, $this->configuration->getSecondLevelCacheLockLifetime()); + $region = new FileLockRegion($region, $directory, $this->regionsConfig->getLockLifetime($cache['region'])); } return $this->regions[$cache['region']] = $region; diff --git a/lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php b/lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php index fb4a45d2f..53ab2c58f 100644 --- a/lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php +++ b/lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php @@ -28,7 +28,7 @@ use Doctrine\ORM\Cache\CollectionCacheKey; use Doctrine\ORM\Cache\CollectionCacheEntry; /** - * Default hidrator cache for collections + * Default hydrator cache for collections * * @since 2.5 * @author Fabio B. Silva diff --git a/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php b/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php index fede42d51..f022ae59f 100644 --- a/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php +++ b/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php @@ -28,7 +28,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Cache\EntityCacheEntry; /** - * Default hidrator cache for entities + * Default hydrator cache for entities * * @since 2.5 * @author Fabio B. Silva diff --git a/lib/Doctrine/ORM/Cache/DefaultQueryCache.php b/lib/Doctrine/ORM/Cache/DefaultQueryCache.php index 8c13d7419..3ff1dd06b 100644 --- a/lib/Doctrine/ORM/Cache/DefaultQueryCache.php +++ b/lib/Doctrine/ORM/Cache/DefaultQueryCache.php @@ -75,7 +75,9 @@ class DefaultQueryCache implements QueryCache $this->em = $em; $this->region = $region; $this->uow = $em->getUnitOfWork(); - $this->validator = $em->getConfiguration()->getSecondLevelCacheQueryValidator(); + $this->validator = $em->getConfiguration() + ->getSecondLevelCacheConfiguration() + ->getQueryValidator(); } /** diff --git a/lib/Doctrine/ORM/Cache/Persister/AbstractCollectionPersister.php b/lib/Doctrine/ORM/Cache/Persister/AbstractCollectionPersister.php index 23a249940..ca56a1bcc 100644 --- a/lib/Doctrine/ORM/Cache/Persister/AbstractCollectionPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/AbstractCollectionPersister.php @@ -82,7 +82,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister /** * @var \Doctrine\ORM\Cache\CollectionHydrator */ - protected $hidrator; + protected $hydrator; /** * @var \Doctrine\ORM\Cache\Logging\CacheLogger @@ -98,7 +98,8 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister public function __construct(CollectionPersister $persister, Region $region, EntityManagerInterface $em, array $association) { $configuration = $em->getConfiguration(); - $cacheFactory = $configuration->getSecondLevelCacheFactory(); + $cacheConfig = $configuration->getSecondLevelCacheConfiguration(); + $cacheFactory = $cacheConfig->getCacheFactory(); $this->region = $region; $this->persister = $persister; @@ -106,8 +107,8 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister $this->regionName = $region->getName(); $this->uow = $em->getUnitOfWork(); $this->metadataFactory = $em->getMetadataFactory(); - $this->cacheLogger = $configuration->getSecondLevelCacheLogger(); - $this->hidrator = $cacheFactory->buildCollectionHydrator($em, $association); + $this->cacheLogger = $cacheConfig->getCacheLogger(); + $this->hydrator = $cacheFactory->buildCollectionHydrator($em, $association); $this->sourceEntity = $em->getClassMetadata($association['sourceEntity']); $this->targetEntity = $em->getClassMetadata($association['targetEntity']); } @@ -149,7 +150,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister return null; } - if (($cache = $this->hidrator->loadCacheEntry($this->sourceEntity, $key, $cache, $collection)) === null) { + if (($cache = $this->hydrator->loadCacheEntry($this->sourceEntity, $key, $cache, $collection)) === null) { return null; } @@ -164,7 +165,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister $targetPersister = $this->uow->getEntityPersister($this->targetEntity->rootEntityName); $targetRegion = $targetPersister->getCacheRegion(); $targetHidrator = $targetPersister->getEntityHydrator(); - $entry = $this->hidrator->buildCacheEntry($this->targetEntity, $key, $elements); + $entry = $this->hydrator->buildCacheEntry($this->targetEntity, $key, $elements); foreach ($entry->identifiers as $index => $identifier) { $entityKey = new EntityCacheKey($this->targetEntity->rootEntityName, $identifier); diff --git a/lib/Doctrine/ORM/Cache/Persister/AbstractEntityPersister.php b/lib/Doctrine/ORM/Cache/Persister/AbstractEntityPersister.php index 25e4bd559..ad113b609 100644 --- a/lib/Doctrine/ORM/Cache/Persister/AbstractEntityPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/AbstractEntityPersister.php @@ -72,7 +72,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister /** * @var \Doctrine\ORM\Cache\EntityHydrator */ - protected $hidrator; + protected $hydrator; /** * @var \Doctrine\ORM\Cache @@ -97,8 +97,9 @@ abstract class AbstractEntityPersister implements CachedEntityPersister */ public function __construct(EntityPersister $persister, Region $region, EntityManagerInterface $em, ClassMetadata $class) { - $config = $em->getConfiguration(); - $factory = $config->getSecondLevelCacheFactory(); + $configuration = $em->getConfiguration(); + $cacheConfig = $configuration->getSecondLevelCacheConfiguration(); + $cacheFactory = $cacheConfig->getCacheFactory(); $this->class = $class; $this->region = $region; @@ -107,8 +108,8 @@ abstract class AbstractEntityPersister implements CachedEntityPersister $this->regionName = $region->getName(); $this->uow = $em->getUnitOfWork(); $this->metadataFactory = $em->getMetadataFactory(); - $this->cacheLogger = $config->getSecondLevelCacheLogger(); - $this->hidrator = $factory->buildEntityHydrator($em, $class); + $this->cacheLogger = $cacheConfig->getCacheLogger(); + $this->hydrator = $cacheFactory->buildEntityHydrator($em, $class); } /** @@ -189,7 +190,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister */ public function getEntityHydrator() { - return $this->hidrator; + return $this->hydrator; } /** @@ -204,7 +205,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister $class = $this->metadataFactory->getMetadataFor($className); } - $entry = $this->hidrator->buildCacheEntry($class, $key, $entity); + $entry = $this->hydrator->buildCacheEntry($class, $key, $entity); $cached = $this->region->put($key, $entry); if ($this->cacheLogger && $cached) { @@ -370,7 +371,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister $class = $this->metadataFactory->getMetadataFor($cacheEntry->class); } - if (($entity = $this->hidrator->loadCacheEntry($class, $cacheKey, $cacheEntry, $entity)) !== null) { + if (($entity = $this->hydrator->loadCacheEntry($class, $cacheKey, $cacheEntry, $entity)) !== null) { if ($this->cacheLogger) { $this->cacheLogger->entityCacheHit($this->regionName, $cacheKey); @@ -393,7 +394,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister $class = $this->metadataFactory->getMetadataFor($className); } - $cacheEntry = $this->hidrator->buildCacheEntry($class, $cacheKey, $entity); + $cacheEntry = $this->hydrator->buildCacheEntry($class, $cacheKey, $entity); $cached = $this->region->put($cacheKey, $cacheEntry); if ($this->cacheLogger && $cached) { diff --git a/lib/Doctrine/ORM/Cache/Persister/NonStrictReadWriteCachedEntityPersister.php b/lib/Doctrine/ORM/Cache/Persister/NonStrictReadWriteCachedEntityPersister.php index 281f70562..f6420ca21 100644 --- a/lib/Doctrine/ORM/Cache/Persister/NonStrictReadWriteCachedEntityPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/NonStrictReadWriteCachedEntityPersister.php @@ -48,7 +48,7 @@ class NonStrictReadWriteCachedEntityPersister extends AbstractEntityPersister } $key = new EntityCacheKey($class->rootEntityName, $this->uow->getEntityIdentifier($entity)); - $entry = $this->hidrator->buildCacheEntry($class, $key, $entity); + $entry = $this->hydrator->buildCacheEntry($class, $key, $entity); $cached = $this->region->put($key, $entry); if ($this->cacheLogger && $cached) { @@ -68,7 +68,7 @@ class NonStrictReadWriteCachedEntityPersister extends AbstractEntityPersister } $key = new EntityCacheKey($class->rootEntityName, $this->uow->getEntityIdentifier($entity)); - $entry = $this->hidrator->buildCacheEntry($class, $key, $entity); + $entry = $this->hydrator->buildCacheEntry($class, $key, $entity); $cached = $this->region->put($key, $entry); if ($this->cacheLogger && $cached) { diff --git a/lib/Doctrine/ORM/Cache/RegionsConfiguration.php b/lib/Doctrine/ORM/Cache/RegionsConfiguration.php new file mode 100644 index 000000000..58bcbdef9 --- /dev/null +++ b/lib/Doctrine/ORM/Cache/RegionsConfiguration.php @@ -0,0 +1,138 @@ +. + */ + +namespace Doctrine\ORM\Cache; + +/** + * Cache regions configuration + * + * @since 2.5 + * @author Fabio B. Silva + */ +class RegionsConfiguration +{ + /** + * @var array + */ + private $lifetimes; + + /** + * @var array + */ + private $lockLifetimes; + + /** + * @var integer + */ + private $defaultLifetime; + + /** + * @var integer + */ + private $defaultLockLifetime; + + /** + * @param integer $defaultLifetime + * @param integer $defaultLockLifetime + */ + public function __construct($defaultLifetime = 3600, $defaultLockLifetime = 60) + { + $this->defaultLifetime = $defaultLifetime; + $this->defaultLockLifetime = $defaultLockLifetime; + } + + /** + * @return integer + */ + public function getDefaultLifetime() + { + return $this->defaultLifetime; + } + + /** + * @param integer $defaultLifetime + */ + public function setDefaultLifetime($defaultLifetime) + { + $this->defaultLifetime = $defaultLifetime; + } + + /** + * @return integer + */ + public function getDefaultLockLifetime() + { + return $this->defaultLockLifetime; + } + + /** + * @param integer $defaultLockLifetime + */ + public function setDefaultLockLifetime($defaultLockLifetime) + { + $this->defaultLockLifetime = $defaultLockLifetime; + } + + /** + * @param string $regionName + * + * @return integer + */ + public function getLifetime($regionName) + { + if (isset($this->lifetimes[$regionName])) { + return $this->lifetimes[$regionName]; + } + + return $this->defaultLifetime; + } + + /** + * @param string $name + * @param integer $lifetime + */ + public function setLifetime($name, $lifetime) + { + $this->lifetimes[$name] = (integer) $lifetime; + } + + /** + * @param string $regionName + * + * @return integer + */ + public function getLockLifetime($regionName) + { + if (isset($this->lockLifetimes[$regionName])) { + return $this->lockLifetimes[$regionName]; + } + + return $this->defaultLockLifetime; + } + + /** + * @param string $name + * @param integer $lifetime + */ + public function setLockLifetime($name, $lifetime) + { + $this->lockLifetimes[$name] = (integer) $lifetime; + } +} diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index be57376e2..094f223a3 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -24,7 +24,8 @@ use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\Common\Annotations\CachedReader; use Doctrine\Common\Annotations\SimpleAnnotationReader; use Doctrine\Common\Cache\ArrayCache; -use Doctrine\Common\Cache\Cache; +use Doctrine\Common\Cache\Cache as CacheDriver; +use Doctrine\ORM\Cache\CacheConfiguration; use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; use Doctrine\ORM\Mapping\DefaultEntityListenerResolver; use Doctrine\ORM\Mapping\DefaultNamingStrategy; @@ -35,10 +36,6 @@ use Doctrine\ORM\Mapping\NamingStrategy; use Doctrine\ORM\Mapping\QuoteStrategy; use Doctrine\ORM\Repository\DefaultRepositoryFactory; use Doctrine\ORM\Repository\RepositoryFactory; -use Doctrine\ORM\Cache\CacheFactory; -use Doctrine\ORM\Cache\Logging\CacheLogger; -use Doctrine\ORM\Cache\QueryCacheValidator; -use Doctrine\ORM\Cache\TimestampQueryCacheValidator; /** * Configuration container for all configuration options of Doctrine. @@ -237,141 +234,6 @@ class Configuration extends \Doctrine\DBAL\Configuration : null; } - /** - * @return boolean - */ - public function isSecondLevelCacheEnabled() - { - return isset($this->_attributes['isSecondLevelCacheEnabled']) - ? $this->_attributes['isSecondLevelCacheEnabled'] - : false; - } - - /** - * @param boolean $flag - * - * @return void - */ - public function setSecondLevelCacheEnabled($flag = true) - { - $this->_attributes['isSecondLevelCacheEnabled'] = (boolean) $flag; - } - - /** - * @return \Doctrine\ORM\Cache\CacheFactory|null - */ - public function getSecondLevelCacheFactory() - { - return isset($this->_attributes['secondLevelCacheFactory']) - ? $this->_attributes['secondLevelCacheFactory'] - : null; - } - - /** - * @param \Doctrine\ORM\Cache\CacheFactory $factory - * - * @return void - */ - public function setSecondLevelCacheFactory(CacheFactory $factory) - { - $this->_attributes['secondLevelCacheFactory'] = $factory; - } - - /** - * @param string $name - * - * @return integer - */ - public function getSecondLevelCacheRegionLifetime($name) - { - if (isset($this->_attributes['secondLevelCacheRegionLifetime'][$name])) { - return $this->_attributes['secondLevelCacheRegionLifetime'][$name]; - } - - return $this->getSecondLevelCacheDefaultRegionLifetime(); - } - - /** - * @param string $name - * @param integer $lifetime - */ - public function setSecondLevelCacheRegionLifetime($name, $lifetime) - { - $this->_attributes['secondLevelCacheRegionLifetime'][$name] = (integer) $lifetime; - } - - /** - * @return integer - */ - public function getSecondLevelCacheDefaultRegionLifetime() - { - return isset($this->_attributes['secondLevelCacheDefaultRegionLifetime']) - ? $this->_attributes['secondLevelCacheDefaultRegionLifetime'] - : 0; - } - - /** - * @param integer $lifetime - */ - public function setSecondLevelCacheDefaultRegionLifetime($lifetime) - { - $this->_attributes['secondLevelCacheDefaultRegionLifetime'] = (integer) $lifetime; - } - - /** - * @param integer $lifetime - */ - public function setSecondLevelCacheLockLifetime($lifetime) - { - $this->_attributes['secondLevelCacheLockLifetime'] = (integer) $lifetime; - } - - /** - * @return integer - */ - public function getSecondLevelCacheLockLifetime() - { - return isset($this->_attributes['secondLevelCacheLockLifetime']) - ? $this->_attributes['secondLevelCacheLockLifetime'] - : 60; - } - - /** - * @return \Doctrine\ORM\Cache\Logging\CacheLogger|null - */ - public function getSecondLevelCacheLogger() - { - return isset($this->_attributes['secondLevelCacheLogger']) - ? $this->_attributes['secondLevelCacheLogger'] - : null; - } - - /** - * @param \Doctrine\ORM\Cache\Logging\CacheLogger $logger - */ - public function setSecondLevelCacheLogger(CacheLogger $logger) - { - $this->_attributes['secondLevelCacheLogger'] = $logger; - } - - /** - * @return \Doctrine\ORM\Cache\QueryCacheValidator - */ - public function getSecondLevelCacheQueryValidator() - { - return isset($this->_attributes['secondLevelCacheQueryValidator']) - ? $this->_attributes['secondLevelCacheQueryValidator'] - : $this->_attributes['secondLevelCacheQueryValidator'] = new TimestampQueryCacheValidator(); - } - - /** - * @param \Doctrine\ORM\Cache\QueryCacheValidator $validator - */ - public function setSecondLevelCacheQueryValidator(QueryCacheValidator $validator) - { - $this->_attributes['secondLevelCacheQueryValidator'] = $validator; - } - /** * Gets the cache driver implementation that is used for the query cache (SQL cache). * @@ -391,7 +253,7 @@ class Configuration extends \Doctrine\DBAL\Configuration * * @return void */ - public function setQueryCacheImpl(Cache $cacheImpl) + public function setQueryCacheImpl(CacheDriver $cacheImpl) { $this->_attributes['queryCacheImpl'] = $cacheImpl; } @@ -415,7 +277,7 @@ class Configuration extends \Doctrine\DBAL\Configuration * * @return void */ - public function setHydrationCacheImpl(Cache $cacheImpl) + public function setHydrationCacheImpl(CacheDriver $cacheImpl) { $this->_attributes['hydrationCacheImpl'] = $cacheImpl; } @@ -439,7 +301,7 @@ class Configuration extends \Doctrine\DBAL\Configuration * * @return void */ - public function setMetadataCacheImpl(Cache $cacheImpl) + public function setMetadataCacheImpl(CacheDriver $cacheImpl) { $this->_attributes['metadataCacheImpl'] = $cacheImpl; } @@ -835,38 +697,6 @@ class Configuration extends \Doctrine\DBAL\Configuration : 'Doctrine\ORM\EntityRepository'; } - /** - * @since 2.5 - * - * @param string $className - * - * @return void - * - * @throws ORMException If not is a \Doctrine\ORM\Cache - */ - public function setSecondLevelCacheClassName($className) - { - $reflectionClass = new \ReflectionClass($className); - - if ( ! $reflectionClass->implementsInterface('Doctrine\ORM\Cache')) { - throw ORMException::invalidSecondLevelCache($className); - } - - $this->_attributes['secondLevelCacheClassName'] = $className; - } - - /** - * @since 2.5 - * - * @return string A \Doctrine\ORM\Cache implementation - */ - public function getSecondLevelCacheClassName() - { - return isset($this->_attributes['secondLevelCacheClassName']) - ? $this->_attributes['secondLevelCacheClassName'] - : 'Doctrine\ORM\Cache\DefaultCache'; - } - /** * Sets naming strategy. * @@ -976,4 +806,56 @@ class Configuration extends \Doctrine\DBAL\Configuration ? $this->_attributes['repositoryFactory'] : new DefaultRepositoryFactory(); } + + /** + * @since 2.5 + * + * @return boolean + */ + public function isSecondLevelCacheEnabled() + { + return isset($this->_attributes['isSecondLevelCacheEnabled']) + ? $this->_attributes['isSecondLevelCacheEnabled'] + : false; + } + + /** + * @since 2.5 + * + * @param boolean $flag + * + * @return void + */ + public function setSecondLevelCacheEnabled($flag = true) + { + $this->_attributes['isSecondLevelCacheEnabled'] = (boolean) $flag; + } + + /** + * @since 2.5 + * + * @param \Doctrine\ORM\Cache\CacheConfiguration $cacheConfig + * + * @return void + */ + public function setSecondLevelCacheConfiguration(CacheConfiguration $cacheConfig) + { + $this->_attributes['secondLevelCacheConfiguration'] = $cacheConfig; + } + + /** + * @since 2.5 + * + * @return \Doctrine\ORM\Cache\CacheConfiguration|null + */ + public function getSecondLevelCacheConfiguration() + { + if ( ! isset($this->_attributes['secondLevelCacheConfiguration']) && $this->isSecondLevelCacheEnabled()) { + $this->_attributes['secondLevelCacheConfiguration'] = new CacheConfiguration(); + } + + return isset($this->_attributes['secondLevelCacheConfiguration']) + ? $this->_attributes['secondLevelCacheConfiguration'] + : null; + } } diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index ef2b58fd0..0df60eed9 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -166,7 +166,7 @@ use Doctrine\Common\Util\ClassUtils; ); if ($config->isSecondLevelCacheEnabled()) { - $cacheClass = $config->getSecondLevelCacheClassName(); + $cacheClass = $config->getSecondLevelCacheConfiguration()->getCacheClassName(); $this->cache = new $cacheClass($this); } } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 6e7ea488b..e0909d4b6 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3012,7 +3012,8 @@ class UnitOfWork implements PropertyChangedListener if ($this->hasCache && $class->cache !== null) { $persister = $this->em->getConfiguration() - ->getSecondLevelCacheFactory() + ->getSecondLevelCacheConfiguration() + ->getCacheFactory() ->buildCachedEntityPersister($this->em, $persister, $class); } @@ -3044,7 +3045,8 @@ class UnitOfWork implements PropertyChangedListener if ($this->hasCache && isset($association['cache'])) { $persister = $this->em->getConfiguration() - ->getSecondLevelCacheFactory() + ->getSecondLevelCacheConfiguration() + ->getCacheFactory() ->buildCachedCollectionPersister($this->em, $persister, $association); } diff --git a/tests/Doctrine/Tests/ORM/Cache/CacheConfigTest.php b/tests/Doctrine/Tests/ORM/Cache/CacheConfigTest.php new file mode 100644 index 000000000..fff090330 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Cache/CacheConfigTest.php @@ -0,0 +1,82 @@ +config = new CacheConfiguration(); + } + + public function testSetGetCacheClassName() + { + $mockClass = get_class($this->getMock('Doctrine\ORM\Cache')); + + $this->assertEquals('Doctrine\ORM\Cache\DefaultCache', $this->config->getCacheClassName()); + $this->config->setCacheClassName($mockClass); + $this->assertEquals($mockClass, $this->config->getCacheClassName()); + + $this->setExpectedException('Doctrine\ORM\ORMException'); + $this->config->setCacheClassName(__CLASS__); + } + + public function testSetGetRegionLifetime() + { + $config = $this->config->getRegionsConfiguration(); + + $config->setDefaultLifetime(111); + + $this->assertEquals($config->getDefaultLifetime(), $config->getLifetime('foo_region')); + + $config->setLifetime('foo_region', 222); + + $this->assertEquals(222, $config->getLifetime('foo_region')); + } + + public function testSetGetCacheLogger() + { + $logger = $this->getMock('Doctrine\ORM\Cache\Logging\CacheLogger'); + + $this->assertNull($this->config->getCacheLogger()); + + $this->config->setCacheLogger($logger); + + $this->assertEquals($logger, $this->config->getCacheLogger()); + } + + public function testSetGetCacheFactory() + { + $factory = $this->getMock('Doctrine\ORM\Cache\CacheFactory'); + + $this->assertNull($this->config->getCacheFactory()); + + $this->config->setCacheFactory($factory); + + $this->assertEquals($factory, $this->config->getCacheFactory()); + } + + public function testSetGetQueryValidator() + { + $validator = $this->getMock('Doctrine\ORM\Cache\QueryCacheValidator'); + + $this->assertInstanceOf('Doctrine\ORM\Cache\TimestampQueryCacheValidator', $this->config->getQueryValidator()); + + $this->config->setQueryValidator($validator); + + $this->assertEquals($validator, $this->config->getQueryValidator()); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultCacheFactoryTest.php b/tests/Doctrine/Tests/ORM/Cache/DefaultCacheFactoryTest.php index d52196d44..fa7cb219a 100644 --- a/tests/Doctrine/Tests/ORM/Cache/DefaultCacheFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/DefaultCacheFactoryTest.php @@ -9,6 +9,7 @@ use Doctrine\ORM\Cache\Region\DefaultRegion; use Doctrine\Tests\Mocks\ConcurrentRegionMock; use Doctrine\ORM\Persisters\BasicEntityPersister; use Doctrine\ORM\Persisters\OneToManyPersister; +use Doctrine\ORM\Cache\RegionsConfiguration; /** * @group DDC-2183 @@ -25,16 +26,20 @@ class DefaultCacheFactoryTest extends OrmTestCase */ private $em; + /** + * @var \Doctrine\ORM\Cache\RegionsConfiguration + */ + private $regionsConfig; + protected function setUp() { $this->enableSecondLevelCache(); parent::setUp(); - $this->em = $this->_getTestEntityManager(); - - - $arguments = array($this->em->getConfiguration(), $this->getSharedSecondLevelCacheDriverImpl()); - $this->factory = $this->getMock('\Doctrine\ORM\Cache\DefaultCacheFactory', array( + $this->em = $this->_getTestEntityManager(); + $this->regionsConfig = new RegionsConfiguration; + $arguments = array($this->regionsConfig, $this->getSharedSecondLevelCacheDriverImpl()); + $this->factory = $this->getMock('\Doctrine\ORM\Cache\DefaultCacheFactory', array( 'getRegion' ), $arguments); } @@ -182,7 +187,7 @@ class DefaultCacheFactoryTest extends OrmTestCase $metadata2 = clone $em->getClassMetadata('Doctrine\Tests\Models\Cache\AttractionLocationInfo'); $persister1 = new BasicEntityPersister($em, $metadata1); $persister2 = new BasicEntityPersister($em, $metadata2); - $factory = new DefaultCacheFactory($this->em->getConfiguration(), $this->getSharedSecondLevelCacheDriverImpl()); + $factory = new DefaultCacheFactory($this->regionsConfig, $this->getSharedSecondLevelCacheDriverImpl()); $cachedPersister1 = $factory->buildCachedEntityPersister($em, $persister1, $metadata1); $cachedPersister2 = $factory->buildCachedEntityPersister($em, $persister2, $metadata2); @@ -201,7 +206,7 @@ class DefaultCacheFactoryTest extends OrmTestCase $metadata2 = clone $em->getClassMetadata('Doctrine\Tests\Models\Cache\City'); $persister1 = new BasicEntityPersister($em, $metadata1); $persister2 = new BasicEntityPersister($em, $metadata2); - $factory = new DefaultCacheFactory($this->em->getConfiguration(), $this->getSharedSecondLevelCacheDriverImpl()); + $factory = new DefaultCacheFactory($this->regionsConfig, $this->getSharedSecondLevelCacheDriverImpl()); $cachedPersister1 = $factory->buildCachedEntityPersister($em, $persister1, $metadata1); $cachedPersister2 = $factory->buildCachedEntityPersister($em, $persister2, $metadata2); @@ -252,7 +257,7 @@ class DefaultCacheFactoryTest extends OrmTestCase */ public function testInvalidFileLockRegionDirectoryException() { - $factory = new \Doctrine\ORM\Cache\DefaultCacheFactory($this->em->getConfiguration(), $this->getSharedSecondLevelCacheDriverImpl()); + $factory = new \Doctrine\ORM\Cache\DefaultCacheFactory($this->regionsConfig, $this->getSharedSecondLevelCacheDriverImpl()); $factory->getRegion(array( 'usage' => ClassMetadata::CACHE_USAGE_READ_WRITE, diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php b/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php index 8cc1c54ef..fd58fedc2 100644 --- a/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php @@ -53,7 +53,9 @@ class DefaultQueryCacheTest extends OrmTestCase $this->queryCache = new DefaultQueryCache($this->em, $this->region); $this->cacheFactory = new CacheFactoryDefaultQueryCacheTest($this->queryCache, $this->region); - $this->em->getConfiguration()->setSecondLevelCacheFactory($this->cacheFactory); + $this->em->getConfiguration() + ->getSecondLevelCacheConfiguration() + ->setCacheFactory($this->cacheFactory); } public function testImplementQueryCache() diff --git a/tests/Doctrine/Tests/ORM/ConfigurationTest.php b/tests/Doctrine/Tests/ORM/ConfigurationTest.php index 1530a05a3..bd8e90d8a 100644 --- a/tests/Doctrine/Tests/ORM/ConfigurationTest.php +++ b/tests/Doctrine/Tests/ORM/ConfigurationTest.php @@ -276,16 +276,13 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase /** * @group DDC-2183 */ - public function testSetGetSecondLevelCacheClassName() + public function testSetGetSecondLevelCacheConfig() { - $mockClass = get_class($this->getMock('Doctrine\ORM\Cache')); + $mockClass = $this->getMock('Doctrine\ORM\Cache\CacheConfiguration'); - $this->assertEquals('Doctrine\ORM\Cache\DefaultCache', $this->configuration->getSecondLevelCacheClassName()); - $this->configuration->setSecondLevelCacheClassName($mockClass); - $this->assertEquals($mockClass, $this->configuration->getSecondLevelCacheClassName()); - - $this->setExpectedException('Doctrine\ORM\ORMException'); - $this->configuration->setSecondLevelCacheClassName(__CLASS__); + $this->assertNull($this->configuration->getSecondLevelCacheConfiguration()); + $this->configuration->setSecondLevelCacheConfiguration($mockClass); + $this->assertEquals($mockClass, $this->configuration->getSecondLevelCacheConfiguration()); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php index ed35992c8..4297e147a 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php @@ -31,7 +31,9 @@ class SecondLevelCacheConcurrentTest extends SecondLevelCacheAbstractTest $this->cacheFactory = new CacheFactorySecondLevelCacheConcurrentTest($this->getSharedSecondLevelCacheDriverImpl()); - $this->_em->getConfiguration()->setSecondLevelCacheFactory($this->cacheFactory); + $this->_em->getConfiguration() + ->getSecondLevelCacheConfiguration() + ->setCacheFactory($this->cacheFactory); $this->countryMetadata = $this->_em->getClassMetadata(Country::CLASSNAME); $countryMetadata = clone $this->countryMetadata; diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index dba7bd09f..aa6c063a8 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -448,18 +448,20 @@ abstract class OrmFunctionalTestCase extends OrmTestCase if ($this->isSecondLevelCacheEnabled || $enableSecondLevelCache) { - $cache = $this->getSharedSecondLevelCacheDriverImpl(); - $factory = new DefaultCacheFactory($config, $cache); + $cacheConfig = new \Doctrine\ORM\Cache\CacheConfiguration(); + $cache = $this->getSharedSecondLevelCacheDriverImpl(); + $factory = new DefaultCacheFactory($cacheConfig->getRegionsConfiguration(), $cache); $this->secondLevelCacheFactory = $factory; if ($this->isSecondLevelCacheLogEnabled) { - $this->secondLevelCacheLogger = new StatisticsCacheLogger(); - $config->setSecondLevelCacheLogger($this->secondLevelCacheLogger); + $this->secondLevelCacheLogger = new StatisticsCacheLogger(); + $cacheConfig->setCacheLogger($this->secondLevelCacheLogger); } - - $config->setSecondLevelCacheEnabled(); - $config->setSecondLevelCacheFactory($factory); + + $cacheConfig->setCacheFactory($factory); + $config->setSecondLevelCacheEnabled(true); + $config->setSecondLevelCacheConfiguration($cacheConfig); $this->isSecondLevelCacheEnabled = true; } diff --git a/tests/Doctrine/Tests/OrmTestCase.php b/tests/Doctrine/Tests/OrmTestCase.php index 541e094a3..8546fae03 100644 --- a/tests/Doctrine/Tests/OrmTestCase.php +++ b/tests/Doctrine/Tests/OrmTestCase.php @@ -127,13 +127,16 @@ abstract class OrmTestCase extends DoctrineTestCase ), true)); if ($this->isSecondLevelCacheEnabled) { - $cache = $this->getSharedSecondLevelCacheDriverImpl(); - $factory = new DefaultCacheFactory($config, $cache); + + $cacheConfig = new \Doctrine\ORM\Cache\CacheConfiguration(); + $cache = $this->getSharedSecondLevelCacheDriverImpl(); + $factory = new DefaultCacheFactory($cacheConfig->getRegionsConfiguration(), $cache); $this->secondLevelCacheFactory = $factory; - $config->setSecondLevelCacheEnabled(); - $config->setSecondLevelCacheFactory($factory); + $cacheConfig->setCacheFactory($factory); + $config->setSecondLevelCacheEnabled(true); + $config->setSecondLevelCacheConfiguration($cacheConfig); } if ($conn === null) {