diff --git a/lib/Cake/ORM/BufferedResultSet.php b/lib/Cake/ORM/BufferedResultSet.php new file mode 100644 index 00000000000..25aec18459c --- /dev/null +++ b/lib/Cake/ORM/BufferedResultSet.php @@ -0,0 +1,50 @@ +_index = 0; + $this->_lastIndex = -1; + } + +/** + * Fetch a result and buffer the fetched row. + * + * @return mixed + */ + public function valid() { + $result = parent::valid(); + if (!isset($this->_results[$this->_index])) { + $this->_results[] = $this->_current; + } + return $result; + } + +} diff --git a/lib/Cake/ORM/ResultSet.php b/lib/Cake/ORM/ResultSet.php index 0c9b48734c6..e54bf717671 100644 --- a/lib/Cake/ORM/ResultSet.php +++ b/lib/Cake/ORM/ResultSet.php @@ -17,6 +17,7 @@ namespace Cake\ORM; use Cake\Database\Type; +use Cake\Database\Exception; use \Iterator; use \JsonSerializable; use \Serializable; @@ -142,20 +143,26 @@ public function key() { */ public function next() { $this->_index++; - $this->_fetchResult(); + $this->_lastIndex = $this->_index; } /** * Rewind a ResultSet. * - * Once rewound results will not be refetched from - * the database. + * Not implemented, Use a BufferedResultSet for a rewindable + * ResultSet. * - * @return void + * @throws Cake\Database\Exception */ public function rewind() { - $this->_index = 0; - $this->_lastIndex = -1; + if ($this->_index == 0) { + return; + } + $msg = __d( + 'cake_dev', + 'You cannot rewind an un-buffered ResultSet. Use Query::bufferResults() to get a buffered ResultSet.' + ); + throw new Exception($msg); } /** @@ -164,7 +171,7 @@ public function rewind() { * @return boolean */ public function valid() { - $this->_fetchResult(); + $this->_current = $this->_fetchResult(); return $this->_current !== false; } @@ -195,28 +202,23 @@ protected function _calculateAssociationMap() { } /** - * Helper function to fetch the next result from the statement and update all - * internal counters. + * Helper function to fetch the next result from the statement or + * seeded results. * - * @return void + * @return mixed */ protected function _fetchResult() { - if (isset($this->_results[$this->_index])) { - $this->_current = $this->_results[$this->_index]; - $this->_lastIndex = $this->_index; - return; + if (!empty($this->_results) && isset($this->_results[$this->_index])) { + return $this->_results[$this->_index]; } - if (!$this->_statement) { - $this->_current = false; - return; + if (!empty($this->_results)) { + return false; } $row = $this->_statement->fetch('assoc'); - if ($row !== false) { - $row = $this->_groupResult($row); - $this->_results[] = $row; + if ($row === false) { + return $row; } - $this->_current = $row; - $this->_lastIndex = $this->_index; + return $this->_groupResult($row); } /** @@ -297,8 +299,7 @@ protected function _castValues($table, $values) { * @return string Serialized object */ public function serialize() { - $this->toArray(); - return serialize($this->_results); + return serialize($this->toArray()); } /** @@ -321,8 +322,7 @@ public function unserialize($serialized) { * @return array The data to convert to JSON */ public function jsonSerialize() { - $this->toArray(); - return $this->_results; + return $this->toArray(); } } diff --git a/lib/Cake/Test/TestCase/ORM/BufferedResultSetTest.php b/lib/Cake/Test/TestCase/ORM/BufferedResultSetTest.php new file mode 100644 index 00000000000..265fde0d93f --- /dev/null +++ b/lib/Cake/Test/TestCase/ORM/BufferedResultSetTest.php @@ -0,0 +1,57 @@ +connection = ConnectionManager::getDataSource('test'); + $this->table = new Table(['table' => 'articles', 'connection' => $this->connection]); + } + +/** + * Test that result sets can be rewound and re-used. + * + * @return void + */ + public function testRewind() { + $query = $this->table->find('all'); + $results = $query->bufferResults()->execute(); + $first = $second = []; + foreach ($results as $result) { + $first[] = $result; + } + foreach ($results as $result) { + $second[] = $result; + } + $this->assertEquals($first, $second); + } + +} diff --git a/lib/Cake/Test/TestCase/ORM/ResultSetTest.php b/lib/Cake/Test/TestCase/ORM/ResultSetTest.php index 20928f414ef..95a5c03ae2e 100644 --- a/lib/Cake/Test/TestCase/ORM/ResultSetTest.php +++ b/lib/Cake/Test/TestCase/ORM/ResultSetTest.php @@ -45,6 +45,7 @@ public function setUp() { /** * Test that result sets can be rewound and re-used. * + * @expectedException Cake\Database\Exception * @return void */ public function testRewind() { @@ -57,7 +58,6 @@ public function testRewind() { foreach ($results as $result) { $second[] = $result; } - $this->assertEquals($first, $second); } /**