Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[DDC-1766] Initial implementation of hydration cache. #329

Merged
merged 9 commits into from

4 participants

@beberlei
Owner

No description provided.

@guilhermeblanco guilhermeblanco commented on the diff
lib/Doctrine/ORM/AbstractQuery.php
@@ -21,7 +21,8 @@
use Doctrine\DBAL\Types\Type,
@guilhermeblanco Owner

Is it possible for us to split the "use"s in logical blocks? Like Doctrine\DBAL and Doctrine\ORM ones?

@Ocramius Owner
Ocramius added a note

Also (not very important right now) PSR-1 says one use statement per row.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((15 lines not shown))
+ * @example
+ * $lifetime = 100;
+ * $resultKey = "abc";
+ * $query->setHydrationCacheProfile(new QueryCacheProfile());
+ * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
+ *
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+ * @return \Doctrine\ORM\AbstractQuery
+ */
+ public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
+ {
+ if ( ! $profile->getResultCacheDriver()) {
+ $profile = $profile->setResultCacheDriver($this->_em->getConfiguration()->getResultCacheImpl());
+ }
+
+ $this->_hydrationCacheProfile = $profile;
@guilhermeblanco Owner

Add a line space between assignments and control structures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((12 lines not shown))
+ * some form of caching with UnitOfWork registration you should use
+ * {@see AbstractQuery::setResultCacheProfile()}.
+ *
+ * @example
+ * $lifetime = 100;
+ * $resultKey = "abc";
+ * $query->setHydrationCacheProfile(new QueryCacheProfile());
+ * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
+ *
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+ * @return \Doctrine\ORM\AbstractQuery
+ */
+ public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
+ {
+ if ( ! $profile->getResultCacheDriver()) {
+ $profile = $profile->setResultCacheDriver($this->_em->getConfiguration()->getResultCacheImpl());
@guilhermeblanco Owner

Split the operation in 2 lines:

$resultCache = $this->_em->getConfiguration()->getResultCacheImpl();
$profile     = $profile->setResultCacheDriver($resultCache);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((42 lines not shown))
+ /**
+ * Set a cache profile for the result cache.
+ *
+ * If no result cache driver is set in the QueryCacheProfile, the default
+ * result cache driver is used from the configuration.
+ *
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+ * @return \Doctrine\ORM\AbstractQuery
+ */
+ public function setResultCacheProfile(QueryCacheProfile $profile = null)
+ {
+ if ( ! $profile->getResultCacheDriver()) {
+ $profile = $profile->setResultCacheDriver($this->_em->getConfiguration()->getResultCacheImpl());
+ }
+
+ $this->_queryCacheProfile = $profile;
@guilhermeblanco Owner

Line space between assignments and control structures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((39 lines not shown))
+ return $this->_hydrationCacheProfile;
+ }
+
+ /**
+ * Set a cache profile for the result cache.
+ *
+ * If no result cache driver is set in the QueryCacheProfile, the default
+ * result cache driver is used from the configuration.
+ *
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+ * @return \Doctrine\ORM\AbstractQuery
+ */
+ public function setResultCacheProfile(QueryCacheProfile $profile = null)
+ {
+ if ( ! $profile->getResultCacheDriver()) {
+ $profile = $profile->setResultCacheDriver($this->_em->getConfiguration()->getResultCacheImpl());
@guilhermeblanco Owner

Split the operation in 2 lines:

$resultCache = $this->_em->getConfiguration()->getResultCacheImpl();
$profile     = $profile->setResultCacheDriver($resultCache);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@guilhermeblanco guilhermeblanco commented on the diff
lib/Doctrine/ORM/AbstractQuery.php
@@ -644,15 +708,73 @@ public function execute($params = array(), $hydrationMode = null)
$this->setParameters($params);
}
+ $setCacheEntry = function() {};
@guilhermeblanco Owner

Line space between assignment and control structures.

@guilhermeblanco Owner

WTH is that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
@@ -644,15 +708,73 @@ public function execute($params = array(), $hydrationMode = null)
$this->setParameters($params);
}
+ $setCacheEntry = function() {};
+ if ($this->_hydrationCacheProfile !== null) {
+ list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
+
+ $qcp = $this->getHydrationCacheProfile();
@guilhermeblanco Owner

Align the assignment blocks "=" signs for better code readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
@@ -644,15 +708,73 @@ public function execute($params = array(), $hydrationMode = null)
$this->setParameters($params);
}
+ $setCacheEntry = function() {};
+ if ($this->_hydrationCacheProfile !== null) {
+ list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
+
+ $qcp = $this->getHydrationCacheProfile();
+ $cache = $qcp->getResultCacheDriver();
+
+ $result = $cache->fetch($cacheKey);
@guilhermeblanco Owner

This LOC is locally part of the previous block. Remove the line space previous to this line and add one after.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@guilhermeblanco guilhermeblanco commented on the diff
lib/Doctrine/ORM/AbstractQuery.php
((26 lines not shown))
$stmt = $this->_doExecute();
if (is_numeric($stmt)) {
+ $setCacheEntry($stmt);
@guilhermeblanco Owner

Line space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@guilhermeblanco guilhermeblanco commented on the diff
lib/Doctrine/ORM/AbstractQuery.php
((37 lines not shown))
+
+ $setCacheEntry($data);
+
+ return $data;
+ }
+
+ /**
+ * Get the result cache id to use to store the result set cache entry.
+ * Will return the configured id if it exists otherwise a hash will be
+ * automatically generated for you.
+ *
+ * @return array ($key, $hash)
+ */
+ protected function getHydrationCacheId()
+ {
+ $params = $this->getParameters();
@guilhermeblanco Owner

Line space between assignment and control structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((39 lines not shown))
+
+ return $data;
+ }
+
+ /**
+ * Get the result cache id to use to store the result set cache entry.
+ * Will return the configured id if it exists otherwise a hash will be
+ * automatically generated for you.
+ *
+ * @return array ($key, $hash)
+ */
+ protected function getHydrationCacheId()
+ {
+ $params = $this->getParameters();
+ foreach ($params AS $key => $value) {
+ if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
@guilhermeblanco Owner

Early return can be applied here to reduce one indentation level.

foreach (...) {
    if ( ! (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value)))) {
        continue;
    }

    // ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@guilhermeblanco guilhermeblanco commented on the diff
lib/Doctrine/ORM/AbstractQuery.php
((37 lines not shown))
$stmt, $this->_resultSetMapping, $this->_hints
);
+
+ $setCacheEntry($data);
+
+ return $data;
+ }
+
+ /**
+ * Get the result cache id to use to store the result set cache entry.
+ * Will return the configured id if it exists otherwise a hash will be
+ * automatically generated for you.
+ *
+ * @return array ($key, $hash)
+ */
@guilhermeblanco Owner

I'd rather encapsulate this block in a separate function.

protected function getEntityIdentifierValueList($entity)
{
    $unitOfWork = $this->_em->getUnitOfWork();

    if ($unitOfWork->getEntityState($entity) === UnitOfWork::STATE_MANAGED) {
        return $unitOfWork->getEntityIdentifier($entity);
    }

    $classMetadata = $this->_em->getClassMetadata(get_class($entity));

    return $classMetadata->getIdentifierValues($entity);
}

Then just reuse it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((46 lines not shown))
+ * Get the result cache id to use to store the result set cache entry.
+ * Will return the configured id if it exists otherwise a hash will be
+ * automatically generated for you.
+ *
+ * @return array ($key, $hash)
+ */
+ protected function getHydrationCacheId()
+ {
+ $params = $this->getParameters();
+
+ foreach ($params AS $key => $value) {
+ if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
+ if ($this->_em->getUnitOfWork()->getEntityState($value) == UnitOfWork::STATE_MANAGED) {
+ $idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+ } else {
+ $class = $this->_em->getClassMetadata(get_class($value));
@guilhermeblanco Owner

Align "=" signs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((49 lines not shown))
+ *
+ * @return array ($key, $hash)
+ */
+ protected function getHydrationCacheId()
+ {
+ $params = $this->getParameters();
+
+ foreach ($params AS $key => $value) {
+ if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
+ if ($this->_em->getUnitOfWork()->getEntityState($value) == UnitOfWork::STATE_MANAGED) {
+ $idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+ } else {
+ $class = $this->_em->getClassMetadata(get_class($value));
+ $idValues = $class->getIdentifierValues($value);
+ }
+ $params[$key] = $idValues;
@guilhermeblanco Owner

Line space before

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((51 lines not shown))
+ */
+ protected function getHydrationCacheId()
+ {
+ $params = $this->getParameters();
+
+ foreach ($params AS $key => $value) {
+ if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
+ if ($this->_em->getUnitOfWork()->getEntityState($value) == UnitOfWork::STATE_MANAGED) {
+ $idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
+ } else {
+ $class = $this->_em->getClassMetadata(get_class($value));
+ $idValues = $class->getIdentifierValues($value);
+ }
+ $params[$key] = $idValues;
+ }
+ }
@guilhermeblanco Owner

Do not abbreviate. What's qcp? Quebec Cops Party?

@Ocramius Owner
Ocramius added a note

I lol'd hard X°D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/AbstractQuery.php
((12 lines not shown))
+ * some form of caching with UnitOfWork registration you should use
+ * {@see AbstractQuery::setResultCacheProfile()}.
+ *
+ * @example
+ * $lifetime = 100;
+ * $resultKey = "abc";
+ * $query->setHydrationCacheProfile(new QueryCacheProfile());
+ * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
+ *
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+ * @return \Doctrine\ORM\AbstractQuery
+ */
+ public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
+ {
+ if ( ! $profile->getResultCacheDriver()) {
+ $resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl();
@stof
stof added a note

is it expected to use the ResultCache implementation for the hydration cache too ? Currently the place using caching in the ORM are using separate cache implementations

@Ocramius Owner
Ocramius added a note

Indeed, a $hydrationCacheDriver could be a nice addition to Doctrine\ORM\Configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@Ocramius Ocramius commented on the diff
lib/Doctrine/ORM/AbstractQuery.php
@@ -102,6 +103,11 @@
protected $_expireResultCache = false;
/**
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile
+ */
+ protected $_hydrationCacheProfile;
@Ocramius Owner
Ocramius added a note

Just wondering about the _. When will this be dropped?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@beberlei
Owner

@guilhermeblanco please see last commit 0b3577f and merge if everything ok now. From me this is finished, and then i rebase this into 2.2

@guilhermeblanco

@beberlei seems perfect! Feel free to merge! =D

@guilhermeblanco guilhermeblanco merged commit a5c13a5 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
126 lib/Doctrine/ORM/AbstractQuery.php
@@ -20,8 +20,9 @@
namespace Doctrine\ORM;
use Doctrine\DBAL\Types\Type,
@guilhermeblanco Owner

Is it possible for us to split the "use"s in logical blocks? Like Doctrine\DBAL and Doctrine\ORM ones?

@Ocramius Owner
Ocramius added a note

Also (not very important right now) PSR-1 says one use statement per row.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ Doctrine\DBAL\Cache\QueryCacheProfile,
Doctrine\ORM\Query\QueryException,
- Doctrine\DBAL\Cache\QueryCacheProfile;
+ Doctrine\ORM\Internal\Hydration\CacheHydrator;
/**
* Base contract for ORM queries. Base class for Query and NativeQuery.
@@ -29,7 +30,6 @@
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
- * @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
@@ -102,6 +102,11 @@
protected $_expireResultCache = false;
/**
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile
+ */
+ protected $_hydrationCacheProfile;
@Ocramius Owner
Ocramius added a note

Just wondering about the _. When will this be dropped?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ /**
* Initializes a new instance of a class derived from <tt>AbstractQuery</tt>.
*
* @param \Doctrine\ORM\EntityManager $entityManager
@@ -300,6 +305,68 @@ public function setResultSetMapping(Query\ResultSetMapping $rsm)
}
/**
+ * Set a cache profile for hydration caching.
+ *
+ * If no result cache driver is set in the QueryCacheProfile, the default
+ * result cache driver is used from the configuration.
+ *
+ * Important: Hydration caching does NOT register entities in the
+ * UnitOfWork when retrieved from the cache. Never use result cached
+ * entities for requests that also flush the EntityManager. If you want
+ * some form of caching with UnitOfWork registration you should use
+ * {@see AbstractQuery::setResultCacheProfile()}.
+ *
+ * @example
+ * $lifetime = 100;
+ * $resultKey = "abc";
+ * $query->setHydrationCacheProfile(new QueryCacheProfile());
+ * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
+ *
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+ * @return \Doctrine\ORM\AbstractQuery
+ */
+ public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
+ {
+ if ( ! $profile->getResultCacheDriver()) {
+ $resultCacheDriver = $this->_em->getConfiguration()->getHydrationCacheImpl();
+ $profile = $profile->setResultCacheDriver($resultCacheDriver);
+ }
+
+ $this->_hydrationCacheProfile = $profile;
+
+ return $this;
+ }
+
+ /**
+ * @return \Doctrine\DBAL\Cache\QueryCacheProfile
+ */
+ public function getHydrationCacheProfile()
+ {
+ return $this->_hydrationCacheProfile;
+ }
+
+ /**
+ * Set a cache profile for the result cache.
+ *
+ * If no result cache driver is set in the QueryCacheProfile, the default
+ * result cache driver is used from the configuration.
+ *
+ * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
+ * @return \Doctrine\ORM\AbstractQuery
+ */
+ public function setResultCacheProfile(QueryCacheProfile $profile = null)
+ {
+ if ( ! $profile->getResultCacheDriver()) {
+ $resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl();
+ $profile = $profile->setResultCacheDriver($resultCacheDriver);
+ }
+
+ $this->_queryCacheProfile = $profile;
+
+ return $this;
+ }
+
+ /**
* Defines a cache driver to be used for caching result sets and implictly enables caching.
*
* @param \Doctrine\Common\Cache\Cache $driver Cache driver
@@ -644,15 +711,68 @@ public function execute($params = array(), $hydrationMode = null)
$this->setParameters($params);
}
+ $setCacheEntry = function() {};
@guilhermeblanco Owner

Line space between assignment and control structures.

@guilhermeblanco Owner

WTH is that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ if ($this->_hydrationCacheProfile !== null) {
+ list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
+
+ $queryCacheProfile = $this->getHydrationCacheProfile();
+ $cache = $queryCacheProfile->getResultCacheDriver();
+ $result = $cache->fetch($cacheKey);
+
+ if (isset($result[$realCacheKey])) {
+ return $result[$realCacheKey];
+ }
+
+ if ( ! $result) {
+ $result = array();
+ }
+
+ $setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
+ $result[$realCacheKey] = $data;
+ $cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
+ };
+ }
+
$stmt = $this->_doExecute();
if (is_numeric($stmt)) {
+ $setCacheEntry($stmt);
@guilhermeblanco Owner

Line space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
return $stmt;
}
- return $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
+ $data = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
$stmt, $this->_resultSetMapping, $this->_hints
);
+
+ $setCacheEntry($data);
+
+ return $data;
+ }
+
+ /**
+ * Get the result cache id to use to store the result set cache entry.
+ * Will return the configured id if it exists otherwise a hash will be
+ * automatically generated for you.
+ *
+ * @return array ($key, $hash)
+ */
@guilhermeblanco Owner

I'd rather encapsulate this block in a separate function.

protected function getEntityIdentifierValueList($entity)
{
    $unitOfWork = $this->_em->getUnitOfWork();

    if ($unitOfWork->getEntityState($entity) === UnitOfWork::STATE_MANAGED) {
        return $unitOfWork->getEntityIdentifier($entity);
    }

    $classMetadata = $this->_em->getClassMetadata(get_class($entity));

    return $classMetadata->getIdentifierValues($entity);
}

Then just reuse it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ protected function getHydrationCacheId()
+ {
+ $params = $this->getParameters();
@guilhermeblanco Owner

Line space between assignment and control structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ foreach ($params AS $key => $value) {
+ $params[$key] = $this->processParameterValue($value);
+ }
+
+ $sql = $this->getSQL();
+ $queryCacheProfile = $this->getHydrationCacheProfile();
+ $hints = $this->getHints();
+ $hints['hydrationMode'] = $this->getHydrationMode();
+ ksort($hints);
+
+ return $queryCacheProfile->generateCacheKeys($sql, $params, $hints);
}
/**
View
22 lib/Doctrine/ORM/Configuration.php
@@ -247,6 +247,28 @@ public function setQueryCacheImpl(Cache $cacheImpl)
}
/**
+ * Gets the cache driver implementation that is used for the hydration cache (SQL cache).
+ *
+ * @return \Doctrine\Common\Cache\Cache
+ */
+ public function getHydrationCacheImpl()
+ {
+ return isset($this->_attributes['hydrationCacheImpl'])
+ ? $this->_attributes['hydrationCacheImpl']
+ : null;
+ }
+
+ /**
+ * Sets the cache driver implementation that is used for the hydration cache (SQL cache).
+ *
+ * @param \Doctrine\Common\Cache\Cache $cacheImpl
+ */
+ public function setHydrationCacheImpl(Cache $cacheImpl)
+ {
+ $this->_attributes['hydrationCacheImpl'] = $cacheImpl;
+ }
+
+ /**
* Gets the cache driver implementation that is used for metadata caching.
*
* @return \Doctrine\Common\Cache\Cache
View
86 tests/Doctrine/Tests/ORM/Functional/HydrationCacheTest.php
@@ -0,0 +1,86 @@
+<?php
+namespace Doctrine\Tests\ORM\Functional;
+
+use Doctrine\Tests\OrmFunctionalTestCase;
+use Doctrine\Tests\Models\Cms\CmsUser;
+use Doctrine\DBAL\Cache\QueryCacheProfile;
+use Doctrine\Common\Cache\ArrayCache;
+
+/**
+ * @group DDC-1766
+ */
+class HydrationCacheTest extends OrmFunctionalTestCase
+{
+ public function setUp()
+ {
+ $this->useModelSet('cms');
+ parent::setUp();
+
+ $user = new CmsUser;
+ $user->name = "Benjamin";
+ $user->username = "beberlei";
+ $user->status = 'active';
+
+ $this->_em->persist($user);
+ $this->_em->flush();
+ $this->_em->clear();
+ }
+
+ public function testHydrationCache()
+ {
+ $cache = new ArrayCache();
+ $dql = "SELECT u FROM Doctrine\Tests\Models\Cms\CmsUser u";
+
+ $users = $this->_em->createQuery($dql)
+ ->setHydrationCacheProfile(new QueryCacheProfile(null, null, $cache))
+ ->getResult();
+
+ $c = $this->getCurrentQueryCount();
+ $users = $this->_em->createQuery($dql)
+ ->setHydrationCacheProfile(new QueryCacheProfile(null, null, $cache))
+ ->getResult();
+
+ $this->assertEquals($c, $this->getCurrentQueryCount(), "Should not execute query. Its cached!");
+
+ $users = $this->_em->createQuery($dql)
+ ->setHydrationCacheProfile(new QueryCacheProfile(null, null, $cache))
+ ->getArrayResult();
+
+ $this->assertEquals($c + 1, $this->getCurrentQueryCount(), "Hydration is part of cache key.");
+
+ $users = $this->_em->createQuery($dql)
+ ->setHydrationCacheProfile(new QueryCacheProfile(null, null, $cache))
+ ->getArrayResult();
+
+ $this->assertEquals($c + 1, $this->getCurrentQueryCount(), "Hydration now cached");
+
+ $users = $this->_em->createQuery($dql)
+ ->setHydrationCacheProfile(new QueryCacheProfile(null, 'cachekey', $cache))
+ ->getArrayResult();
+
+ $this->assertTrue($cache->contains('cachekey'), 'Explicit cache key');
+
+ $users = $this->_em->createQuery($dql)
+ ->setHydrationCacheProfile(new QueryCacheProfile(null, 'cachekey', $cache))
+ ->getArrayResult();
+ $this->assertEquals($c + 2, $this->getCurrentQueryCount(), "Hydration now cached");
+ }
+
+ public function testHydrationParametersSerialization()
+ {
+ $cache = new ArrayCache();
+ $user = new CmsUser();
+ $user->id = 1;
+
+ $dql = "SELECT u FROM Doctrine\Tests\Models\Cms\CmsUser u WHERE u.id = ?1";
+ $query = $this->_em->createQuery($dql)
+ ->setParameter(1, $user)
+ ->setHydrationCacheProfile(new QueryCacheProfile(null, null, $cache));
+
+ $query->getResult();
+ $c = $this->getCurrentQueryCount();
+ $query->getResult();
+ $this->assertEquals($c, $this->getCurrentQueryCount(), "Should not execute query. Its cached!");
+ }
+}
+
Something went wrong with that request. Please try again.