From e71272e2b4e1f13318adfb1b16cc09c2e25ae70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Cobucci?= Date: Sun, 30 Apr 2017 21:12:40 +0200 Subject: [PATCH] Evict result set cache if Query#expireResultCache() was called --- lib/Doctrine/ORM/Query.php | 19 +++++++++++ tests/Doctrine/Tests/ORM/Query/QueryTest.php | 33 ++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php index 12fb3f560..9a5ded2c7 100644 --- a/lib/Doctrine/ORM/Query.php +++ b/lib/Doctrine/ORM/Query.php @@ -20,6 +20,7 @@ namespace Doctrine\ORM; use Doctrine\DBAL\LockMode; +use Doctrine\ORM\Query\Exec\AbstractSqlExecutor; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\ParserResult; use Doctrine\ORM\Query\QueryException; @@ -322,9 +323,27 @@ final class Query extends AbstractQuery list($sqlParams, $types) = $this->processParameterMappings($paramMappings); + $this->evictResultSetCache($executor, $sqlParams, $types); + return $executor->execute($this->_em->getConnection(), $sqlParams, $types); } + private function evictResultSetCache(AbstractSqlExecutor $executor, array $sqlParams, array $types) + { + if (null === $this->_queryCacheProfile || ! $this->getExpireResultCache()) { + return; + } + + $cacheDriver = $this->_queryCacheProfile->getResultCacheDriver(); + $statements = (array) $executor->getSqlStatements(); // Type casted since it can either be a string or an array + + foreach ($statements as $statement) { + $cacheKeys = $this->_queryCacheProfile->generateCacheKeys($statement, $sqlParams, $types); + + $cacheDriver->delete(reset($cacheKeys)); + } + } + /** * Evict entity cache region */ diff --git a/tests/Doctrine/Tests/ORM/Query/QueryTest.php b/tests/Doctrine/Tests/ORM/Query/QueryTest.php index 9b8f24d40..6b0091e9c 100644 --- a/tests/Doctrine/Tests/ORM/Query/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Query/QueryTest.php @@ -243,4 +243,37 @@ class QueryTest extends OrmTestCase $query->setHydrationCacheProfile(null); $this->assertNull($query->getHydrationCacheProfile()); } + + /** + * @group 2947 + */ + public function testResultCacheEviction() + { + $this->_em->getConfiguration()->setResultCacheImpl(new ArrayCache()); + + $query = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u") + ->useResultCache(true); + + /** @var DriverConnectionMock $driverConnectionMock */ + $driverConnectionMock = $this->_em->getConnection() + ->getWrappedConnection(); + + $driverConnectionMock->setStatementMock(new StatementArrayMock([['id_0' => 1]])); + + // Performs the query and sets up the initial cache + self::assertCount(1, $query->getResult()); + + $driverConnectionMock->setStatementMock(new StatementArrayMock([['id_0' => 1], ['id_0' => 2]])); + + // Retrieves cached data since expire flag is false and we have a cached result set + self::assertCount(1, $query->getResult()); + + // Performs the query and caches the result set since expire flag is true + self::assertCount(2, $query->expireResultCache(true)->getResult()); + + $driverConnectionMock->setStatementMock(new StatementArrayMock([['id_0' => 1]])); + + // Retrieves cached data since expire flag is false and we have a cached result set + self::assertCount(2, $query->expireResultCache(false)->getResult()); + } }