From 4cd7c50463a80bccfac190906fc4d2c3e0364386 Mon Sep 17 00:00:00 2001
From: Mathias Brodala <mbrodala@pagemachine.de>
Date: Tue, 30 Jun 2015 10:17:23 +0200
Subject: [PATCH] [BUGFIX] 1st level cache for ``QueryResult::count()``
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Counting the results of the ``QueryResultInterface`` proxy returned by
Repository finder methods always executed a ``COUNT query`` even if
the results had been fetched or counted already.

With this patch the number of results is cached as soon as the result
is initialized and/or counted once.

Resolves: #67837
Releases: master, 6.2
Change-Id: I98f680372b845f992ad3d436647b0cf5e460b606
Reviewed-on: http://review.typo3.org/40750
Reviewed-by: Stephan Großberndt <stephan@grossberndt.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
---
 .../Persistence/Generic/QueryResult.php        | 16 ++++++++++++----
 .../Persistence/Generic/QueryResultTest.php    | 18 ++++++++++++++++++
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php b/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
index 5059824aa36c..7ee1ba0d2bd4 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
@@ -35,6 +35,11 @@ class QueryResult implements QueryResultInterface {
 	 */
 	protected $persistenceManager;
 
+	/**
+	 * @var int|NULL
+	 */
+	protected $numberOfResults;
+
 	/**
 	 * @var \TYPO3\CMS\Extbase\Persistence\QueryInterface
 	 */
@@ -105,11 +110,14 @@ class QueryResult implements QueryResultInterface {
 	 * @api
 	 */
 	public function count() {
-		if (is_array($this->queryResult)) {
-			return count($this->queryResult);
-		} else {
-			return $this->persistenceManager->getObjectCountByQuery($this->query);
+		if ($this->numberOfResults === NULL) {
+			if (is_array($this->queryResult)) {
+				$this->numberOfResults = count($this->queryResult);
+			} else {
+				$this->numberOfResults = $this->persistenceManager->getObjectCountByQuery($this->query);
+			}
 		}
+		return $this->numberOfResults;
 	}
 
 	/**
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/QueryResultTest.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/QueryResultTest.php
index c91924723b04..be1e9a017f3f 100644
--- a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/QueryResultTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/QueryResultTest.php
@@ -129,6 +129,24 @@ class QueryResultTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 		$this->assertEquals(2, $queryResult->count());
 	}
 
+	/**
+	 * @test
+	 */
+	public function countCountsQueryResultDirectlyIfAlreadyInitialized() {
+		$this->mockPersistenceManager->expects($this->never())->method('getObjectCountByQuery');
+		$this->queryResult->toArray();
+		$this->assertEquals(2, $this->queryResult->count());
+	}
+
+	/**
+	 * @test
+	 */
+	public function countOnlyCallsGetObjectCountByQueryOnPersistenceManagerOnce() {
+		$this->mockPersistenceManager->expects($this->once())->method('getObjectCountByQuery')->will($this->returnValue(2));
+		$this->queryResult->count();
+		$this->assertEquals(2, $this->queryResult->count());
+	}
+
 	/**
 	 * @test
 	 */
-- 
GitLab