3
* Copyright 2007-2014 Horde LLC (http://www.horde.org/)
5
* See the enclosed file COPYING for license information (LGPL). If you
6
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
9
* @copyright 2007-2014 Horde LLC
10
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
15
* Cache storage in a SQL databsae.
17
* The table structure for the cache is as follows:
19
* CREATE TABLE horde_cache (
20
* cache_id VARCHAR(32) NOT NULL,
21
* cache_timestamp BIGINT NOT NULL,
22
* cache_data LONGBLOB,
25
* (Or on some other DBMS systems:)
28
* PRIMARY KEY (cache_id)
32
* @author Ben Klang <ben@alkaloid.net>
33
* @author Michael Slusarz <slusarz@horde.org>
35
* @copyright 2007-2014 Horde LLC
36
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
39
class Horde_Cache_Storage_Sql extends Horde_Cache_Storage_Base
42
* Handle for the current database connection.
44
* @var Horde_Db_Adapter
51
* @param array $params Parameters:
52
* - db: (Horde_Db_Adapter) [REQUIRED] The DB instance.
53
* - table: (string) The name of the cache table.
54
* DEFAULT: 'horde_cache'
56
public function __construct($params = array())
58
if (!isset($params['db'])) {
59
throw new InvalidArgumentException('Missing db parameter.');
62
parent::__construct(array_merge(array(
63
'table' => 'horde_cache',
69
protected function _initOb()
71
$this->_db = $this->_params['db'];
77
public function __destruct()
79
/* Only do garbage collection 0.1% of the time we create an object. */
80
if (substr(time(), -3) !== '000') {
84
$query = 'DELETE FROM ' . $this->_params['table'] .
85
' WHERE cache_expiration < ? AND cache_expiration <> 0';
86
$values = array(time());
89
$this->_db->delete($query, $values);
90
} catch (Horde_Db_Exception $e) {}
95
public function get($key, $lifetime = 0)
98
$key = hash('md5', $key);
101
$maxage = $timestamp - $lifetime;
103
/* Build SQL query. */
104
$query = 'SELECT cache_data FROM ' . $this->_params['table'] .
105
' WHERE cache_id = ?';
106
$values = array($key);
108
// 0 lifetime checks for objects which have no expiration
109
if ($lifetime != 0) {
110
$query .= ' AND cache_timestamp >= ?';
115
$result = $this->_db->selectValue($query, $values);
116
} catch (Horde_Db_Exception $e) {
121
/* No rows were found - cache miss */
122
if ($this->_logger) {
123
$this->_logger->log(sprintf('Cache miss: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
128
if ($this->_logger) {
129
$this->_logger->log(sprintf('Cache hit: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
137
public function set($key, $data, $lifetime = 0)
140
$key = hash('md5', $key);
144
// 0 lifetime indicates the object should not be GC'd.
145
$expiration = ($lifetime === 0)
147
: ($lifetime + $timestamp);
149
if ($this->_logger) {
150
$this->_logger->log(sprintf('Cache set: %s (Id %s set at %d expires at %d)', $okey, $key, $timestamp, $expiration), 'DEBUG');
153
// Remove any old cache data and prevent duplicate keys
154
$query = 'DELETE FROM ' . $this->_params['table'] . ' WHERE cache_id=?';
155
$values = array($key);
157
$this->_db->delete($query, $values);
158
} catch (Horde_Db_Exception $e) {}
160
/* Build SQL query. */
161
$query = 'INSERT INTO ' . $this->_params['table'] .
162
' (cache_id, cache_timestamp, cache_expiration, cache_data)' .
163
' VALUES (?, ?, ?, ?)';
164
$values = array($key, $timestamp, $expiration, $data);
167
$this->_db->insert($query, $values);
168
} catch (Horde_Db_Exception $e) {
169
throw new Horde_Cache_Exception($e);
175
public function exists($key, $lifetime = 0)
178
$key = hash('md5', $key);
180
/* Build SQL query. */
181
$query = 'SELECT 1 FROM ' . $this->_params['table'] .
182
' WHERE cache_id = ?';
183
$values = array($key);
185
// 0 lifetime checks for objects which have no expiration
186
if ($lifetime != 0) {
187
$query .= ' AND cache_timestamp >= ?';
188
$values[] = time() - $lifetime;
192
$result = $this->_db->selectValue($query, $values);
193
} catch (Horde_Db_Exception $e) {
198
if (empty($result)) {
199
if ($this->_logger) {
200
$this->_logger->log(sprintf('Cache exists() miss: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
205
if ($this->_logger) {
206
$this->_logger->log(sprintf('Cache exists() hit: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
214
public function expire($key)
216
$key = hash('md5', $key);
218
$query = 'DELETE FROM ' . $this->_params['table'] .
219
' WHERE cache_id = ?';
220
$values = array($key);
223
$this->_db->delete($query, $values);
224
} catch (Horde_Db_Exception $e) {
233
public function clear()
235
$query = 'DELETE FROM ' . $this->_params['table'];
238
$this->_db->delete($query);
239
} catch (Horde_Db_Exception $e) {
240
throw new Horde_Cache_Exception($e);