1 | <?php |
||||
2 | App::uses('DataSource', 'Model/Datasource'); |
||||
3 | |||||
4 | /** |
||||
5 | * Redis Source class |
||||
6 | * |
||||
7 | */ |
||||
8 | class RedisSource extends DataSource { |
||||
0 ignored issues
–
show
|
|||||
9 | |||||
10 | /** |
||||
11 | * Datasource description. |
||||
12 | * |
||||
13 | * @var string |
||||
14 | */ |
||||
15 | public $description = 'Redis Data Source'; |
||||
16 | |||||
17 | /** |
||||
18 | * Base configuration. |
||||
19 | * |
||||
20 | * @var array |
||||
21 | */ |
||||
22 | protected $_baseConfig = [ |
||||
23 | 'host' => '127.0.0.1', |
||||
24 | 'port' => 6379, |
||||
25 | 'password' => '', |
||||
26 | 'database' => 0, |
||||
27 | 'timeout' => 0, |
||||
28 | 'persistent' => false, |
||||
29 | 'unix_socket' => '', |
||||
30 | 'prefix' => '', |
||||
31 | ]; |
||||
32 | |||||
33 | /** |
||||
34 | * Configuration. |
||||
35 | * |
||||
36 | * @var array |
||||
37 | */ |
||||
38 | public $config = []; |
||||
39 | |||||
40 | /** |
||||
41 | * A reference to the physical connection of this DataSource. |
||||
42 | * |
||||
43 | * @var Redis |
||||
44 | */ |
||||
45 | protected $_connection = null; |
||||
46 | |||||
47 | /** |
||||
48 | * Whether or not we are connected to the DataSource. |
||||
49 | * |
||||
50 | * @var bool |
||||
51 | */ |
||||
52 | public $connected = false; |
||||
53 | |||||
54 | /** |
||||
55 | * Whether or not source data like available tables and schema descriptions should be cached. |
||||
56 | * |
||||
57 | * @var bool |
||||
58 | */ |
||||
59 | public $cacheSources = false; |
||||
60 | |||||
61 | /** |
||||
62 | * Constructor. |
||||
63 | * |
||||
64 | * @param array $config Array of configuration information for the Datasource |
||||
65 | * @return bool True if connecting to the DataSource succeeds, else false |
||||
66 | * @throws RedisSourceException |
||||
67 | */ |
||||
68 | public function __construct($config = []) { |
||||
69 | parent::__construct($config); |
||||
70 | |||||
71 | if (!$this->enabled()) { |
||||
72 | throw new RedisSourceException(__d('redis', 'Extension is not loaded.')); |
||||
0 ignored issues
–
show
The function
__d was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
73 | } |
||||
74 | |||||
75 | $this->_connection = new Redis(); |
||||
76 | |||||
77 | return $this->connect(); |
||||
78 | } |
||||
79 | |||||
80 | /** |
||||
81 | * Destructor. |
||||
82 | * |
||||
83 | * Closes the connection to the host (if needed). |
||||
84 | * |
||||
85 | * @return void |
||||
86 | * @todo Write test |
||||
87 | */ |
||||
88 | public function __destruct() { |
||||
89 | if (!$this->config['persistent']) { |
||||
90 | $this->close(); |
||||
91 | } |
||||
92 | } |
||||
93 | |||||
94 | /** |
||||
95 | * Passes (non-existing) method calls to `Redis`. |
||||
96 | * |
||||
97 | * @param string $name The name of the method being called |
||||
98 | * @param array $arguments An enumerated array containing the parameters passed to the method |
||||
99 | * @return mixed Method return value |
||||
100 | * @throws RedisSourceException |
||||
101 | */ |
||||
102 | public function __call($name, $arguments) { |
||||
103 | if (!method_exists($this->_connection, $name)) { |
||||
104 | throw new RedisSourceException(__d('redis', 'Method (%s) does not exist.', $name)); |
||||
0 ignored issues
–
show
The function
__d was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
105 | } |
||||
106 | |||||
107 | try { |
||||
108 | return call_user_func_array([$this->_connection, $name], $arguments); |
||||
109 | } catch (RedisException $e) { |
||||
110 | throw new RedisSourceException(__d('redis', 'Method (%s) failed: %s.', $name, $e->getMessage())); |
||||
111 | } |
||||
112 | } |
||||
113 | |||||
114 | /** |
||||
115 | * Check that the redis extension is loaded. |
||||
116 | * |
||||
117 | * @return bool Whether or not the extension is loaded |
||||
118 | */ |
||||
119 | public function enabled() { |
||||
120 | return extension_loaded('redis'); |
||||
121 | } |
||||
122 | |||||
123 | /** |
||||
124 | * Connects to the database using options in the given configuration array. |
||||
125 | * |
||||
126 | * "Connects" means: |
||||
127 | * - connect |
||||
128 | * - authenticate |
||||
129 | * - select |
||||
130 | * - setPrefix |
||||
131 | * |
||||
132 | * @return bool True if all of the above steps succeed, else false |
||||
133 | * @throws RedisSourceException |
||||
134 | */ |
||||
135 | public function connect() { |
||||
136 | if (!$this->_connect()) { |
||||
137 | throw new RedisSourceException(__d('redis', 'Could not connect.')); |
||||
0 ignored issues
–
show
The function
__d was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
138 | } |
||||
139 | |||||
140 | if (!$this->_authenticate()) { |
||||
141 | throw new RedisSourceException(__d('redis', 'Could not authenticate.')); |
||||
142 | } |
||||
143 | |||||
144 | if (!$this->_select()) { |
||||
145 | throw new RedisSourceException(__d('redis', 'Could not select.')); |
||||
146 | } |
||||
147 | |||||
148 | if (!$this->_setPrefix()) { |
||||
149 | throw new RedisSourceException(__d('redis', 'Could not set prefix.')); |
||||
150 | } |
||||
151 | |||||
152 | $this->connected = true; |
||||
153 | |||||
154 | return $this->connected; |
||||
155 | } |
||||
156 | |||||
157 | /** |
||||
158 | * Connects to the database using options in the given configuration array. |
||||
159 | * |
||||
160 | * @return bool True if connecting to the DataSource succeeds, else false |
||||
161 | */ |
||||
162 | protected function _connect() { |
||||
163 | $unixSocket = $this->config['unix_socket']; |
||||
164 | $persistent = $this->config['persistent']; |
||||
165 | $host = $this->config['host']; |
||||
166 | $port = $this->config['port']; |
||||
167 | $timeout = $this->config['timeout']; |
||||
168 | |||||
169 | if ($unixSocket) { |
||||
170 | return $this->_connection->connect($unixSocket); |
||||
171 | } elseif ($persistent) { |
||||
172 | return $this->_connection->pconnect($host, $port, $timeout, $persistent); |
||||
173 | } else { |
||||
174 | return $this->_connection->connect($host, $port, $timeout); |
||||
175 | } |
||||
176 | } |
||||
177 | |||||
178 | /** |
||||
179 | * Authenticates to the database (if needed) using options in the given configuration array. |
||||
180 | * |
||||
181 | * @return bool True if the authentication succeeded or no password was specified, else false |
||||
182 | */ |
||||
183 | protected function _authenticate() { |
||||
184 | if ($this->config['password']) { |
||||
185 | return $this->_connection->auth($this->config['password']); |
||||
186 | } |
||||
187 | |||||
188 | return true; |
||||
189 | } |
||||
190 | |||||
191 | /** |
||||
192 | * Selects a database (if needed) using options in the given configuration array. |
||||
193 | * |
||||
194 | * @return bool True if the select succeeded or no database was specified, else false |
||||
195 | */ |
||||
196 | protected function _select() { |
||||
197 | if ($this->config['database']) { |
||||
198 | return $this->_connection->select($this->config['database']); |
||||
199 | } |
||||
200 | |||||
201 | return true; |
||||
202 | } |
||||
203 | |||||
204 | /** |
||||
205 | * Sets a prefix for all keys (if needed) using options in the given configuration array. |
||||
206 | * |
||||
207 | * @return bool True if setting the prefix succeeded or no prefix was specified, else false |
||||
208 | */ |
||||
209 | protected function _setPrefix() { |
||||
210 | if ($this->config['prefix']) { |
||||
211 | return $this->_connection->setOption(Redis::OPT_PREFIX, $this->config['prefix']); |
||||
212 | } |
||||
213 | |||||
214 | return true; |
||||
215 | } |
||||
216 | |||||
217 | /** |
||||
218 | * Closes a connection. |
||||
219 | * |
||||
220 | * @return bool Always true |
||||
221 | */ |
||||
222 | public function close() { |
||||
223 | if ($this->isConnected()) { |
||||
224 | $this->_connection->close(); |
||||
225 | } |
||||
226 | |||||
227 | $this->connected = false; |
||||
228 | $this->_connection = null; |
||||
229 | |||||
230 | return true; |
||||
231 | } |
||||
232 | |||||
233 | /** |
||||
234 | * Checks if the source is connected to the database. |
||||
235 | * |
||||
236 | * @return bool True if the database is connected, else false |
||||
237 | */ |
||||
238 | public function isConnected() { |
||||
239 | return $this->connected; |
||||
240 | } |
||||
241 | |||||
242 | /** |
||||
243 | * Caches/returns cached results for child instances. |
||||
244 | * |
||||
245 | * @param mixed $data List of tables |
||||
246 | * @return array Array of sources available in this datasource |
||||
247 | */ |
||||
248 | public function listSources($data = null) { |
||||
249 | return parent::listSources($data); |
||||
250 | } |
||||
251 | |||||
252 | /** |
||||
253 | * Returns a Model description (metadata) or null if none found. |
||||
254 | * |
||||
255 | * @param Model|string $model Name of database table to inspect or model instance |
||||
0 ignored issues
–
show
The type
Model was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
256 | * @return array Array of Metadata for the $model |
||||
257 | */ |
||||
258 | public function describe($model) { |
||||
259 | return parent::describe($model); |
||||
260 | } |
||||
261 | |||||
262 | } |
||||
263 | |||||
264 | /** |
||||
265 | * Redis Source Exception class. |
||||
266 | * |
||||
267 | */ |
||||
268 | class RedisSourceException extends CakeException { |
||||
0 ignored issues
–
show
The type
CakeException was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
269 | } |
||||
270 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths