~ubuntu-branches/ubuntu/wily/php-horde-cache/wily

« back to all changes in this revision

Viewing changes to Horde_Cache-2.4.1/lib/Horde/Cache/Storage/Mongo.php

  • Committer: Package Import Robot
  • Author(s): Mathieu Parent
  • Date: 2014-04-13 09:11:33 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20140413091133-um8xxmlwuawkhbi5
Tags: 2.4.2-1
New upstream version 2.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
 * Copyright 2013-2014 Horde LLC (http://www.horde.org/)
4
 
 *
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.
7
 
 *
8
 
 * @category  Horde
9
 
 * @copyright 2013-2014 Horde LLC
10
 
 * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
11
 
 * @package   Cache
12
 
 */
13
 
 
14
 
/**
15
 
 * Cache storage in a MongoDB database.
16
 
 *
17
 
 * @author    Michael Slusarz <slusarz@horde.org>
18
 
 * @category  Horde
19
 
 * @copyright 2013-2014 Horde LLC
20
 
 * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
21
 
 * @package   Cache
22
 
 */
23
 
class Horde_Cache_Storage_Mongo extends Horde_Cache_Storage_Base
24
 
{
25
 
    /* Field names. */
26
 
    const CID = 'cid';
27
 
    const DATA = 'data';
28
 
    const EXPIRE = 'expire';
29
 
    const TIMESTAMP = 'ts';
30
 
 
31
 
    /**
32
 
     * The MongoDB Collection object for the cache data.
33
 
     *
34
 
     * @var MongoCollection
35
 
     */
36
 
    protected $_db;
37
 
 
38
 
    /**
39
 
     * Constructor.
40
 
     *
41
 
     * @param array $params  Parameters:
42
 
     *   - collection: (string) The collection name.
43
 
     *   - mongo_db: [REQUIRED] (Horde_Mongo_Client) A MongoDB client object.
44
 
     */
45
 
    public function __construct(array $params = array())
46
 
    {
47
 
        if (!isset($params['mongo_db'])) {
48
 
            throw new InvalidArgumentException('Missing mongo_db parameter.');
49
 
        }
50
 
 
51
 
        parent::__construct(array_merge(array(
52
 
            'collection' => 'horde_cache'
53
 
        ), $params));
54
 
    }
55
 
 
56
 
    /**
57
 
     * Destructor.
58
 
     */
59
 
    public function __destruct()
60
 
    {
61
 
        /* Only do garbage collection 0.1% of the time we create an object. */
62
 
        if (substr(time(), -3) === '000') {
63
 
            try {
64
 
                $this->_db->remove(array(
65
 
                    self::EXPIRE => array(
66
 
                        '$exists' => true,
67
 
                        '$lt' => time()
68
 
                    )
69
 
                ));
70
 
            } catch (MongoException $e) {
71
 
                $this->_logger->log($e->getMessage(), 'DEBUG');
72
 
            }
73
 
        }
74
 
    }
75
 
 
76
 
    /**
77
 
     */
78
 
    protected function _initOb()
79
 
    {
80
 
        $this->_db = $this->_params['mongo_db']->selectCollection(null, $this->_params['collection']);
81
 
    }
82
 
 
83
 
    /**
84
 
     */
85
 
    public function get($key, $lifetime = 0)
86
 
    {
87
 
        $okey = $key;
88
 
        $key = $this->_getCid($key);
89
 
 
90
 
        /* Build SQL query. */
91
 
        $query = array(
92
 
            self::CID => $key
93
 
        );
94
 
 
95
 
        // 0 lifetime checks for objects which have no expiration
96
 
        if ($lifetime != 0) {
97
 
            $query[self::TIMESTAMP] = array('$gte' => time() - $lifetime);
98
 
        }
99
 
 
100
 
        try {
101
 
            $result = $this->_db->findOne($query, array(self::DATA));
102
 
        } catch (MongoException $e) {
103
 
            $this->_logger->log($e->getMessage(), 'DEBUG');
104
 
            return false;
105
 
        }
106
 
 
107
 
        if (empty($result)) {
108
 
            /* No rows were found - cache miss */
109
 
            if ($this->_logger) {
110
 
                $this->_logger->log(sprintf('Cache miss: %s (cache ID %s)', $okey, $key), 'DEBUG');
111
 
            }
112
 
            return false;
113
 
        }
114
 
 
115
 
        if ($this->_logger) {
116
 
            $this->_logger->log(sprintf('Cache hit: %s (cache ID %s)', $okey, $key), 'DEBUG');
117
 
        }
118
 
 
119
 
        return $result[self::DATA]->bin;
120
 
    }
121
 
 
122
 
    /**
123
 
     */
124
 
    public function set($key, $data, $lifetime = 0)
125
 
    {
126
 
        $okey = $key;
127
 
        $key = $this->_getCid($key);
128
 
        $curr = time();
129
 
 
130
 
        $data = array(
131
 
            self::CID => $key,
132
 
            self::DATA => new MongoBinData($data, MongoBinData::BYTE_ARRAY),
133
 
            self::TIMESTAMP => $curr
134
 
        );
135
 
 
136
 
        // 0 lifetime indicates the object should not be GC'd.
137
 
        if (!empty($lifetime)) {
138
 
            $data[self::EXPIRE] = intval($lifetime) + $curr;
139
 
        }
140
 
 
141
 
        if ($this->_logger) {
142
 
            $this->_logger->log(sprintf(
143
 
                'Cache set: %s (id %s set at %s%s)',
144
 
                $okey,
145
 
                $key,
146
 
                date('r', $curr),
147
 
                (isset($data[self::EXPIRE]) ? ' expires at ' . date('r', $data[self::EXPIRE]) : '')
148
 
            ), 'DEBUG');
149
 
        }
150
 
 
151
 
        // Remove any old cache data and prevent duplicate keys
152
 
        try {
153
 
            $this->_db->update(array(
154
 
                self::CID => $key
155
 
            ), array(
156
 
                '$set' => $data
157
 
            ), array(
158
 
                'upsert' => true,
159
 
                'w' => 0
160
 
            ));
161
 
        } catch (MongoException $e) {
162
 
            $this->_logger->log($e->getMessage(), 'DEBUG');
163
 
            return false;
164
 
        }
165
 
    }
166
 
 
167
 
    /**
168
 
     */
169
 
    public function exists($key, $lifetime = 0)
170
 
    {
171
 
        $okey = $key;
172
 
        $key = $this->_getCid($key);
173
 
 
174
 
        /* Build SQL query. */
175
 
        $query = array(
176
 
            self::CID => $key
177
 
        );
178
 
 
179
 
        // 0 lifetime checks for objects which have no expiration
180
 
        if ($lifetime != 0) {
181
 
            $query[self::TIMESTAMP] = array('$gte' => time() - $lifetime);
182
 
        }
183
 
 
184
 
        try {
185
 
            $result = $this->_db->findOne($query);
186
 
        } catch (MongoException $e) {
187
 
            $this->_logger->log($e->getMessage(), 'DEBUG');
188
 
            return false;
189
 
        }
190
 
 
191
 
        if (is_null($result)) {
192
 
            if ($this->_logger) {
193
 
                $this->_logger->log(sprintf('Cache exists() miss: %s (cache ID %s)', $okey, $key), 'DEBUG');
194
 
            }
195
 
            return false;
196
 
        }
197
 
 
198
 
        if ($this->_logger) {
199
 
            $this->_logger->log(sprintf('Cache exists() hit: %s (cache ID %s)', $okey, $key), 'DEBUG');
200
 
        }
201
 
 
202
 
        return true;
203
 
    }
204
 
 
205
 
    /**
206
 
     */
207
 
    public function expire($key)
208
 
    {
209
 
        $okey = $key;
210
 
        $key = $this->_getCid($key);
211
 
 
212
 
        try {
213
 
            $this->_db->remove(array(
214
 
                self::CID => $key
215
 
            ));
216
 
            $this->_logger->log(sprintf('Cache expire: %s (cache ID %s)', $okey, $key), 'DEBUG');
217
 
            return true;
218
 
        } catch (MongoException $e) {
219
 
            return false;
220
 
        }
221
 
    }
222
 
 
223
 
    /**
224
 
     */
225
 
    public function clear()
226
 
    {
227
 
        $this->_db->drop();
228
 
    }
229
 
 
230
 
    /**
231
 
     * Gets the cache ID for a key.
232
 
     *
233
 
     * @param string $key  The key.
234
 
     *
235
 
     * @return string  The cache ID.
236
 
     */
237
 
    protected function _getCid($key)
238
 
    {
239
 
        return hash('md5', $key);
240
 
    }
241
 
 
242
 
}