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
24 changes: 1 addition & 23 deletions docs/en/reference/caching.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
Caching
=======

A ``Doctrine\DBAL\Statement`` can automatically cache result sets. The
A ``Doctrine\DBAL\Connection`` can automatically cache result sets. The
feature is optional though, and by default, no result set is cached.

To use the result cache, there are three mandatory steps:

1. Configure a global result cache, or provide one at query time.
2. Provide a cache profile for the result set you want to cache when
making a query.
3. Read the entire result set from the database.

Configuring the result cache
----------------------------
Expand Down Expand Up @@ -53,24 +52,3 @@ default cache instance:
<?php
$cache = new \Symfony\Component\Cache\Adapter\FilesystemAdapter();
new QueryCacheProfile(0, "some key", $cache);

Reading the entire result set
-----------------------------

Caching half a result set would cause bugs if a subsequent caller needed
more rows from that same result sets. To be able to cache the entire
result set, it must be fetched entirely from the database, and not all
APIs do that. The easiest way to ensure that is to use one of the
``fetchAll*()`` methods:

::

<?php
$stmt = $conn->executeCacheQuery($query, $params, $types, new QueryCacheProfile(0, "some key"));
$data = $stmt->fetchAllAssociative();

.. warning::

When using the cache layer not all fetch modes are supported. See
the code of the ``Doctrine\DBAL\Cache\CachingResult`` for
details.
5 changes: 0 additions & 5 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@
is no longer supported.
-->
<file name="src/Tools/Console/ConsoleRunner.php"/>
<!--
This suppression should be removed once Doctrine Cache
is no longer supported.
-->
<file name="tests/Functional/ResultCacheTest.php"/>
<!--
This suppression should be removed in 4.0.0.
-->
Expand Down
185 changes: 0 additions & 185 deletions src/Cache/CachingResult.php

This file was deleted.

35 changes: 17 additions & 18 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Cache\ArrayResult;
use Doctrine\DBAL\Cache\CacheException;
use Doctrine\DBAL\Cache\CachingResult;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Driver\API\ExceptionConverter;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
Expand All @@ -28,7 +27,6 @@
use Throwable;
use Traversable;

use function array_key_exists;
use function assert;
use function count;
use function get_class;
Expand Down Expand Up @@ -1066,30 +1064,31 @@ public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp)

[$cacheKey, $realKey] = $qcp->generateCacheKeys($sql, $params, $types, $connectionParams);

// fetch the row pointers entry
$item = $resultCache->getItem($cacheKey);

if ($item->isHit()) {
$data = $item->get();
// is the real key part of this row pointers map or is the cache only pointing to other cache keys?
if (isset($data[$realKey])) {
$result = new ArrayResult($data[$realKey]);
} elseif (array_key_exists($realKey, $data)) {
$result = new ArrayResult([]);
$value = $item->get();
if (isset($value[$realKey])) {
return new Result(new ArrayResult($value[$realKey]), $this);
}
} else {
$value = [];
}

if (! isset($result)) {
$result = new CachingResult(
$this->executeQuery($sql, $params, $types),
$resultCache,
$cacheKey,
$realKey,
$qcp->getLifetime()
);
$data = $this->fetchAllAssociative($sql, $params, $types);

$value[$realKey] = $data;

$item->set($value);

$lifetime = $qcp->getLifetime();
if ($lifetime > 0) {
$item->expiresAfter($lifetime);
}

return new Result($result, $this);
$resultCache->save($item);

return new Result(new ArrayResult($data), $this);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

use const CASE_LOWER;

class ResultCacheTest extends FunctionalTestCase
class QueryCacheTest extends FunctionalTestCase
{
/** @var list<array{test_int: int, test_string: string}> */
private $expectedResult = [
Expand Down Expand Up @@ -156,7 +156,7 @@ public function testFetchViaIteration(callable $fetch, callable $fetchAll): void
self::assertEquals($data, $dataIterator);
}

public function testFetchAndFinishSavesCache(): void
public function testFetchSavesCache(): void
{
$result = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
Expand All @@ -179,31 +179,6 @@ public function testFetchAndFinishSavesCache(): void
self::assertCount(1, $this->sqlLogger->queries, 'Only one query has hit the database.');
}

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

$result->fetchAssociative();

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

$this->hydrateViaIteration($result, static function (Result $result) {
return $result->fetchNumeric();
});

self::assertCount(2, $this->sqlLogger->queries, 'Two queries have hit the database.');
}

/**
* @dataProvider fetchAllProvider
*/
Expand Down