-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathQueryCacher.php
137 lines (123 loc) · 3.74 KB
/
QueryCacher.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Datasource;
use Cake\Cache\Cache;
use Closure;
use Psr\SimpleCache\CacheInterface;
use RuntimeException;
use Traversable;
/**
* Handles caching queries and loading results from the cache.
*
* Used by Cake\Datasource\QueryTrait internally.
*
* @internal
* @see \Cake\Datasource\QueryTrait::cache() for the public interface.
*/
class QueryCacher
{
/**
* The key or function to generate a key.
*
* @var string|\Closure
*/
protected $_key;
/**
* Config for cache engine.
*
* @var string|\Psr\SimpleCache\CacheInterface
*/
protected $_config;
/**
* Constructor.
*
* @param string|\Closure $key The key or function to generate a key.
* @param string|\Psr\SimpleCache\CacheInterface $config The cache config name or cache engine instance.
* @throws \RuntimeException
*/
public function __construct($key, $config)
{
if (!is_string($key) && !($key instanceof Closure)) {
throw new RuntimeException('Cache keys must be strings or callables.');
}
$this->_key = $key;
if (!is_string($config) && !($config instanceof CacheInterface)) {
throw new RuntimeException('Cache configs must be strings or \Psr\SimpleCache\CacheInterface instances.');
}
$this->_config = $config;
}
/**
* Load the cached results from the cache or run the query.
*
* @param object $query The query the cache read is for.
* @return mixed|null Either the cached results or null.
*/
public function fetch(object $query)
{
$key = $this->_resolveKey($query);
$storage = $this->_resolveCacher();
$result = $storage->get($key);
if (empty($result)) {
return null;
}
return $result;
}
/**
* Store the result set into the cache.
*
* @param object $query The query the cache read is for.
* @param \Traversable $results The result set to store.
* @return bool True if the data was successfully cached, false on failure
*/
public function store(object $query, Traversable $results): bool
{
$key = $this->_resolveKey($query);
$storage = $this->_resolveCacher();
return $storage->set($key, $results);
}
/**
* Get/generate the cache key.
*
* @param object $query The query to generate a key for.
* @return string
* @throws \RuntimeException
*/
protected function _resolveKey(object $query): string
{
if (is_string($this->_key)) {
return $this->_key;
}
$func = $this->_key;
$key = $func($query);
if (!is_string($key)) {
$msg = sprintf('Cache key functions must return a string. Got %s.', var_export($key, true));
throw new RuntimeException($msg);
}
return $key;
}
/**
* Get the cache engine.
*
* @return \Psr\SimpleCache\CacheInterface
*/
protected function _resolveCacher()
{
if (is_string($this->_config)) {
return Cache::pool($this->_config);
}
return $this->_config;
}
}