Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12345 anikendra 1
<?php
2
/**
3
 * Redis storage engine for cache
4
 *
5
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://cakephp.org CakePHP(tm) Project
14
 * @package       Cake.Cache.Engine
15
 * @since         CakePHP(tm) v 2.2
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
/**
20
 * Redis storage engine for cache.
21
 *
22
 * @package       Cake.Cache.Engine
23
 */
24
class RedisEngine extends CacheEngine {
25
 
26
/**
27
 * Redis wrapper.
28
 *
29
 * @var Redis
30
 */
31
	protected $_Redis = null;
32
 
33
/**
34
 * Settings
35
 *
36
 *  - server = string URL or ip to the Redis server host
37
 *  - database = integer database number to use for connection
38
 *  - port = integer port number to the Redis server (default: 6379)
39
 *  - timeout = float timeout in seconds (default: 0)
40
 *  - persistent = boolean Connects to the Redis server with a persistent connection (default: true)
41
 *  - unix_socket = path to the unix socket file (default: false)
42
 *
43
 * @var array
44
 */
45
	public $settings = array();
46
 
47
/**
48
 * Initialize the Cache Engine
49
 *
50
 * Called automatically by the cache frontend
51
 * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
52
 *
53
 * @param array $settings array of setting for the engine
54
 * @return bool True if the engine has been successfully initialized, false if not
55
 */
56
	public function init($settings = array()) {
57
		if (!class_exists('Redis')) {
58
			return false;
59
		}
60
		parent::init(array_merge(array(
61
			'engine' => 'Redis',
62
			'prefix' => null,
63
			'server' => '127.0.0.1',
64
			'database' => 0,
65
			'port' => 6379,
66
			'password' => false,
67
			'timeout' => 0,
68
			'persistent' => true,
69
			'unix_socket' => false
70
			), $settings)
71
		);
72
 
73
		return $this->_connect();
74
	}
75
 
76
/**
77
 * Connects to a Redis server
78
 *
79
 * @return bool True if Redis server was connected
80
 */
81
	protected function _connect() {
82
		$return = false;
83
		try {
84
			$this->_Redis = new Redis();
85
			if (!empty($this->settings['unix_socket'])) {
86
				$return = $this->_Redis->connect($this->settings['unix_socket']);
87
			} elseif (empty($this->settings['persistent'])) {
88
				$return = $this->_Redis->connect($this->settings['server'], $this->settings['port'], $this->settings['timeout']);
89
			} else {
90
				$persistentId = $this->settings['port'] . $this->settings['timeout'] . $this->settings['database'];
91
				$return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout'], $persistentId);
92
			}
93
		} catch (RedisException $e) {
94
			return false;
95
		}
96
		if ($return && $this->settings['password']) {
97
			$return = $this->_Redis->auth($this->settings['password']);
98
		}
99
		if ($return) {
100
			$return = $this->_Redis->select($this->settings['database']);
101
		}
102
		return $return;
103
	}
104
 
105
/**
106
 * Write data for key into cache.
107
 *
108
 * @param string $key Identifier for the data
109
 * @param mixed $value Data to be cached
110
 * @param int $duration How long to cache the data, in seconds
111
 * @return bool True if the data was successfully cached, false on failure
112
 */
113
	public function write($key, $value, $duration) {
114
		if (!is_int($value)) {
115
			$value = serialize($value);
116
		}
117
		if ($duration === 0) {
118
			return $this->_Redis->set($key, $value);
119
		}
120
 
121
		return $this->_Redis->setex($key, $duration, $value);
122
	}
123
 
124
/**
125
 * Read a key from the cache
126
 *
127
 * @param string $key Identifier for the data
128
 * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
129
 */
130
	public function read($key) {
131
		$value = $this->_Redis->get($key);
132
		if (ctype_digit($value)) {
133
			$value = (int)$value;
134
		}
135
		if ($value !== false && is_string($value)) {
136
			$value = unserialize($value);
137
		}
138
		return $value;
139
	}
140
 
141
/**
142
 * Increments the value of an integer cached key
143
 *
144
 * @param string $key Identifier for the data
145
 * @param int $offset How much to increment
146
 * @return New incremented value, false otherwise
147
 * @throws CacheException when you try to increment with compress = true
148
 */
149
	public function increment($key, $offset = 1) {
150
		return (int)$this->_Redis->incrBy($key, $offset);
151
	}
152
 
153
/**
154
 * Decrements the value of an integer cached key
155
 *
156
 * @param string $key Identifier for the data
157
 * @param int $offset How much to subtract
158
 * @return New decremented value, false otherwise
159
 * @throws CacheException when you try to decrement with compress = true
160
 */
161
	public function decrement($key, $offset = 1) {
162
		return (int)$this->_Redis->decrBy($key, $offset);
163
	}
164
 
165
/**
166
 * Delete a key from the cache
167
 *
168
 * @param string $key Identifier for the data
169
 * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
170
 */
171
	public function delete($key) {
172
		return $this->_Redis->delete($key) > 0;
173
	}
174
 
175
/**
176
 * Delete all keys from the cache
177
 *
178
 * @param bool $check Whether or not expiration keys should be checked. If
179
 *   true, no keys will be removed as cache will rely on redis TTL's.
180
 * @return bool True if the cache was successfully cleared, false otherwise
181
 */
182
	public function clear($check) {
183
		if ($check) {
184
			return true;
185
		}
186
		$keys = $this->_Redis->getKeys($this->settings['prefix'] . '*');
187
		$this->_Redis->del($keys);
188
 
189
		return true;
190
	}
191
 
192
/**
193
 * Returns the `group value` for each of the configured groups
194
 * If the group initial value was not found, then it initializes
195
 * the group accordingly.
196
 *
197
 * @return array
198
 */
199
	public function groups() {
200
		$result = array();
201
		foreach ($this->settings['groups'] as $group) {
202
			$value = $this->_Redis->get($this->settings['prefix'] . $group);
203
			if (!$value) {
204
				$value = 1;
205
				$this->_Redis->set($this->settings['prefix'] . $group, $value);
206
			}
207
			$result[] = $group . $value;
208
		}
209
		return $result;
210
	}
211
 
212
/**
213
 * Increments the group value to simulate deletion of all keys under a group
214
 * old values will remain in storage until they expire.
215
 *
216
 * @param string $group The group name to clear.
217
 * @return bool success
218
 */
219
	public function clearGroup($group) {
220
		return (bool)$this->_Redis->incr($this->settings['prefix'] . $group);
221
	}
222
 
223
/**
224
 * Disconnects from the redis server
225
 */
226
	public function __destruct() {
227
		if (!$this->settings['persistent']) {
228
			$this->_Redis->close();
229
		}
230
	}
231
}