Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Commit

Permalink
Fix CS and update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
FabioBatSilva authored and fabios committed Dec 16, 2013
1 parent 1438a59 commit 61bff7d
Show file tree
Hide file tree
Showing 47 changed files with 338 additions and 187 deletions.
12 changes: 12 additions & 0 deletions docs/en/reference/annotations-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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>`
Expand Down Expand Up @@ -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
Expand Down
128 changes: 111 additions & 17 deletions docs/en/reference/second-level-cache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,39 @@ 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.
*
* @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
------------

Expand Down Expand Up @@ -226,16 +248,17 @@ 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);
//Enable second-level-cache
$config->setSecondLevelCacheEnabled();
//Cache factory
$config->setSecondLevelCacheFactory($factory);
$config->getSecondLevelCacheConfiguration()
->setCacheFactory($factory);
Cache Factory
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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::
Expand Down Expand Up @@ -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
---------
Expand Down Expand Up @@ -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);
Expand Down
50 changes: 28 additions & 22 deletions lib/Doctrine/ORM/AbstractQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
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;

Expand Down Expand Up @@ -127,7 +127,7 @@ abstract class AbstractQuery
*
* @var boolean
*/
protected $cacheable;
protected $cacheable = false;

/**
* Second level cache region name.
Expand Down Expand Up @@ -216,7 +216,7 @@ public function getCacheRegion()
}

/**
* @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()
{
Expand Down Expand Up @@ -340,7 +340,7 @@ public function setParameters($parameters)
$parameterCollection = new ArrayCollection();

foreach ($parameters as $key => $value) {
$parameter = new Query\Parameter($key, $value);
$parameter = new Parameter($key, $value);

$parameterCollection->add($parameter);
}
Expand Down Expand Up @@ -381,7 +381,7 @@ function ($parameter) use ($key)
return $this;
}

$parameter = new Query\Parameter($key, $value, $type);
$parameter = new Parameter($key, $value, $type);

$this->parameters->add($parameter);

Expand All @@ -395,10 +395,14 @@ function ($parameter) use ($key)
*
* @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);
Expand Down Expand Up @@ -889,7 +893,7 @@ public function iterate($parameters = null, $hydrationMode = null)
$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);
Expand Down Expand Up @@ -962,7 +966,7 @@ private function executeIgnoreQueryCache($parameters = null, $hydrationMode = nu
return $stmt;
}

$rsm = $this->_resultSetMapping ?: $this->getResultSetMapping();
$rsm = $this->getResultSetMapping();
$data = $this->_em->newHydrator($this->_hydrationMode)->hydrateAll($stmt, $rsm, $this->_hints);

$setCacheEntry($data);
Expand All @@ -980,13 +984,12 @@ private function executeIgnoreQueryCache($parameters = null, $hydrationMode = nu
*/
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);
}
Expand All @@ -995,14 +998,14 @@ private function executeUsingQueryCache($parameters = null, $hydrationMode = nul
}

$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;
Expand Down Expand Up @@ -1089,15 +1092,18 @@ public function __clone()
*/
protected function getHash()
{
$hints = $this->getHints();
$self = $this;
$query = $this->getSQL();
$params = array();

foreach ($this->parameters as $parameter) {
$value = $parameter->getValue();
$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;
}

$params[$parameter->getName()] = is_scalar($value) ? $value : $this->processParameterValue($value);
}
return $self->processParameterValue($value);
}, $this->parameters->getValues());

ksort($hints);

Expand Down
Loading

0 comments on commit 61bff7d

Please sign in to comment.