diff --git a/src/ResultSet.php b/src/ResultSet.php index 151c190..e109f12 100644 --- a/src/ResultSet.php +++ b/src/ResultSet.php @@ -236,6 +236,42 @@ public function current(): Document return $entity; } + /** + * Returns the state to be serialized, so result sets can be stored in a cache (without elastica handles) + * + * @return array + */ + public function __serialize(): array + { + return [ + 'resultSet' => $this->resultSet, + 'entityClass' => $this->entityClass, + 'embeds' => $this->embeds, + 'repoName' => $this->repoName, + ]; + } + + /** + * Restores a result set from its serialized state + * + * @param array $data The state as returned by __serialize() + * @return void + */ + public function __unserialize(array $data): void + { + assert($data['resultSet'] instanceof ElasticaResultSet); + assert(is_string($data['entityClass'])); + assert(is_array($data['embeds'])); + assert(is_string($data['repoName'])); + + $this->resultSet = $data['resultSet']; + $this->entityClass = $data['entityClass']; + $this->embeds = $data['embeds']; + $this->repoName = $data['repoName']; + + parent::__construct($this->resultSet); + } + /** * Debug output hook method. */ diff --git a/tests/TestCase/QueryTest.php b/tests/TestCase/QueryTest.php index 90518a9..e203651 100644 --- a/tests/TestCase/QueryTest.php +++ b/tests/TestCase/QueryTest.php @@ -17,6 +17,8 @@ namespace Cake\ElasticSearch\Test\TestCase; use AssertionError; +use Cake\Cache\Cache; +use Cake\Cache\Engine\FileEngine; use Cake\Datasource\ConnectionManager; use Cake\Datasource\Exception\RecordNotFoundException; use Cake\Datasource\RepositoryInterface; @@ -682,6 +684,30 @@ public function testCacheMethod(): void $this->assertSame($query, $result); } + /** + * Test that a cached query stores its results when it is executed and reads them back on the next execution + */ + public function testCacheMethodWithExecutedQuery(): void + { + Cache::setConfig('query_cache', [ + 'className' => FileEngine::class, + 'path' => sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'query_cache' . DIRECTORY_SEPARATOR, + 'duration' => '1 second', + ]); + + $index = $this->getIndex(); + + $results = (new Query($index))->limit(1)->cache('test_key', 'query_cache')->all(); + $cached = (new Query($index))->limit(1)->cache('test_key', 'query_cache')->all(); + $this->assertEquals($results->toArray(), $cached->toArray()); + $this->assertEquals($results->getTotalHits(), $cached->getTotalHits()); + $this->assertEquals($results->getAggregations(), $cached->getAggregations()); + $this->assertEquals($results->getSuggests(), $cached->getSuggests()); + $this->assertEquals($results->getMaxScore(), $cached->getMaxScore()); + $this->assertEquals($results->getTotalTime(), $cached->getTotalTime()); + $this->assertEquals($results->hasTimedOut(), $cached->hasTimedOut()); + } + /** * Test mapReduce method */