Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 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' => Inflector::slug(APP_DIR) . '_',
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
		try {
83
			$this->_Redis = new Redis();
84
			if (!empty($this->settings['unix_socket'])) {
85
				$return = $this->_Redis->connect($this->settings['unix_socket']);
86
			} elseif (empty($this->settings['persistent'])) {
87
				$return = $this->_Redis->connect($this->settings['server'], $this->settings['port'], $this->settings['timeout']);
88
			} else {
89
				$persistentId = $this->settings['port'] . $this->settings['timeout'] . $this->settings['database'];
90
				$return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout'], $persistentId);
91
			}
92
		} catch (RedisException $e) {
93
			$return = false;
94
		}
95
		if (!$return) {
96
			return false;
97
		}
98
		if ($this->settings['password'] && !$this->_Redis->auth($this->settings['password'])) {
99
			return false;
100
		}
101
		return $this->_Redis->select($this->settings['database']);
102
	}
103
 
104
/**
105
 * Write data for key into cache.
106
 *
107
 * @param string $key Identifier for the data
108
 * @param mixed $value Data to be cached
109
 * @param int $duration How long to cache the data, in seconds
110
 * @return bool True if the data was successfully cached, false on failure
111
 */
112
	public function write($key, $value, $duration) {
113
		if (!is_int($value)) {
114
			$value = serialize($value);
115
		}
116
		if ($duration === 0) {
117
			return $this->_Redis->set($key, $value);
118
		}
119
 
120
		return $this->_Redis->setex($key, $duration, $value);
121
	}
122
 
123
/**
124
 * Read a key from the cache
125
 *
126
 * @param string $key Identifier for the data
127
 * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
128
 */
129
	public function read($key) {
130
		$value = $this->_Redis->get($key);
131
		if (ctype_digit($value)) {
132
			$value = (int)$value;
133
		}
134
		if ($value !== false && is_string($value)) {
135
			$value = unserialize($value);
136
		}
137
		return $value;
138
	}
139
 
140
/**
141
 * Increments the value of an integer cached key
142
 *
143
 * @param string $key Identifier for the data
144
 * @param int $offset How much to increment
145
 * @return New incremented value, false otherwise
146
 * @throws CacheException when you try to increment with compress = true
147
 */
148
	public function increment($key, $offset = 1) {
149
		return (int)$this->_Redis->incrBy($key, $offset);
150
	}
151
 
152
/**
153
 * Decrements the value of an integer cached key
154
 *
155
 * @param string $key Identifier for the data
156
 * @param int $offset How much to subtract
157
 * @return New decremented value, false otherwise
158
 * @throws CacheException when you try to decrement with compress = true
159
 */
160
	public function decrement($key, $offset = 1) {
161
		return (int)$this->_Redis->decrBy($key, $offset);
162
	}
163
 
164
/**
165
 * Delete a key from the cache
166
 *
167
 * @param string $key Identifier for the data
168
 * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
169
 */
170
	public function delete($key) {
171
		return $this->_Redis->delete($key) > 0;
172
	}
173
 
174
/**
175
 * Delete all keys from the cache
176
 *
177
 * @param bool $check Whether or not expiration keys should be checked. If
178
 *   true, no keys will be removed as cache will rely on redis TTL's.
179
 * @return bool True if the cache was successfully cleared, false otherwise
180
 */
181
	public function clear($check) {
182
		if ($check) {
183
			return true;
184
		}
185
		$keys = $this->_Redis->getKeys($this->settings['prefix'] . '*');
186
		$this->_Redis->del($keys);
187
 
188
		return true;
189
	}
190
 
191
/**
192
 * Returns the `group value` for each of the configured groups
193
 * If the group initial value was not found, then it initializes
194
 * the group accordingly.
195
 *
196
 * @return array
197
 */
198
	public function groups() {
199
		$result = array();
200
		foreach ($this->settings['groups'] as $group) {
201
			$value = $this->_Redis->get($this->settings['prefix'] . $group);
202
			if (!$value) {
203
				$value = 1;
204
				$this->_Redis->set($this->settings['prefix'] . $group, $value);
205
			}
206
			$result[] = $group . $value;
207
		}
208
		return $result;
209
	}
210
 
211
/**
212
 * Increments the group value to simulate deletion of all keys under a group
213
 * old values will remain in storage until they expire.
214
 *
215
 * @param string $group The group name to clear.
216
 * @return bool success
217
 */
218
	public function clearGroup($group) {
219
		return (bool)$this->_Redis->incr($this->settings['prefix'] . $group);
220
	}
221
 
222
/**
223
 * Disconnects from the redis server
224
 */
225
	public function __destruct() {
226
		if (!$this->settings['persistent']) {
227
			$this->_Redis->close();
228
		}
229
	}
230
}