Browse Source

Fixing Query::count(), previous implementation was trying to be too
smart and was giving inconsisten results.

In some cases count() returned the full

Jose Lorenzo Rodriguez 12 years ago
parent
commit
73b9bedd21
2 changed files with 13 additions and 16 deletions
  1. 5 11
      src/ORM/Query.php
  2. 8 5
      tests/TestCase/ORM/QueryTest.php

+ 5 - 11
src/ORM/Query.php

@@ -872,20 +872,14 @@ class Query extends DatabaseQuery {
  * this method will replace the selected fields with a COUNT(*), and the resulting
  * count will be returned.
  *
- * If the query does contain GROUP BY or map reduce functions, then it
- * will be executed, and the number of rows in the ResultSet will be returned.
- *
  * @return integer
  */
 	public function count() {
-		$noFormatters = $this->mapReduce() === [] && empty($this->_formatters);
-		if ($this->clause('group') === [] && $noFormatters) {
-			$this->select(['count' => $this->func()->count('*')], true)
-				->hydrate(false);
-			return (int)$this->first()['count'];
-		}
-		$results = $this->execute();
-		return count($results);
+		$query = clone $this;
+		$query->select(['count' => $this->func()->count('*')])->hydrate(false);
+		$query->mapReduce(null, null, true);
+		$query->formatResults(null, true);
+		return (int)$query->first()['count'];
 	}
 
 /**

+ 8 - 5
tests/TestCase/ORM/QueryTest.php

@@ -1491,12 +1491,14 @@ class QueryTest extends TestCase {
 		$this->assertSame(3, $result);
 
 		$query = $table->find('all')
-			->where(['id >' => 1]);
+			->where(['id >' => 1])
+			->limit(1);
 		$result = $query->count();
 		$this->assertSame(2, $result);
 
 		$result = $query->all();
-		$this->assertEquals(['count' => 2], $result->first());
+		$this->assertCount(1, $result);
+		$this->assertEquals(2, $result->first()->id);
 	}
 
 /**
@@ -1506,10 +1508,11 @@ class QueryTest extends TestCase {
  */
 	public function testCountWithGroup() {
 		$table = TableRegistry::get('articles');
-		$query = $table->find('all')
-			->group(['published']);
+		$query = $table->find('all');
+		$query->select(['author_id', 's' => $query->func()->sum('id')])
+			->group(['author_id']);
 		$result = $query->count();
-		$this->assertEquals(1, $result);
+		$this->assertEquals(2, $result);
 	}
 
 /**