Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions docs/en/reference/caching.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,13 @@ the default cache instance:
new QueryCacheProfile(0, "some key", $cache);

In order for the data to actually be cached its necessary to ensure that the entire
result set is read (the easiest way to ensure this is to use ``fetchAll``) and the statement
object is closed:
result set is read (the easiest way to ensure this is to use one of the ``fetchAll*()`` methods):

::

<?php
$stmt = $conn->executeCacheQuery($query, $params, $types, new QueryCacheProfile(0, "some key"));
$data = $stmt->fetchAllAssociative();
$stmt->closeCursor(); // at this point the result is cached

.. warning::

Expand Down
50 changes: 24 additions & 26 deletions lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
/** @var ResultStatement */
private $statement;

/**
* Did we reach the end of the statement?
*
* @var bool
*/
private $emptied = false;

/** @var array<int,array<string,mixed>> */
/** @var array<int,array<string,mixed>>|null */
private $data;

/** @var int */
Expand All @@ -83,19 +76,8 @@ public function __construct(ResultStatement $stmt, Cache $resultCache, $cacheKey
public function closeCursor()
{
$this->statement->closeCursor();
if (! $this->emptied || $this->data === null) {
return true;
}

$data = $this->resultCache->fetch($this->cacheKey);
if (! $data) {
$data = [];
}

$data[$this->realKey] = $this->data;

$this->resultCache->save($this->cacheKey, $data, $this->lifetime);
unset($this->data);
$this->data = null;

return true;
}
Expand Down Expand Up @@ -169,7 +151,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
throw new InvalidArgumentException('Invalid fetch-style given for caching result.');
}

$this->emptied = true;
$this->saveToCache();

return false;
}
Expand All @@ -183,8 +165,9 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n
{
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE, $fetchArgument, $ctorArgs);

$this->data = $data;
$this->emptied = true;
$this->data = $data;

$this->saveToCache();

if ($fetchMode === FetchMode::NUMERIC) {
foreach ($data as $i => $row) {
Expand Down Expand Up @@ -327,7 +310,7 @@ private function doFetch()
return $row;
}

$this->emptied = true;
$this->saveToCache();

return false;
}
Expand All @@ -337,7 +320,22 @@ private function doFetch()
*/
private function store(array $data): void
{
$this->data = $data;
$this->emptied = true;
$this->data = $data;
}

private function saveToCache(): void
{
if ($this->data === null) {
return;
}

$data = $this->resultCache->fetch($this->cacheKey);
if (! $data) {
$data = [];
}

$data[$this->realKey] = $this->data;

$this->resultCache->save($this->cacheKey, $data, $this->lifetime);
}
}
13 changes: 3 additions & 10 deletions tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ private function assertStandardAndIteratorFetchAreEqual(int $fetchMode): void
self::assertEquals($data, $dataIterator);
}

public function testDontCloseNoCache(): void
public function testFetchAndFinishSavesCache(): void
{
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));

Expand All @@ -153,15 +153,14 @@ public function testDontCloseNoCache(): void
$data[] = $row;
}

self::assertCount(2, $this->sqlLogger->queries);
self::assertCount(1, $this->sqlLogger->queries);
}

public function testDontFinishNoCache(): void
{
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));

$stmt->fetch(FetchMode::ASSOCIATIVE);
$stmt->closeCursor();

$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));

Expand All @@ -170,12 +169,11 @@ public function testDontFinishNoCache(): void
self::assertCount(2, $this->sqlLogger->queries);
}

public function testFetchAllAndFinishSavesCache(): void
public function testFetchAllSavesCache(): void
{
$layerCache = new ArrayCache();
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(0, 'testcachekey', $layerCache));
$stmt->fetchAll();
$stmt->closeCursor();

self::assertCount(1, $layerCache->fetch('testcachekey'));
}
Expand All @@ -189,7 +187,6 @@ public function testFetchAllColumn(): void

$stmt = $this->connection->executeCacheQuery($query, [], [], $qcp);
$stmt->fetchAll(FetchMode::COLUMN);
$stmt->closeCursor();

$stmt = $this->connection->executeCacheQuery($query, [], [], $qcp);

Expand Down Expand Up @@ -251,8 +248,6 @@ private function hydrateStmt(ResultStatement $stmt, int $fetchMode = FetchMode::
$data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
}

$stmt->closeCursor();

return $data;
}

Expand All @@ -267,8 +262,6 @@ private function hydrateStmtIterator(ResultStatement $stmt, int $fetchMode = Fet
$data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
}

$stmt->closeCursor();

return $data;
}
}