Make caching layer not rely on closeCursor()

parent 08dbcfb9
...@@ -35,15 +35,13 @@ the default cache instance: ...@@ -35,15 +35,13 @@ the default cache instance:
new QueryCacheProfile(0, "some key", $cache); new QueryCacheProfile(0, "some key", $cache);
In order for the data to actually be cached its necessary to ensure that the entire 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 result set is read (the easiest way to ensure this is to use one of the ``fetchAll*()`` methods):
object is closed:
:: ::
<?php <?php
$stmt = $conn->executeCacheQuery($query, $params, $types, new QueryCacheProfile(0, "some key")); $stmt = $conn->executeCacheQuery($query, $params, $types, new QueryCacheProfile(0, "some key"));
$data = $stmt->fetchAllAssociative(); $data = $stmt->fetchAllAssociative();
$stmt->closeCursor(); // at this point the result is cached
.. warning:: .. warning::
......
...@@ -50,14 +50,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -50,14 +50,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
/** @var ResultStatement */ /** @var ResultStatement */
private $statement; private $statement;
/** /** @var array<int,array<string,mixed>>|null */
* Did we reach the end of the statement?
*
* @var bool
*/
private $emptied = false;
/** @var array<int,array<string,mixed>> */
private $data; private $data;
/** @var int */ /** @var int */
...@@ -83,19 +76,8 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -83,19 +76,8 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
public function closeCursor() public function closeCursor()
{ {
$this->statement->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->data = null;
$this->resultCache->save($this->cacheKey, $data, $this->lifetime);
unset($this->data);
return true; return true;
} }
...@@ -169,7 +151,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -169,7 +151,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
throw new InvalidArgumentException('Invalid fetch-style given for caching result.'); throw new InvalidArgumentException('Invalid fetch-style given for caching result.');
} }
$this->emptied = true; $this->saveToCache();
return false; return false;
} }
...@@ -183,8 +165,9 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -183,8 +165,9 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
{ {
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE, $fetchArgument, $ctorArgs); $data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE, $fetchArgument, $ctorArgs);
$this->data = $data; $this->data = $data;
$this->emptied = true;
$this->saveToCache();
if ($fetchMode === FetchMode::NUMERIC) { if ($fetchMode === FetchMode::NUMERIC) {
foreach ($data as $i => $row) { foreach ($data as $i => $row) {
...@@ -327,7 +310,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -327,7 +310,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
return $row; return $row;
} }
$this->emptied = true; $this->saveToCache();
return false; return false;
} }
...@@ -337,7 +320,22 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -337,7 +320,22 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
*/ */
private function store(array $data): void private function store(array $data): void
{ {
$this->data = $data; $this->data = $data;
$this->emptied = true; }
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);
} }
} }
...@@ -135,7 +135,7 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -135,7 +135,7 @@ class ResultCacheTest extends DbalFunctionalTestCase
self::assertEquals($data, $dataIterator); 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')); $stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
...@@ -153,7 +153,7 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -153,7 +153,7 @@ class ResultCacheTest extends DbalFunctionalTestCase
$data[] = $row; $data[] = $row;
} }
self::assertCount(2, $this->sqlLogger->queries); self::assertCount(1, $this->sqlLogger->queries);
} }
public function testDontFinishNoCache(): void public function testDontFinishNoCache(): void
...@@ -161,7 +161,6 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -161,7 +161,6 @@ class ResultCacheTest extends DbalFunctionalTestCase
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey')); $stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$stmt->fetch(FetchMode::ASSOCIATIVE); $stmt->fetch(FetchMode::ASSOCIATIVE);
$stmt->closeCursor();
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey')); $stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
...@@ -170,12 +169,11 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -170,12 +169,11 @@ class ResultCacheTest extends DbalFunctionalTestCase
self::assertCount(2, $this->sqlLogger->queries); self::assertCount(2, $this->sqlLogger->queries);
} }
public function testFetchAllAndFinishSavesCache(): void public function testFetchAllSavesCache(): void
{ {
$layerCache = new ArrayCache(); $layerCache = new ArrayCache();
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(0, 'testcachekey', $layerCache)); $stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(0, 'testcachekey', $layerCache));
$stmt->fetchAll(); $stmt->fetchAll();
$stmt->closeCursor();
self::assertCount(1, $layerCache->fetch('testcachekey')); self::assertCount(1, $layerCache->fetch('testcachekey'));
} }
...@@ -189,7 +187,6 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -189,7 +187,6 @@ class ResultCacheTest extends DbalFunctionalTestCase
$stmt = $this->connection->executeCacheQuery($query, [], [], $qcp); $stmt = $this->connection->executeCacheQuery($query, [], [], $qcp);
$stmt->fetchAll(FetchMode::COLUMN); $stmt->fetchAll(FetchMode::COLUMN);
$stmt->closeCursor();
$stmt = $this->connection->executeCacheQuery($query, [], [], $qcp); $stmt = $this->connection->executeCacheQuery($query, [], [], $qcp);
...@@ -251,8 +248,6 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -251,8 +248,6 @@ class ResultCacheTest extends DbalFunctionalTestCase
$data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row; $data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
} }
$stmt->closeCursor();
return $data; return $data;
} }
...@@ -267,8 +262,6 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -267,8 +262,6 @@ class ResultCacheTest extends DbalFunctionalTestCase
$data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row; $data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
} }
$stmt->closeCursor();
return $data; return $data;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment