[BUGFIX] 1st level cache for ``QueryResult::count()`` 50/40750/4
authorMathias Brodala <mbrodala@pagemachine.de>
Tue, 30 Jun 2015 08:17:23 +0000 (10:17 +0200)
committerMarkus Klein <markus.klein@typo3.org>
Tue, 30 Jun 2015 22:29:07 +0000 (00:29 +0200)
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>
typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
typo3/sysext/extbase/Tests/Unit/Persistence/Generic/QueryResultTest.php

index 5059824..7ee1ba0 100644 (file)
@@ -36,6 +36,11 @@ class QueryResult implements QueryResultInterface {
        protected $persistenceManager;
 
        /**
+        * @var int|NULL
+        */
+       protected $numberOfResults;
+
+       /**
         * @var \TYPO3\CMS\Extbase\Persistence\QueryInterface
         */
        protected $query;
@@ -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;
        }
 
        /**
index c919247..be1e9a0 100644 (file)
@@ -132,6 +132,24 @@ class QueryResultTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        /**
         * @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
+        */
        public function iteratorMethodsAreCorrectlyImplemented() {
                $array1 = array('foo' => 'Foo1', 'bar' => 'Bar1');
                $array2 = array('foo' => 'Foo2', 'bar' => 'Bar2');