Skip to content

Commit

Permalink
Make ResultSets serializable.
Browse files Browse the repository at this point in the history
By implementing Serializable, ResultSets can be persisted into
a persistent cache like Memcache. Unserializing needs only to set the
results again as other properties are set to their defaults.
  • Loading branch information
markstory committed Aug 5, 2013
1 parent fce427a commit 66e9970
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
28 changes: 27 additions & 1 deletion lib/Cake/ORM/ResultSet.php
Expand Up @@ -18,6 +18,7 @@

use Cake\Database\Type;
use \Iterator;
use \Serializable;

/**
* Represents the results obtained after executing a query for an specific table
Expand All @@ -26,7 +27,7 @@
* queries required for eager loading external associations.
*
*/
class ResultSet implements Iterator {
class ResultSet implements Iterator, Serializable {

/**
* Original query from where results where generated
Expand Down Expand Up @@ -286,4 +287,29 @@ protected function _castValues($table, $values) {
return $values;
}

/**
* Serialize a resultset.
*
* Part of Serializable Interface
*
* @return string Serialized object
*/
public function serialize() {
iterator_to_array($this);
return serialize($this->_results);
}

/**
* Unserialize a resultset.
*
* Part of Serializable Interface
*
* @param string Serialized object
* @return ResultSet The hydrated result set.
*/
public function unserialize($serialized) {
$this->_results = unserialize($serialized);
return $this;
}

}
40 changes: 40 additions & 0 deletions lib/Cake/Test/TestCase/ORM/ResultSetTest.php
Expand Up @@ -54,4 +54,44 @@ public function testRewind() {
$this->assertEquals($first, $second);
}

/**
* An integration test for testing serialize and unserialize features.
*
* Compare the results of a query with the results iterated, with
* those of a different query that have been serialized/unserialized.
*
* @return void
*/
public function testSerialization() {
$query = $this->table->find('all');
$results = $query->execute();
$expected = $results->toArray();

$query2 = $this->table->find('all');
$results2 = $query2->execute();
$serialized = serialize($results2);
$outcome = unserialize($serialized);
$this->assertEquals($expected, $outcome->toArray());
}

/**
* Test iteration after serialization
*
* @return void
*/
public function testIteratorAfterSerialization() {
$query = $this->table->find('all');
$results = unserialize(serialize($query->execute()));

$expected = [
['id' => 1, 'author_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y'],
['id' => 2, 'author_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y'],
['id' => 3, 'author_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y']
];
// Use a loop to test Iterator implementation
foreach ($results as $i => $row) {
$this->assertEquals($expected[$i], $row, "Row $i does not match");
}
}

}

0 comments on commit 66e9970

Please sign in to comment.