[ Index ] |
|
Code source de Symfony 1.0.0 |
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 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 3198 2007-01-08 20:36:20Z fabien $ 18 */ 19 class sfSQLiteCache extends sfCache 20 { 21 const DEFAULT_NAMESPACE = ''; 22 23 protected $conn = null; 24 25 /** 26 * File where to put the cache database (or :memory: to store cache in memory) 27 */ 28 protected $database = ''; 29 30 /** 31 * Disable / Tune the automatic cleaning process 32 * 33 * The automatic cleaning process destroy too old (for the given life time) 34 * cache files when a new cache file is written. 35 * 0 => no automatic cache cleaning 36 * 1 => systematic cache cleaning 37 * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write 38 */ 39 protected $automaticCleaningFactor = 500; 40 41 /** 42 * Constructor. 43 * 44 * @param string The database name 45 */ 46 public function __construct($database = null) 47 { 48 if (!extension_loaded('sqlite')) 49 { 50 throw new sfConfigurationException('sfSQLiteCache class needs "sqlite" extension'); 51 } 52 53 $this->setDatabase($database); 54 } 55 56 /** 57 * Initializes the cache. 58 * 59 * @param array An array of options 60 * Available options: 61 * - database: database name 62 * - automaticCleaningFactor: disable / tune automatic cleaning process (int) 63 * 64 */ 65 public function initialize($options = array()) 66 { 67 if (isset($options['database'])) 68 { 69 $this->setDatabase($options['database']); 70 unset($options['database']); 71 } 72 73 $availableOptions = array('automaticCleaningFactor'); 74 foreach ($options as $key => $value) 75 { 76 if (!in_array($key, $availableOptions)) 77 { 78 sfLogger::getInstance()->error(sprintf('sfSQLiteCache cannot take "%s" as an option', $key)); 79 } 80 81 $this->$key = $value; 82 } 83 } 84 85 /** 86 * Sets the database name. 87 * 88 * @param string The database name where to store the cache 89 */ 90 public function setDatabase($database) 91 { 92 if (!$database) 93 { 94 return; 95 } 96 97 $this->database = $database; 98 99 $new = false; 100 if (':memory:' == $database) 101 { 102 $new = true; 103 } 104 elseif (!is_file($database)) 105 { 106 $new = true; 107 108 // create cache dir if needed 109 $dir = dirname($database); 110 $current_umask = umask(0000); 111 if (!is_dir($dir)) 112 { 113 @mkdir($dir, 0777, true); 114 } 115 116 touch($database); 117 umask($current_umask); 118 } 119 120 if (!($this->conn = @sqlite_open($this->database, 0644, $errmsg))) 121 { 122 throw new sfException(sprintf("Unable to connect to SQLite database: %s", $errmsg)); 123 } 124 125 if ($new) 126 { 127 $this->createSchema(); 128 } 129 } 130 131 /** 132 * Creates the database schema. 133 * 134 * @throws sfException 135 */ 136 protected function createSchema() 137 { 138 $statements = array( 139 "CREATE TABLE [cache] ( 140 [id] VARCHAR(255), 141 [namespace] VARCHAR(255), 142 [data] LONGVARCHAR, 143 [created_at] TIMESTAMP 144 )", 145 "CREATE INDEX [cache_unique] ON [cache] ([namespace], [id])", 146 ); 147 148 foreach ($statements as $statement) 149 { 150 if (!sqlite_query($statement, $this->conn)) 151 { 152 throw new sfException(sqlite_error_string(sqlite_last_error($this->database))); 153 } 154 } 155 } 156 157 /** 158 * Destructor. 159 */ 160 public function __destruct() 161 { 162 sqlite_close($this->conn); 163 } 164 165 /** 166 * Gets the database name. 167 * 168 * @return string The database name 169 */ 170 public function getDatabase() 171 { 172 return $this->database; 173 } 174 175 /** 176 * Tests if a cache is available and (if yes) returns it. 177 * 178 * @param string The cache id 179 * @param string The name of the cache namespace 180 * @param boolean If set to true, the cache validity won't be tested 181 * 182 * @return string The data in the cache (or null if no cache available) 183 * 184 * @see sfCache 185 */ 186 public function get($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false) 187 { 188 $statement = sprintf("SELECT data FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace)); 189 if (!$doNotTestCacheValidity) 190 { 191 $statement .= sprintf(" AND created_at > '%s'", sqlite_escape_string($this->refreshTime)); 192 } 193 194 $rs = sqlite_query($statement, $this->conn); 195 196 return sqlite_num_rows($rs) ? sqlite_fetch_single($rs) : null; 197 } 198 199 /** 200 * Returns true if there is a cache for the given id and namespace. 201 * 202 * @param string The cache id 203 * @param string The name of the cache namespace 204 * @param boolean If set to true, the cache validity won't be tested 205 * 206 * @return boolean true if the cache exists, false otherwise 207 * 208 * @see sfCache 209 */ 210 public function has($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false) 211 { 212 $statement = sprintf("SELECT id FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace)); 213 if (!$doNotTestCacheValidity) 214 { 215 $statement .= sprintf(" AND created_at > '%s'", sqlite_escape_string($this->refreshTime)); 216 } 217 218 return sqlite_num_rows(sqlite_query($statement, $this->conn)) ? true : false; 219 } 220 221 /** 222 * Saves some data in the cache. 223 * 224 * @param string The cache id 225 * @param string The name of the cache namespace 226 * @param string The data to put in cache 227 * 228 * @return boolean true if no problem 229 * 230 * @see sfCache 231 */ 232 public function set($id, $namespace = self::DEFAULT_NAMESPACE, $data) 233 { 234 if ($this->automaticCleaningFactor > 0) 235 { 236 $rand = rand(1, $this->automaticCleaningFactor); 237 if ($rand == 1) 238 { 239 $this->clean(false, 'old'); 240 } 241 } 242 243 if (!$this->has($id, $namespace)) 244 { 245 $statement = sprintf("INSERT INTO cache (id, namespace, data, created_at) VALUES ('%s', '%s', '%s', %d)", sqlite_escape_string($id), sqlite_escape_string($namespace), sqlite_escape_string($data), time()); 246 } 247 else 248 { 249 $statement = sprintf("UPDATE cache SET data = '%s', created_at = %s WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($data), time(), sqlite_escape_string($id), sqlite_escape_string($namespace)); 250 } 251 252 if (sqlite_query($statement, $this->conn)) 253 { 254 return true; 255 } 256 257 return false; 258 } 259 260 /** 261 * Removes an element from the cache. 262 * 263 * @param string The cache id 264 * @param string The name of the cache namespace 265 * 266 * @return boolean true if no problem 267 * 268 * @see sfCache 269 */ 270 public function remove($id, $namespace = self::DEFAULT_NAMESPACE) 271 { 272 $statement = sprintf("DELETE FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace)); 273 if (sqlite_query($statement, $this->conn)) 274 { 275 return true; 276 } 277 278 return false; 279 } 280 281 /** 282 * Cleans the cache. 283 * 284 * If no namespace is specified all cache files will be destroyed 285 * else only cache files of the specified namespace will be destroyed. 286 * 287 * @param string The name of the cache namespace 288 * 289 * @return boolean true if no problem 290 */ 291 public function clean($namespace = null, $mode = 'all') 292 { 293 if (!$namespace) 294 { 295 $statement = "DELETE FROM cache"; 296 } 297 else 298 { 299 $statement = sprintf("DELETE FROM cache WHERE namespace LIKE '%s%%'", $namespace); 300 } 301 302 if ('old' == $mode) 303 { 304 $statement .= sprintf(" %s created_at < '%s'", $namespace ? 'AND' : 'WHERE', sqlite_escape_string($this->refreshTime)); 305 } 306 307 return sqlite_num_rows(sqlite_query($statement, $this->conn)) ? true : false; 308 } 309 310 public function lastModified($id, $namespace = self::DEFAULT_NAMESPACE) 311 { 312 $statement = sprintf("SELECT created_at FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace)); 313 $rs = sqlite_query($statement, $this->conn); 314 315 return sqlite_num_rows($rs) ? intval(sqlite_fetch_single($rs)) : 0; 316 } 317 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |