Skip to content

Commit b5ff431

Browse files
authored
Merge pull request #156 from homersimpsons/fix/inner-result-iterator-count-performance
InnerResultIterator: Improve count() performance of non-executed query
2 parents 65e5feb + 65f0e4b commit b5ff431

File tree

3 files changed

+20
-21
lines changed

3 files changed

+20
-21
lines changed

src/AlterableResultIterator.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ public function take($offset, $limit)
222222
*/
223223
public function count()
224224
{
225+
if ($this->resultIterator instanceof \Countable && $this->alterations->count() === 0) {
226+
return $this->resultIterator->count();
227+
}
225228
return count($this->toArray());
226229
}
227230

src/InnerResultIterator.php

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ protected function executeQuery(): void
102102
$this->fetchStarted = true;
103103
}
104104

105+
private $count = null;
105106
/**
106107
* Counts found records (this is the number of records fetched, taking into account the LIMIT and OFFSET settings).
107108
*
@@ -113,30 +114,14 @@ public function count()
113114
return $this->count;
114115
}
115116

116-
if ($this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform) {
117+
if ($this->fetchStarted && $this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform) {
117118
// Optimisation: we don't need a separate "count" SQL request in MySQL.
118-
return $this->getRowCountViaRowCountFunction();
119-
} else {
120-
return $this->getRowCountViaSqlQuery();
121-
}
122-
}
123-
124-
private $count = null;
125-
126-
/**
127-
* Get the row count from the rowCount function (only works with MySQL)
128-
*/
129-
private function getRowCountViaRowCountFunction(): int
130-
{
131-
if (!$this->fetchStarted) {
132-
$this->executeQuery();
119+
$this->count = $this->statement->rowCount();
120+
return $this->count;
133121
}
134-
135-
$this->count = $this->statement->rowCount();
136-
return $this->count;
122+
return $this->getRowCountViaSqlQuery();
137123
}
138124

139-
140125
/**
141126
* Makes a separate SQL query to compute the row count.
142127
* (not needed in MySQL)
@@ -147,7 +132,7 @@ private function getRowCountViaSqlQuery(): int
147132

148133
$this->logger->debug('Running count SQL request: '.$countSql);
149134

150-
$this->count = $this->tdbmService->getConnection()->fetchColumn($countSql, $this->parameters);
135+
$this->count = (int) $this->tdbmService->getConnection()->fetchColumn($countSql, $this->parameters);
151136
return $this->count;
152137
}
153138

tests/TDBMDaoGeneratorTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,17 @@ public function testPageJsonEncode(): void
961961
$this->assertCount(1, $msgDecoded);
962962
}
963963

964+
/**
965+
* @depends testDaoGeneration
966+
*/
967+
public function testInnerResultIteratorCountAfterFetch(): void
968+
{
969+
$userDao = new TestUserDao($this->tdbmService);
970+
$users = $userDao->getUsersByLoginStartingWith('j')->take(0, 4);
971+
$users->toArray(); // We force to fetch
972+
$this->assertEquals(3, $users->count());
973+
}
974+
964975
/**
965976
* @depends testDaoGeneration
966977
*/

0 commit comments

Comments
 (0)