[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/cache/ -> sfSQLiteCache.class.php (source)

   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  }


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7