Added the zend framework 2 library, the path is specified in line no.26 in zend_modul...
[openemr.git] / interface / modules / zend_modules / library / Zend / Cache / Storage / Adapter / Redis.php
blobb7e5726cd39ffb92d229c7d39d06882195da8f8a
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Cache\Storage\Adapter;
12 use Redis as RedisResource;
13 use RedisException as RedisResourceException;
14 use stdClass;
15 use Zend\Cache\Storage\Adapter\AbstractAdapter;
16 use Zend\Cache\Exception;
17 use Zend\Cache\Storage\AvailableSpaceCapableInterface;
18 use Zend\Cache\Storage\Capabilities;
19 use Zend\Cache\Storage\FlushableInterface;
20 use Zend\Cache\Storage\TotalSpaceCapableInterface;
22 class Redis extends AbstractAdapter implements
23 FlushableInterface,
24 TotalSpaceCapableInterface
27 /**
28 * Has this instance be initialized
30 * @var bool
32 protected $initialized = false;
34 /**
35 * The redis resource manager
37 * @var null|RedisResourceManager
39 protected $resourceManager;
41 /**
42 * The redis resource id
44 * @var null|string
46 protected $resourceId;
48 /**
49 * The namespace prefix
51 * @var string
53 protected $namespacePrefix = '';
55 /**
56 * Create new Adapter for redis storage
58 * @param null|array|Traversable|RedisOptions $options
59 * @see \Zend\Cache\Storage\Adapter\Abstract
61 public function __construct($options = null)
63 if (!extension_loaded('redis')) {
64 throw new Exception\ExtensionNotLoadedException("Redis extension is not loaded");
67 parent::__construct($options);
69 // reset initialized flag on update option(s)
70 $initialized = & $this->initialized;
71 $this->getEventManager()->attach('option', function ($event) use (& $initialized) {
72 $initialized = false;
73 });
76 /**
77 * Get Redis resource
79 * @return RedisResource
81 protected function getRedisResource()
83 if (!$this->initialized) {
84 $options = $this->getOptions();
86 // get resource manager and resource id
87 $this->resourceManager = $options->getResourceManager();
88 $this->resourceId = $options->getResourceId();
90 // init namespace prefix
91 $namespace = $options->getNamespace();
92 if ($namespace !== '') {
93 $this->namespacePrefix = $namespace . $options->getNamespaceSeparator();
94 } else {
95 $this->namespacePrefix = '';
98 // update initialized flag
99 $this->initialized = true;
102 return $this->resourceManager->getResource($this->resourceId);
105 /* options */
108 * Set options.
110 * @param array|Traversable|RedisOptions $options
111 * @return Redis
112 * @see getOptions()
114 public function setOptions($options)
116 if (!$options instanceof RedisOptions) {
117 $options = new RedisOptions($options);
119 return parent::setOptions($options);
123 * Get options.
125 * @return RedisOptions
126 * @see setOptions()
128 public function getOptions()
130 if (!$this->options) {
131 $this->setOptions(new RedisOptions());
133 return $this->options;
137 * Internal method to get an item.
139 * @param string &$normalizedKey Key where to store data
140 * @param bool &$success If the operation was successfull
141 * @param mixed &$casToken Token
142 * @return mixed Data on success, false on key not found
143 * @throws Exception\RuntimeException
145 protected function internalGetItem(& $normalizedKey, & $success = null, & $casToken = null)
147 $redis = $this->getRedisResource();
148 try {
149 $value = $redis->get($this->namespacePrefix . $normalizedKey);
150 } catch (RedisResourceException $e) {
151 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
154 if ($value === false) {
155 $success = false;
156 return null;
159 $success = true;
160 $casToken = $value;
161 return $value;
165 * Internal method to get multiple items.
167 * @param array &$normalizedKeys Array of keys to be obtained
169 * @return array Associative array of keys and values
170 * @throws Exception\RuntimeException
172 protected function internalGetItems(array & $normalizedKeys)
174 $redis = $this->getRedisResource();
176 $namespacedKeys = array();
177 foreach ($normalizedKeys as & $normalizedKey) {
178 $namespacedKeys[] = $this->namespacePrefix . $normalizedKey;
181 try {
182 $results = $redis->mGet($namespacedKeys);
183 } catch (RedisResourceException $e) {
184 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
186 //combine the key => value pairs and remove all missing values
187 return array_filter(
188 array_combine($normalizedKeys, $results),
189 function ($value) {
190 return $value !== false;
196 * Internal method to test if an item exists.
198 * @param string &$normalizedKey Normalized key which will be checked
200 * @return bool
201 * @throws Exception\RuntimeException
203 protected function internalHasItem(& $normalizedKey)
205 $redis = $this->getRedisResource();
206 try {
207 return $redis->exists($this->namespacePrefix . $normalizedKey);
208 } catch (RedisResourceException $e) {
209 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
214 * Internal method to store an item.
216 * @param string &$normalizedKey Key in Redis under which value will be saved
217 * @param mixed &$value Value to store under cache key
219 * @return bool
220 * @throws Exception\RuntimeException
222 protected function internalSetItem(& $normalizedKey, & $value)
224 $redis = $this->getRedisResource();
225 $ttl = $this->getOptions()->getTtl();
227 try {
228 if ($ttl) {
229 if ($this->resourceManager->getMajorVersion($this->resourceId) < 2) {
230 throw new Exception\UnsupportedMethodCallException("To use ttl you need version >= 2.0.0");
232 $success = $redis->setex($this->namespacePrefix . $normalizedKey, $ttl, $value);
233 } else {
234 $success = $redis->set($this->namespacePrefix . $normalizedKey, $value);
236 } catch (RedisResourceException $e) {
237 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
240 return $success;
244 * Internal method to store multiple items.
246 * @param array &$normalizedKeyValuePairs An array of normalized key/value pairs
248 * @return array Array of not stored keys
249 * @throws Exception\RuntimeException
251 protected function internalSetItems(array & $normalizedKeyValuePairs)
253 $redis = $this->getRedisResource();
254 $ttl = $this->getOptions()->getTtl();
256 $namespacedKeyValuePairs = array();
257 foreach ($normalizedKeyValuePairs as $normalizedKey => & $value) {
258 $namespacedKeyValuePairs[$this->namespacePrefix . $normalizedKey] = & $value;
260 try {
261 if ($ttl > 0) {
262 //check if ttl is supported
263 if ($this->resourceManager->getMajorVersion($this->resourceId) < 2) {
264 throw new Exception\UnsupportedMethodCallException("To use ttl you need version >= 2.0.0");
266 //mSet does not allow ttl, so use transaction
267 $transaction = $redis->multi();
268 foreach ($namespacedKeyValuePairs as $key => $value) {
269 $transaction->setex($key, $ttl, $value);
271 $success = $transaction->exec();
272 } else {
273 $success = $redis->mSet($namespacedKeyValuePairs);
276 } catch (RedisResourceException $e) {
277 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
279 if (!$success) {
280 throw new Exception\RuntimeException($redis->getLastError());
283 return array();
287 * Add an item.
289 * @param string $normalizedKey
290 * @param mixed $value
291 * @return bool
292 * @throws Exception\RuntimeException
294 protected function internalAddItem(& $normalizedKey, & $value)
296 $redis = $this->getRedisResource();
297 try {
298 return $redis->setnx($this->namespacePrefix . $normalizedKey, $value);
299 } catch (RedisResourceException $e) {
300 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
305 * Internal method to remove an item.
307 * @param string &$normalizedKey Key which will be removed
309 * @return bool
310 * @throws Exception\RuntimeException
312 protected function internalRemoveItem(& $normalizedKey)
314 $redis = $this->getRedisResource();
315 try {
316 return (bool) $redis->delete($this->namespacePrefix . $normalizedKey);
317 } catch (RedisResourceException $e) {
318 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
323 * Internal method to increment an item.
325 * @param string $normalizedKey
326 * @param int $value
327 * @return int|bool The new value on success, false on failure
328 * @throws Exception\RuntimeException
330 protected function internalIncrementItem(& $normalizedKey, & $value)
332 $redis = $this->getRedisResource();
333 try {
334 return $redis->incrBy($this->namespacePrefix . $normalizedKey, $value);
335 } catch (RedisResourceException $e) {
336 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
341 * Internal method to decrement an item.
343 * @param string $normalizedKey
344 * @param int $value
345 * @return int|bool The new value on success, false on failure
346 * @throws Exception\RuntimeException
348 protected function internalDecrementItem(& $normalizedKey, & $value)
350 $redis = $this->getRedisResource();
351 try {
352 return $redis->decrBy($this->namespacePrefix . $normalizedKey, $value);
353 } catch (RedisResourceException $e) {
354 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
359 * Flush currently set DB
361 * @return bool
362 * @throws Exception\RuntimeException
364 public function flush()
366 $redis = $this->getRedisResource();
367 try {
368 return $redis->flushDB();
369 } catch (RedisResourceException $e) {
370 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
374 /* TotalSpaceCapableInterface */
377 * Get total space in bytes
379 * @return int|float
381 public function getTotalSpace()
383 $redis = $this->getRedisResource();
384 try {
385 $info = $redis->info();
386 } catch (RedisResourceException $e) {
387 throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
390 return $info['used_memory'];
394 /* status */
397 * Internal method to get capabilities of this adapter
399 * @return Capabilities
401 protected function internalGetCapabilities()
403 if ($this->capabilities === null) {
404 $this->capabilityMarker = new stdClass();
405 $minTtl = $this->resourceManager->getMajorVersion($this->resourceId) < 2 ? 0 : 1;
406 //without serialization redis supports only strings for simple
407 //get/set methods
408 $this->capabilities = new Capabilities(
409 $this,
410 $this->capabilityMarker,
411 array(
412 'supportedDatatypes' => array(
413 'NULL' => 'string',
414 'boolean' => 'string',
415 'integer' => 'string',
416 'double' => 'string',
417 'string' => true,
418 'array' => false,
419 'object' => false,
420 'resource' => false,
422 'supportedMetadata' => array(),
423 'minTtl' => $minTtl,
424 'maxTtl' => 0,
425 'staticTtl' => true,
426 'ttlPrecision' => 1,
427 'useRequestTime' => false,
428 'expiredRead' => false,
429 'maxKeyLength' => 255,
430 'namespaceIsPrefix' => true,
435 return $this->capabilities;