Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/*
3
 *  $Id: Db.php 7490 2010-03-29 19:53:27Z jwage $
4
 *
5
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
 *
17
 * This software consists of voluntary contributions made by many individuals
18
 * and is licensed under the LGPL. For more information, see
19
 * <http://www.doctrine-project.org>.
20
 */
21
 
22
/**
23
 * Database cache driver
24
 *
25
 * @package     Doctrine
26
 * @subpackage  Cache
27
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
28
 * @link        www.doctrine-project.org
29
 * @since       1.0
30
 * @version     $Revision: 7490 $
31
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
32
 * @author      Jonathan H. Wage <jonwage@gmail.com>
33
 */
34
class Doctrine_Cache_Db extends Doctrine_Cache_Driver
35
{
36
    /**
37
     * Configure Database cache driver. Specify instance of Doctrine_Connection
38
     * and tableName to store cache in
39
     *
40
     * @param array $_options      an array of options
41
     */
42
    public function __construct($options = array())
43
    {
44
        if ( ! isset($options['connection']) ||
45
             ! ($options['connection'] instanceof Doctrine_Connection)) {
46
 
47
            throw new Doctrine_Cache_Exception('Connection option not set.');
48
        }
49
 
50
        if ( ! isset($options['tableName']) ||
51
             ! is_string($options['tableName'])) {
52
 
53
             throw new Doctrine_Cache_Exception('Table name option not set.');
54
        }
55
 
56
 
57
        $this->_options = $options;
58
    }
59
 
60
    /**
61
     * Get the connection object associated with this cache driver
62
     *
63
     * @return Doctrine_Connection $connection
64
     */
65
    public function getConnection()
66
    {
67
        return $this->_options['connection'];
68
    }
69
 
70
    /**
71
     * Fetch a cache record from this cache driver instance
72
     *
73
     * @param string $id cache id
74
     * @param boolean $testCacheValidity        if set to false, the cache validity won't be tested
75
     * @return mixed  Returns either the cached data or false
76
     */
77
    protected function _doFetch($id, $testCacheValidity = true)
78
    {
79
        $sql = 'SELECT data, expire FROM ' . $this->_options['tableName']
80
             . ' WHERE id = ?';
81
 
82
        if ($testCacheValidity) {
83
            $sql .= " AND (expire is null OR expire > '" . date('Y-m-d H:i:s') . "')";
84
        }
85
 
86
        $result = $this->getConnection()->execute($sql, array($id))->fetchAll(Doctrine_Core::FETCH_NUM);
87
 
88
        if ( ! isset($result[0])) {
89
            return false;
90
        }
91
 
92
        return unserialize($this->_hex2bin($result[0][0]));
93
    }
94
 
95
    /**
96
     * Test if a cache record exists for the passed id
97
     *
98
     * @param string $id cache id
99
     * @return mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record
100
     */
101
    protected function _doContains($id)
102
    {
103
        $sql = 'SELECT id, expire FROM ' . $this->_options['tableName']
104
             . ' WHERE id = ?';
105
 
106
        $result = $this->getConnection()->fetchOne($sql, array($id));
107
 
108
        if (isset($result[0] )) {
109
            return time();
110
        }
111
        return false;
112
    }
113
 
114
    /**
115
     * Save a cache record directly. This method is implemented by the cache
116
     * drivers and used in Doctrine_Cache_Driver::save()
117
     *
118
     * @param string $id        cache id
119
     * @param string $data      data to cache
120
     * @param int $lifeTime     if != false, set a specific lifetime for this cache record (null => infinite lifeTime)
121
     * @return boolean true if no problem
122
     */
123
    protected function _doSave($id, $data, $lifeTime = false, $saveKey = true)
124
    {
125
        if ($this->contains($id)) {
126
            //record is in database, do update
127
            $sql = 'UPDATE ' . $this->_options['tableName']
128
                . ' SET data = ?, expire=? '
129
                . ' WHERE id = ?';
130
 
131
            if ($lifeTime) {
132
                $expire = date('Y-m-d H:i:s', time() + $lifeTime);
133
            } else {
134
                $expire = NULL;
135
            }
136
 
137
            $params = array(bin2hex(serialize($data)), $expire, $id);
138
        } else {
139
            //record is not in database, do insert
140
            $sql = 'INSERT INTO ' . $this->_options['tableName']
141
                . ' (id, data, expire) VALUES (?, ?, ?)';
142
 
143
            if ($lifeTime) {
144
                $expire = date('Y-m-d H:i:s', time() + $lifeTime);
145
            } else {
146
                $expire = NULL;
147
            }
148
 
149
            $params = array($id, bin2hex(serialize($data)), $expire);
150
        }
151
 
152
        return $this->getConnection()->exec($sql, $params);
153
    }
154
 
155
    /**
156
     * Remove a cache record directly. This method is implemented by the cache
157
     * drivers and used in Doctrine_Cache_Driver::delete()
158
     *
159
     * @param string $id cache id
160
     * @return boolean true if no problem
161
     */
162
    protected function _doDelete($id)
163
    {
164
        $sql = 'DELETE FROM ' . $this->_options['tableName'] . ' WHERE id = ?';
165
        return $this->getConnection()->exec($sql, array($id));
166
    }
167
 
168
    /**
169
     * Create the cache table
170
     *
171
     * @return void
172
     */
173
    public function createTable()
174
    {
175
        $name = $this->_options['tableName'];
176
 
177
        $fields = array(
178
            'id' => array(
179
                'type'   => 'string',
180
                'length' => 255
181
            ),
182
            'data' => array(
183
                'type'    => 'blob'
184
            ),
185
            'expire' => array(
186
                'type'    => 'timestamp'
187
            )
188
        );
189
 
190
        $options = array(
191
            'primary' => array('id')
192
        );
193
 
194
        $this->getConnection()->export->createTable($name, $fields, $options);
195
    }
196
 
197
    /**
198
     * Convert hex data to binary data. If passed data is not hex then
199
     * it is returned as is.
200
     *
201
     * @param string $hex
202
     * @return string $binary
203
     */
204
    protected function _hex2bin($hex)
205
    {
206
        if ( ! is_string($hex)) {
207
            return null;
208
        }
209
 
210
        if ( ! ctype_xdigit($hex)) {
211
            return $hex;
212
        }
213
 
214
        return pack("H*", $hex);
215
    }
216
 
217
    /**
218
     * Fetch an array of all keys stored in cache
219
     *
220
     * @return array Returns the array of cache keys
221
     */
222
    protected function _getCacheKeys()
223
    {
224
        $sql = 'SELECT id FROM ' . $this->_options['tableName'];
225
        $keys = array();
226
        $results = $this->getConnection()->execute($sql)->fetchAll(Doctrine_Core::FETCH_NUM);
227
        for ($i = 0, $count = count($results); $i < $count; $i++) {
228
            $keys[] = $results[$i][0];
229
        }
230
        return $keys;
231
    }
232
}