Skip to content

Commit

Permalink
Make sure the paginator does not put the same entries into the query …
Browse files Browse the repository at this point in the history
…cache repeatedly
  • Loading branch information
mpdude committed Jan 19, 2023
1 parent 8da741a commit fc7afd1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 29 deletions.
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Tools/Pagination/Paginator.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public function getIterator()
$whereInQuery->setFirstResult(0)->setMaxResults(null);
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
$whereInQuery->setCacheable($this->query->isCacheable());
$whereInQuery->expireQueryCache();
$whereInQuery->useQueryCache(false);

$result = $whereInQuery->getResult($this->query->getHydrationMode());
} else {
Expand Down
64 changes: 36 additions & 28 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/GH7820Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Tests\OrmFunctionalTestCase;
use PHPUnit\Framework\Assert;
use Psr\Cache\CacheItemInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;

use function array_map;
use function is_string;
Expand Down Expand Up @@ -69,51 +72,56 @@ protected function setUp(): void

public function testWillFindSongsInPaginator(): void
{
$query = $this->_em->getRepository(GH7820Line::class)
->createQueryBuilder('l')
->orderBy('l.lineNumber', Criteria::ASC)
->setMaxResults(100);
$lines = $this->fetchSongLinesWithPaginator();

self::assertSame(
self::SONG,
array_map(static function (GH7820Line $line): string {
return $line->toString();
}, iterator_to_array(new Paginator($query)))
);
self::assertSame(self::SONG, $lines);
}

/** @group GH7837 */
public function testWillFindSongsInPaginatorEvenWithCachedQueryParsing(): void
{
// Enable the query cache
$this->_em->getConfiguration()
->getQueryCache()
->clear();

$query = $this->_em->getRepository(GH7820Line::class)
->createQueryBuilder('l')
->orderBy('l.lineNumber', Criteria::ASC)
->setMaxResults(100);
// Fetch song lines with the paginator, also priming the query cache
$lines = $this->fetchSongLinesWithPaginator();
self::assertSame(self::SONG, $lines, 'Expected to return expected data before query cache is populated with DQL -> SQL translation. Were SQL parameters translated?');

self::assertSame(
self::SONG,
array_map(static function (GH7820Line $line): string {
return $line->toString();
}, iterator_to_array(new Paginator($query))),
'Expected to return expected data before query cache is populated with DQL -> SQL translation. Were SQL parameters translated?'
);
// Fetch song lines again
$lines = $this->fetchSongLinesWithPaginator();
self::assertSame(self::SONG, $lines, 'Expected to return expected data even when DQL -> SQL translation is present in cache. Were SQL parameters translated again?');
}

public function testPaginatorDoesNotForceCacheToUpdateEntries(): void
{
$this->_em->getConfiguration()->setQueryCache(new class extends ArrayAdapter {
public function save(CacheItemInterface $item): bool
{
Assert::assertFalse($this->hasItem($item->getKey()), 'The cache should not have to overwrite the entry');

return parent::save($item);
}
});

// "Prime" the cache (in fact, that should not even happen)
$this->fetchSongLinesWithPaginator();

// Make sure we can query again without overwriting the cache
$this->fetchSongLinesWithPaginator();
}

private function fetchSongLinesWithPaginator(): array
{
$query = $this->_em->getRepository(GH7820Line::class)
->createQueryBuilder('l')
->orderBy('l.lineNumber', Criteria::ASC)
->setMaxResults(100);

self::assertSame(
self::SONG,
array_map(static function (GH7820Line $line): string {
return $line->toString();
}, iterator_to_array(new Paginator($query))),
'Expected to return expected data even when DQL -> SQL translation is present in cache. Were SQL parameters translated again?'
);
return array_map(static function (GH7820Line $line): string {
return $line->toString();
}, iterator_to_array(new Paginator($query)));
}
}

Expand Down

0 comments on commit fc7afd1

Please sign in to comment.