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:
53
* - db: (Horde_Db_Adapter) [REQUIRED] The DB instance.
54
* - table: (string) The name of the cache table.
55
* DEFAULT: 'horde_cache'
58
public function __construct($params = array())
60
if (!isset($params['db'])) {
61
throw new InvalidArgumentException('Missing db parameter.');
64
parent::__construct(array_merge(array(
65
'table' => 'horde_cache',
71
protected function _initOb()
73
$this->_db = $this->_params['db'];
79
public function __destruct()
81
/* Only do garbage collection 0.1% of the time we create an object. */
82
if (substr(time(), -3) !== '000') {
86
$query = 'DELETE FROM ' . $this->_params['table'] .
87
' WHERE cache_expiration < ? AND cache_expiration <> 0';
88
$values = array(time());
91
$this->_db->delete($query, $values);
92
} catch (Horde_Db_Exception $e) {}
97
public function get($key, $lifetime = 0)
100
$key = hash('md5', $key);
103
$maxage = $timestamp - $lifetime;
105
/* Build SQL query. */
106
$query = 'SELECT cache_data FROM ' . $this->_params['table'] .
107
' WHERE cache_id = ?';
108
$values = array($key);
110
// 0 lifetime checks for objects which have no expiration
111
if ($lifetime != 0) {
112
$query .= ' AND cache_timestamp >= ?';
117
$result = $this->_db->selectValue($query, $values);
118
} catch (Horde_Db_Exception $e) {
123
/* No rows were found - cache miss */
124
if ($this->_logger) {
125
$this->_logger->log(sprintf('Cache miss: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
130
if ($this->_logger) {
131
$this->_logger->log(sprintf('Cache hit: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
139
public function set($key, $data, $lifetime = 0)
142
$key = hash('md5', $key);
146
// 0 lifetime indicates the object should not be GC'd.
147
$expiration = ($lifetime === 0)
149
: ($lifetime + $timestamp);
151
if ($this->_logger) {
152
$this->_logger->log(sprintf('Cache set: %s (Id %s set at %d expires at %d)', $okey, $key, $timestamp, $expiration), 'DEBUG');
155
// Remove any old cache data and prevent duplicate keys
156
$query = 'DELETE FROM ' . $this->_params['table'] . ' WHERE cache_id=?';
157
$values = array($key);
159
$this->_db->delete($query, $values);
160
} catch (Horde_Db_Exception $e) {}
162
/* Build SQL query. */
163
$query = 'INSERT INTO ' . $this->_params['table'] .
164
' (cache_id, cache_timestamp, cache_expiration, cache_data)' .
165
' VALUES (?, ?, ?, ?)';
166
$values = array($key, $timestamp, $expiration, $data);
169
$this->_db->insert($query, $values);
170
} catch (Horde_Db_Exception $e) {
171
throw new Horde_Cache_Exception($e);
177
public function exists($key, $lifetime = 0)
180
$key = hash('md5', $key);
182
/* Build SQL query. */
183
$query = 'SELECT 1 FROM ' . $this->_params['table'] .
184
' WHERE cache_id = ?';
185
$values = array($key);
187
// 0 lifetime checks for objects which have no expiration
188
if ($lifetime != 0) {
189
$query .= ' AND cache_timestamp >= ?';
190
$values[] = time() - $lifetime;
194
$result = $this->_db->selectValue($query, $values);
195
} catch (Horde_Db_Exception $e) {
200
if (empty($result)) {
201
if ($this->_logger) {
202
$this->_logger->log(sprintf('Cache exists() miss: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
207
if ($this->_logger) {
208
$this->_logger->log(sprintf('Cache exists() hit: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
216
public function expire($key)
218
$key = hash('md5', $key);
220
$query = 'DELETE FROM ' . $this->_params['table'] .
221
' WHERE cache_id = ?';
222
$values = array($key);
225
$this->_db->delete($query, $values);
226
} catch (Horde_Db_Exception $e) {
235
public function clear()
237
$query = 'DELETE FROM ' . $this->_params['table'];
240
$this->_db->delete($query);
241
} catch (Horde_Db_Exception $e) {
242
throw new Horde_Cache_Exception($e);