Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/*
4
 * This file is part of the symfony package.
5
 * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
 
11
/**
12
 * Cache class that stores cached content in a SQLite database.
13
 *
14
 * @package    symfony
15
 * @subpackage cache
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfSQLiteCache.class.php 23501 2009-11-01 22:54:37Z FabianLange $
18
 */
19
class sfSQLiteCache extends sfCache
20
{
21
  protected
22
    $dbh      = null,
23
    $database = '';
24
 
25
  /**
26
   * Initializes this sfCache instance.
27
   *
28
   * Available options:
29
   *
30
   * * database: File where to put the cache database (or :memory: to store cache in memory)
31
   *
32
   * * see sfCache for options available for all drivers
33
   *
34
   * @see sfCache
35
   */
36
  public function initialize($options = array())
37
  {
38
    if (!extension_loaded('SQLite') && !extension_loaded('pdo_SQLite'))
39
    {
40
      throw new sfConfigurationException('sfSQLiteCache class needs "sqlite" or "pdo_sqlite" extension to be loaded.');
41
    }
42
 
43
    parent::initialize($options);
44
 
45
    if (!$this->getOption('database'))
46
    {
47
      throw new sfInitializationException('You must pass a "database" option to initialize a sfSQLiteCache object.');
48
    }
49
 
50
    $this->setDatabase($this->getOption('database'));
51
  }
52
 
53
  /**
54
   * @see sfCache
55
   */
56
  public function getBackend()
57
  {
58
    return $this->dbh;
59
  }
60
 
61
  /**
62
   * @see sfCache
63
   */
64
  public function get($key, $default = null)
65
  {
66
    $data = $this->dbh->singleQuery(sprintf("SELECT data FROM cache WHERE key = '%s' AND timeout > %d", sqlite_escape_string($key), time()));
67
 
68
    return null === $data ? $default : $data;
69
  }
70
 
71
  /**
72
   * @see sfCache
73
   */
74
  public function has($key)
75
  {
76
    return (boolean) $this->dbh->query(sprintf("SELECT key FROM cache WHERE key = '%s' AND timeout > %d", sqlite_escape_string($key), time()))->numRows();
77
  }
78
 
79
  /**
80
   * @see sfCache
81
   */
82
  public function set($key, $data, $lifetime = null)
83
  {
84
    if ($this->getOption('automatic_cleaning_factor') > 0 && rand(1, $this->getOption('automatic_cleaning_factor')) == 1)
85
    {
86
      $this->clean(sfCache::OLD);
87
    }
88
 
89
    return (boolean) $this->dbh->query(sprintf("INSERT OR REPLACE INTO cache (key, data, timeout, last_modified) VALUES ('%s', '%s', %d, %d)", sqlite_escape_string($key), sqlite_escape_string($data), time() + $this->getLifetime($lifetime), time()));
90
  }
91
 
92
  /**
93
   * @see sfCache
94
   */
95
  public function remove($key)
96
  {
97
    return (boolean) $this->dbh->query(sprintf("DELETE FROM cache WHERE key = '%s'", sqlite_escape_string($key)));
98
  }
99
 
100
  /**
101
   * @see sfCache
102
   */
103
  public function removePattern($pattern)
104
  {
105
    return (boolean) $this->dbh->query(sprintf("DELETE FROM cache WHERE REGEXP('%s', key)", sqlite_escape_string(self::patternToRegexp($pattern))));
106
  }
107
 
108
  /**
109
   * @see sfCache
110
   */
111
  public function clean($mode = sfCache::ALL)
112
  {
113
    return (boolean) $this->dbh->query("DELETE FROM cache".(sfCache::OLD == $mode ? sprintf(" WHERE timeout < '%s'", time()) : ''))->numRows();
114
  }
115
 
116
  /**
117
   * @see sfCache
118
   */
119
  public function getTimeout($key)
120
  {
121
    $rs = $this->dbh->query(sprintf("SELECT timeout FROM cache WHERE key = '%s' AND timeout > %d", sqlite_escape_string($key), time()));
122
 
123
    return $rs->numRows() ? intval($rs->fetchSingle()) : 0;
124
  }
125
 
126
  /**
127
   * @see sfCache
128
   */
129
  public function getLastModified($key)
130
  {
131
    $rs = $this->dbh->query(sprintf("SELECT last_modified FROM cache WHERE key = '%s' AND timeout > %d", sqlite_escape_string($key), time()));
132
 
133
    return $rs->numRows() ? intval($rs->fetchSingle()) : 0;
134
  }
135
 
136
  /**
137
   * Sets the database name.
138
   *
139
   * @param string $database The database name where to store the cache
140
   */
141
  protected function setDatabase($database)
142
  {
143
    $this->database = $database;
144
 
145
    $new = false;
146
    if (':memory:' == $database)
147
    {
148
      $new = true;
149
    }
150
    else if (!is_file($database))
151
    {
152
      $new = true;
153
 
154
      // create cache dir if needed
155
      $dir = dirname($database);
156
      $current_umask = umask(0000);
157
      if (!is_dir($dir))
158
      {
159
        @mkdir($dir, 0777, true);
160
      }
161
 
162
      touch($database);
163
      umask($current_umask);
164
    }
165
 
166
    if (!$this->dbh = new SQLiteDatabase($this->database, 0644, $errmsg))
167
    {
168
      throw new sfCacheException(sprintf('Unable to connect to SQLite database: %s.', $errmsg));
169
    }
170
 
171
    $this->dbh->createFunction('regexp', array($this, 'removePatternRegexpCallback'), 2);
172
 
173
    if ($new)
174
    {
175
      $this->createSchema();
176
    }
177
  }
178
 
179
  /**
180
   * Callback used when deleting keys from cache.
181
   */
182
  public function removePatternRegexpCallback($regexp, $key)
183
  {
184
    return preg_match($regexp, $key);
185
  }
186
 
187
  /**
188
   * @see sfCache
189
   */
190
  public function getMany($keys)
191
  {
192
    $rows = $this->dbh->arrayQuery(sprintf("SELECT key, data FROM cache WHERE key IN ('%s') AND timeout > %d", implode('\', \'', array_map('sqlite_escape_string', $keys)), time()));
193
 
194
    $data = array();
195
    foreach ($rows as $row)
196
    {
197
      $data[$row['key']] = $row['data'];
198
    }
199
 
200
    return $data;
201
  }
202
 
203
  /**
204
   * Creates the database schema.
205
   *
206
   * @throws sfCacheException
207
   */
208
  protected function createSchema()
209
  {
210
    $statements = array(
211
      'CREATE TABLE [cache] (
212
        [key] VARCHAR(255),
213
        [data] LONGVARCHAR,
214
        [timeout] TIMESTAMP,
215
        [last_modified] TIMESTAMP
216
      )',
217
      'CREATE UNIQUE INDEX [cache_unique] ON [cache] ([key])',
218
    );
219
 
220
    foreach ($statements as $statement)
221
    {
222
      if (!$this->dbh->query($statement))
223
      {
224
        throw new sfCacheException(sqlite_error_string($this->dbh->lastError()));
225
      }
226
    }
227
  }
228
}