Skip to content

Commit

Permalink
Add count() and improve one() to ResultSet
Browse files Browse the repository at this point in the history
one() should work even if the ResultSet has been serialized. Adding
support for count() as other parts of the framework expect that result
sets are countable.
  • Loading branch information
markstory committed Nov 16, 2013
1 parent c71c569 commit 862b2a2
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 4 deletions.
30 changes: 26 additions & 4 deletions Cake/ORM/ResultSet.php
Expand Up @@ -18,6 +18,7 @@

use Cake\Database\Exception;
use Cake\Database\Type;
use \Countable;
use \Iterator;
use \JsonSerializable;
use \Serializable;
Expand All @@ -29,7 +30,7 @@
* queries required for eager loading external associations.
*
*/
class ResultSet implements Iterator, Serializable, JsonSerializable {
class ResultSet implements Countable, Iterator, Serializable, JsonSerializable {

use ResultCollectionTrait;

Expand All @@ -43,7 +44,7 @@ class ResultSet implements Iterator, Serializable, JsonSerializable {
/**
* Database statement holding the results
*
* @var \Cake\Database\Statement
* @var \Cake\Database\StatementInterface
*/
protected $_statement;

Expand Down Expand Up @@ -115,7 +116,7 @@ class ResultSet implements Iterator, Serializable, JsonSerializable {
* Constructor
*
* @param Query from where results come
* @param \Cake\Database\Statement $statement
* @param \Cake\Database\StatementInterface $statement
* @return void
*/
public function __construct($query, $statement) {
Expand Down Expand Up @@ -192,7 +193,11 @@ public function valid() {

/**
* Returns the first result in this set and blocks the set so that no other
* results can be fetched
* results can be fetched.
*
* When using serialized results, the index will be incremented past the
* end of the results simulating the behavior when the result set is backed
* by a statement.
*
* @return array|object
*/
Expand All @@ -201,11 +206,28 @@ public function one() {
if ($this->_statement) {
$this->_statement->closeCursor();
}
if (!$this->_statement && $this->_results) {
$this->_index = count($this->_results);
}
return $this->_current;
}
return null;
}

/**
* Gives the number of rows in the result set.
*
* Part of the countable interface.
*
* @return integer
*/
public function count() {
if ($this->_statement) {
return $this->_statement->rowCount();
}
return count($this->_results);
}

/**
* Calculates the list of associations that should get eager loaded
* when fetching each record
Expand Down
63 changes: 63 additions & 0 deletions Cake/Test/TestCase/ORM/ResultSetTest.php
Expand Up @@ -30,6 +30,11 @@ class ResultSetTest extends TestCase {

public $fixtures = ['core.article'];

/**
* setup
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->connection = ConnectionManager::get('test');
Expand Down Expand Up @@ -128,4 +133,62 @@ public function testJsonSerialize() {
$this->assertEquals($expected, json_encode($results));
}

/**
* Test one() method with a statement backed result set.
*
* @return void
*/
public function testOne() {
$query = $this->table->find('all');
$results = $query->hydrate(false)->execute();

$row = $results->one();
$this->assertEquals($this->fixtureData[0], $row);

$this->assertNull($results->one(), 'No more rows.');
$this->assertNull($results->one(), 'No more rows.');
}

/**
* Test one() method with a result set that has been unserialized
*
* @return void
*/
public function testOneAfterSerialize() {
$query = $this->table->find('all');
$results = $query->hydrate(false)->execute();
$results = unserialize(serialize($results));

$row = $results->one();
$this->assertEquals($this->fixtureData[0], $row);

$this->assertNull($results->one(), 'No more rows.');
$this->assertNull($results->one(), 'No more rows.');
}

/**
* Test the countable interface.
*
* @return void
*/
public function testCount() {
$query = $this->table->find('all');
$results = $query->execute();

$this->assertCount(3, $results, 'Should be countable and 3');
}

/**
* Test the countable interface after unserialize
*
* @return void
*/
public function testCountAfterSerialize() {
$query = $this->table->find('all');
$results = $query->execute();
$results = unserialize(serialize($results));

$this->assertCount(3, $results, 'Should be countable and 3');
}

}

0 comments on commit 862b2a2

Please sign in to comment.