Skip to content

Commit

Permalink
Implemented Collection::first() and renaming one() to first() everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Dec 28, 2013
1 parent 205242e commit b2d204e
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 90 deletions.
11 changes: 11 additions & 0 deletions Cake/Collection/CollectionTrait.php
Expand Up @@ -603,6 +603,17 @@ public function firstMatch(array $conditions) {
return null;
}

/**
* Returns the first result in this collection
*
* @return mixed The first value in the collection will be returned.
*/
public function first() {
foreach ($this->take(1) as $result) {
return $result;
}
}

/**
* Returns a new collection as the result of concatenating the list of elements
* in this collection with the passed list of elements
Expand Down
2 changes: 1 addition & 1 deletion Cake/ORM/Query.php
Expand Up @@ -638,7 +638,7 @@ public function first() {
}
$this->bufferResults();
$this->_results = $this->execute();
return $this->_results->one();
return $this->_results->first();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion Cake/ORM/ResultSet.php
Expand Up @@ -213,7 +213,7 @@ public function valid() {
*
* @return array|object
*/
public function one() {
public function first() {
if ($this->valid()) {
if ($this->_statement) {
$this->_statement->closeCursor();
Expand Down
79 changes: 26 additions & 53 deletions Cake/ORM/ResultSetDecorator.php
Expand Up @@ -16,83 +16,56 @@
*/
namespace Cake\ORM;

use \ArrayIterator;
use \Countable;
use \IteratorAggregate;
use \JsonSerializable;
use \Serializable;
use \Traversable;
use ArrayIterator;
use Cake\Collection\Collection;
use Countable;
use IteratorIterator;
use JsonSerializable;
use Serializable;
use Traversable;

/**
* Generic ResultSet decorator. This will make any traversable object appear to
* be a database result
*
* @return void
*/
class ResultSetDecorator implements Countable, IteratorAggregate, Serializable, JsonSerializable {

use ResultCollectionTrait;

/**
* Holds the records after an instance of this object has been unserialized
*
* @var array
*/
protected $_results;
class ResultSetDecorator extends Collection implements Countable, Serializable, JsonSerializable {

/**
* Constructor
* Make this object countable.
*
* @param Traversable $results
*/
public function __construct(Traversable $results) {
$this->_results = $results;
}

/**
* Returns the inner iterator this decorator is wrapping
* Part of the Countable interface. Calling this method
* will convert the underlying traversable object into an array and
* get the count of the underlying data.
*
* @return \Iterator
* @return integer.
*/
public function getIterator() {
if (is_array($this->_results)) {
$this->_results = new ArrayIterator($this->_results);
}
return $this->_results;
public function count() {
return count(iterator_to_array($this));
}

/**
* Get a single result from the results.
* Serialize a resultset.
*
* Calling this method will convert the underlying data into
* an array and will return the first result in the data set.
* Part of Serializable interface.
*
* @return mixed The first value in the results will be returned.
* @return string Serialized object
*/
public function one() {
if (!is_array($this->_results)) {
$this->_results = iterator_to_array($this->_results);
}
if (count($this->_results) < 1) {
return false;
}
return current($this->_results);
public function serialize() {
return serialize($this->toArray());
}

/**
* Make this object countable.
* Unserialize a resultset.
*
* Part of the Countable interface. Calling this method
* will convert the underlying traversable object into an array and
* get the count of the underlying data.
* Part of Serializable interface.
*
* @return integer.
* @param string Serialized object
* @return ResultSet The hydrated result set.
*/
public function count() {
if (!is_array($this->_results)) {
$this->_results = iterator_to_array($this->_results);
}
return count($this->_results);
public function unserialize($serialized) {
parent::__construct(unserialize($serialized));
}

}
21 changes: 1 addition & 20 deletions Cake/Test/TestCase/ORM/QueryTest.php
Expand Up @@ -867,23 +867,6 @@ public function testSetResult() {
$this->assertSame($results, $query->execute());
}

/**
* Test enabling buffering of results.
*
* @return void
*/
public function testBufferResults() {
$this->markTestIncomplete();
$table = TableRegistry::get('articles', ['table' => 'articles']);
$query = new Query($this->connection, $table);

$result = $query->select()->bufferResults();
$this->assertSame($query, $result, 'Query should be the same');
$result = $query->execute();
$this->assertInstanceOf('Cake\ORM\BufferedResultSet', $result);
$result->toArray();
}

/**
* Tests that applying array options to a query will convert them
* to equivalent function calls with the correspondent array values
Expand Down Expand Up @@ -1089,7 +1072,6 @@ function($k, $v, $mr) {
* @return void
*/
public function testFirstDirtyQuery() {
$this->markTestIncomplete();
$table = TableRegistry::get('articles', ['table' => 'articles']);
$query = new Query($this->connection, $table);
$result = $query->select(['id'])->hydrate(false)->first();
Expand Down Expand Up @@ -1404,7 +1386,6 @@ public function testHydrateBelongsToCustomEntity() {
* @return void
*/
public function testCount() {
$this->markTestIncomplete();
$table = TableRegistry::get('articles');
$result = $table->find('all')->count();
$this->assertEquals(3, $result);
Expand All @@ -1415,7 +1396,7 @@ public function testCount() {
$this->assertEquals(2, $result);

$result = $query->execute();
$this->assertEquals(['count' => 2], $result->one());
$this->assertEquals(['count' => 2], $result->first());
}

/**
Expand Down
8 changes: 4 additions & 4 deletions Cake/Test/TestCase/ORM/ResultSetDecoratorTest.php
Expand Up @@ -71,16 +71,16 @@ public function testSerialization() {
}

/**
* Test the one() method which is part of the ResultSet duck type.
* Test the first() method which is part of the ResultSet duck type.
*
* @return void
*/
public function testOne() {
public function testFirst() {
$data = new \ArrayIterator([1, 2, 3]);
$decorator = new ResultSetDecorator($data);

$this->assertEquals(1, $decorator->one());
$this->assertEquals(1, $decorator->one());
$this->assertEquals(1, $decorator->first());
$this->assertEquals(1, $decorator->first());
}

/**
Expand Down
18 changes: 9 additions & 9 deletions Cake/Test/TestCase/ORM/ResultSetTest.php
Expand Up @@ -154,36 +154,36 @@ public function testJsonSerialize() {
}

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

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

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

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

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

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

/**
Expand Down
4 changes: 2 additions & 2 deletions Cake/Test/TestCase/ORM/TableTest.php
Expand Up @@ -1648,7 +1648,7 @@ public function testDeleteDependent() {
'author_id' => $entity->id
]
]);
$this->assertNull($query->execute()->one(), 'Should not find any rows.');
$this->assertNull($query->execute()->first(), 'Should not find any rows.');
}

/**
Expand Down Expand Up @@ -1689,7 +1689,7 @@ public function testDeleteBelongsToMany() {

$junction = $table->association('tags')->junction();
$query = $junction->find('all')->where(['article_id' => 1]);
$this->assertNull($query->execute()->one(), 'Should not find any rows.');
$this->assertNull($query->execute()->first(), 'Should not find any rows.');
}

/**
Expand Down

0 comments on commit b2d204e

Please sign in to comment.