From 66843b23960e17991db0b4f7b01487063b2234bc Mon Sep 17 00:00:00 2001 From: xue <> Date: Tue, 4 Apr 2006 04:08:48 +0000 Subject: Refactored cache classes with support for cache dependency --- framework/Caching/TAPCCache.php | 152 +++++++++++----------------- framework/Caching/TCache.php | 200 +++++++++++++++++++++++++++++-------- framework/Caching/TMemCache.php | 83 +++++---------- framework/Caching/TSqliteCache.php | 102 ++++++------------- framework/Web/UI/TThemeManager.php | 11 +- framework/interfaces.php | 73 ++++++++++++++ 6 files changed, 355 insertions(+), 266 deletions(-) (limited to 'framework') diff --git a/framework/Caching/TAPCCache.php b/framework/Caching/TAPCCache.php index 0ed1d433..4c5f2779 100644 --- a/framework/Caching/TAPCCache.php +++ b/framework/Caching/TAPCCache.php @@ -35,118 +35,88 @@ * cache module. It can be accessed via {@link TApplication::getCache()}. * * TAPCCache may be configured in application configuration file as follows + * * + * * * @author Alban Hanry * @version $Revision: $ $Date: $ * @package System.Caching * @since 3.0b */ -class TAPCCache extends TModule implements ICache +class TAPCCache extends TCache { - /** - * @var boolean if the module is initialized - */ - private $_initialized=false; - - /** - * @var string a unique prefix used to identify this cache instance from the others - */ - protected $_prefix=null; - /** * Initializes this module. * This method is required by the IModule interface. * @param TXmlElement configuration for this module, can be null * @throws TConfigurationException if apc extension is not installed or not started, check your php.ini */ - public function init($config) - { + public function init($config) + { if(!extension_loaded('apc')) throw new TConfigurationException('apccache_extension_required'); - $application=$this->getApplication(); - $this->_prefix=$application->getUniqueID(); - $application->setCache($this); - $this->_initialized=true; - } - - /** - * Retrieves a value from cache with a specified key. - * @return mixed the value stored in cache, false if the value is not in the cache or expired. - */ - public function get($key) - { - if(($value=apc_fetch($this->_prefix.$key))!==false) - return Prado::unserialize($value); - else - return $value; - } + parent::init($config); + } - /** - * Stores a value identified by a key into cache. - * If the cache already contains such a key, the existing value and - * expiration time will be replaced with the new ones. - * - * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * @return boolean true if the value is successfully stored into cache, false otherwise - */ - public function set($key,$value,$expiry=0) - { - return apc_store($this->_prefix.$key,Prado::serialize($value),$expiry); - } + /** + * Retrieves a value from cache with a specified key. + * This is the implementation of the method declared in the parent class. + * @param string a unique key identifying the cached value + * @return string the value stored in cache, false if the value is not in the cache or expired. + */ + protected function getValue($key) + { + return apc_fetch($key); + } - /** - * Stores a value identified by a key into cache if the cache does not contain this key. - * APC does not support this mode. So calling this method will raise an exception. - * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * @return boolean true if the value is successfully stored into cache, false otherwise - * @throw new TNotSupportedException if this method is invoked - */ - public function add($key,$value,$expiry=0) - { - throw new TNotSupportedException('apccache_add_unsupported'); - } + /** + * Stores a value identified by a key in cache. + * This is the implementation of the method declared in the parent class. + * + * @param string the key identifying the value to be cached + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + protected function setValue($key,$value,$expire) + { + return apc_store($key,$value,$expire); + } - /** - * Stores a value identified by a key into cache only if the cache contains this key. - * The existing value and expiration time will be overwritten with the new ones. - * APC does not support this mode. So calling this method will raise an exception. - * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * @return boolean true if the value is successfully stored into cache, false otherwise - * @throw new TNotSupportedException if this method is invoked - */ - public function replace($key,$value,$expiry=0) - { - throw new TNotSupportedException('apccache_replace_unsupported'); - } + /** + * Stores a value identified by a key into cache if the cache does not contain this key. + * This is the implementation of the method declared in the parent class. + * + * @param string the key identifying the value to be cached + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + protected function addValue($key,$value,$expire) + { + throw new TNotSupportedException('apccache_add_unsupported'); + } - /** - * Deletes a value with the specified key from cache - * @param string the key of the value to be deleted - * @return boolean if no error happens during deletion - */ - public function delete($key) - { - return apc_delete($this->_prefix.$key); - } - - /** - * Deletes all values from cache. - */ - public function flush() - { - return apc_clear_cache('user'); - } + /** + * Deletes a value with the specified key from cache + * This is the implementation of the method declared in the parent class. + * @param string the key of the value to be deleted + * @return boolean if no error happens during deletion + */ + protected function deleteValue($key) + { + return apc_delete($key); + } + /** + * Deletes all values from cache. + * Be careful of performing this operation if the cache is shared by multiple applications. + */ + public function flush() + { + return apc_clear_cache('user'); + } } ?> \ No newline at end of file diff --git a/framework/Caching/TCache.php b/framework/Caching/TCache.php index d246b9d0..859180c9 100644 --- a/framework/Caching/TCache.php +++ b/framework/Caching/TCache.php @@ -1,22 +1,105 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ + * @package System.Web + */ /** - * ICache interface. + * TCache class + * + * TCache is the base class for cache classes with different cache storage implementation. + * + * TCache implements the interface {@link ICache} with the following methods, + * - {@link get} : retrieve the value with a key (if any) from cache + * - {@link set} : store the value with a key into cache + * - {@link add} : store the value only if cache does not have this key + * - {@link delete} : delete the value with the specified key from cache + * - {@link flush} : delete all values from cache + * + * Each value is associated with an expiration time. The {@link get} operation + * ensures that any expired value will not be returned. The expiration time by + * the number of seconds. A expiration time 0 represents never expire. * - * This interface must be implemented by cache managers. + * By definition, cache does not ensure the existence of a value + * even if it never expires. Cache is not meant to be an persistent storage. + * + * Child classes must implement the following methods: + * - {@link getValue} + * - {@link setValue} + * - {@link addValue} + * - {@link deleteValue} + * and optionally {@link flush} * * @author Qiang Xue * @version $Revision: $ $Date: $ * @package System.Caching * @since 3.0 */ -interface ICache +abstract class TCache extends TModule implements ICache { + private $_prefix=null; + + /** + * Initializes the cache module. + * This method initializes the cache key prefix and registers the cache module + * with the application. + * @param TXmlElement the module configuration + */ + public function init($config) + { + if($this->_prefix===null) + $this->_prefix=$this->getApplication()->getUniqueID(); + $this->getApplication()->setCache($this); + } + + /** + * @return string a unique prefix for the keys of cached values. + * If it is not explicitly set, it will take the value of {@link TApplication::getUniqueID}. + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * @param string a unique prefix for the keys of cached values + */ + public function setPrefix($value) + { + $this->_prefix=$value; + } + + /** + * @param string a key identifying a value to be cached + * @return sring a key generated from the provided key which ensures the uniqueness across applications + */ + protected function generateUniqueKey($key) + { + return md5($this->_prefix.$key); + } + /** * Retrieves a value from cache with a specified key. + * @param string a key identifying the cached value * @return mixed the value stored in cache, false if the value is not in the cache or expired. */ - public function get($id); + public function get($id) + { + if(($value=$this->getValue($this->generateUniqueKey($id)))!==false) + { + $data=unserialize($value); + if(!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged()) + return $data[0]; + } + return false; + } + /** * Stores a value identified by a key into cache. * If the cache already contains such a key, the existing value and @@ -24,65 +107,100 @@ interface ICache * * @param string the key identifying the value to be cached * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @param ICacheDependency dependency of the cached item. If the dependency changes, the item is labelled invalid. * @return boolean true if the value is successfully stored into cache, false otherwise */ - public function set($id,$value,$expire=0); + public function set($id,$value,$expire=0,$dependency=null) + { + $data=array($value,$dependency); + $expire=($expire<=0)?0:time()+$expire; + return $this->setValue($this->generateUniqueKey($id),serialize($data),$expire); + } + /** * Stores a value identified by a key into cache if the cache does not contain this key. * Nothing will be done if the cache already contains the key. * @param string the key identifying the value to be cached * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @param ICacheDependency dependency of the cached item. If the dependency changes, the item is labelled invalid. * @return boolean true if the value is successfully stored into cache, false otherwise */ - public function add($id,$value,$expire=0); - /** - * Stores a value identified by a key into cache only if the cache contains this key. - * The existing value and expiration time will be overwritten with the new ones. - * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. - * @return boolean true if the value is successfully stored into cache, false otherwise - */ - public function replace($id,$value,$expire=0); + public function add($id,$value,$expire=0,$dependency=null) + { + $data=array($value,$dependency); + $expire=($expire<=0)?0:time()+$expire; + return $this->addValue($this->generateUniqueKey($id),serialize($data),$expire); + } + /** * Deletes a value with the specified key from cache * @param string the key of the value to be deleted * @return boolean if no error happens during deletion */ - public function delete($id); + public function delete($id) + { + return $this->deleteValue($this->generateUniqueKey($id)); + } + /** * Deletes all values from cache. * Be careful of performing this operation if the cache is shared by multiple applications. + * Child classes may implement this method to realize the flush operation. + * @throws TNotSupportedException if this method is not overriden by child classes */ - public function flush(); -} - -interface IDependency -{ + public function flush() + { + throw new TNotSupportedException('cache_flush_unsupported'); + } -} + /** + * Retrieves a value from cache with a specified key. + * This method should be implemented by child classes to store the data + * in specific cache storage. The uniqueness and dependency are handled + * in {@link get()} already. So only the implementation of data retrieval + * is needed. + * @param string a unique key identifying the cached value + * @return string the value stored in cache, false if the value is not in the cache or expired. + */ + abstract protected function getValue($key); -class TTimeDependency -{ -} + /** + * Stores a value identified by a key in cache. + * This method should be implemented by child classes to store the data + * in specific cache storage. The uniqueness and dependency are handled + * in {@link set()} already. So only the implementation of data storage + * is needed. + * + * @param string the key identifying the value to be cached + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + abstract protected function setValue($key,$value,$expire); -class TFileDependency -{ -} + /** + * Stores a value identified by a key into cache if the cache does not contain this key. + * This method should be implemented by child classes to store the data + * in specific cache storage. The uniqueness and dependency are handled + * in {@link add()} already. So only the implementation of data storage + * is needed. + * + * @param string the key identifying the value to be cached + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + abstract protected function addValue($key,$value,$expire); -class TDirectoryDependency -{ + /** + * Deletes a value with the specified key from cache + * This method should be implemented by child classes to delete the data from actual cache storage. + * @param string the key of the value to be deleted + * @return boolean if no error happens during deletion + */ + abstract protected function deleteValue($key); } ?> \ No newline at end of file diff --git a/framework/Caching/TMemCache.php b/framework/Caching/TMemCache.php index f3b3e0cf..4497ad4c 100644 --- a/framework/Caching/TMemCache.php +++ b/framework/Caching/TMemCache.php @@ -24,7 +24,6 @@ * - {@link get} : retrieve the value with a key (if any) from cache * - {@link set} : store the value with a key into cache * - {@link add} : store the value only if cache does not have this key - * - {@link replace} : store the value only if cache has this key * - {@link delete} : delete the value with the specified key from cache * - {@link flush} : delete all values from cache * @@ -53,7 +52,9 @@ * cache module. It can be accessed via {@link TApplication::getCache()}. * * TMemCache may be configured in application configuration file as follows + * * + * * where {@link getHost Host} and {@link getPort Port} are configurable properties * of TMemCache. * @@ -111,10 +112,8 @@ class TMemCache extends TModule implements ICache $this->_cache=new Memcache; if($this->_cache->connect($this->_host,$this->_port)===false) throw new TConfigurationException('memcache_connection_failed',$this->_host,$this->_port); - $application=$this->getApplication(); - $this->_prefix=$application->getUniqueID(); - $application->setCache($this); $this->_initialized=true; + parent::init($config); } /** @@ -159,75 +158,52 @@ class TMemCache extends TModule implements ICache /** * Retrieves a value from cache with a specified key. - * @return mixed the value stored in cache, false if the value is not in the cache or expired. + * This is the implementation of the method declared in the parent class. + * @param string a unique key identifying the cached value + * @return string the value stored in cache, false if the value is not in the cache or expired. */ - public function get($key) + protected function getValue($key) { - return $this->_cache->get($this->generateUniqueKey($key)); + return $this->_cache->get($key); } /** - * Stores a value identified by a key into cache. - * If the cache already contains such a key, the existing value and - * expiration time will be replaced with the new ones. - * - * Note, avoid using this method whenever possible. Database insertion is - * very expensive. Try using {@link add} instead, which will not store the value - * if the key is already in cache. + * Stores a value identified by a key in cache. + * This is the implementation of the method declared in the parent class. * * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. * @return boolean true if the value is successfully stored into cache, false otherwise */ - public function set($key,$value,$expire=0) + protected function setValue($key,$value,$expire) { - return $this->_cache->set($this->generateUniqueKey($key),$value,0,$expire); + return $this->_cache->set($key,$value,0,$expire); } /** * Stores a value identified by a key into cache if the cache does not contain this key. - * Nothing will be done if the cache already contains the key. - * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. - * @return boolean true if the value is successfully stored into cache, false otherwise - */ - public function add($key,$value,$expiry=0) - { - return $this->_cache->add($this->generateUniqueKey($key),$value,0,$expiry); - } - - /** - * Stores a value identified by a key into cache only if the cache contains this key. - * The existing value and expiration time will be overwritten with the new ones. + * This is the implementation of the method declared in the parent class. + * * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. * @return boolean true if the value is successfully stored into cache, false otherwise */ - public function replace($key,$value,$expiry=0) + protected function addValue($key,$value,$expire) { - return $this->_cache->replace($this->generateUniqueKey($key),$value,0,$expiry); + return $this->_cache->add($key,$value,0,$expire); } /** * Deletes a value with the specified key from cache + * This is the implementation of the method declared in the parent class. * @param string the key of the value to be deleted * @return boolean if no error happens during deletion */ - public function delete($key) + protected function deleteValue($key) { - return $this->_cache->delete($this->generateUniqueKey($key)); + return $this->_cache->delete($key); } /** @@ -238,19 +214,6 @@ class TMemCache extends TModule implements ICache { return $this->_cache->flush(); } - - /** - * Generates a unique key based on a given user key. - * This method generates a unique key with the memcache. - * The key is made unique by prefixing with a unique string that is supposed - * to be unique among applications using the same memcache. - * @param string user key - * @param string a unique key - */ - protected function generateUniqueKey($key) - { - return md5($this->_prefix.$key); - } } ?> \ No newline at end of file diff --git a/framework/Caching/TSqliteCache.php b/framework/Caching/TSqliteCache.php index 92cc46a6..dc4bf13f 100644 --- a/framework/Caching/TSqliteCache.php +++ b/framework/Caching/TSqliteCache.php @@ -25,14 +25,12 @@ * - {@link get} : retrieve the value with a key (if any) from cache * - {@link set} : store the value with a key into cache * - {@link add} : store the value only if cache does not have this key - * - {@link replace} : store the value only if cache has this key * - {@link delete} : delete the value with the specified key from cache * - {@link flush} : delete all values from cache * * Each value is associated with an expiration time. The {@link get} operation - * ensures that any expired value will not be returned. The expiration time can - * be specified by the number of seconds (maximum 60*60*24*30) - * or a UNIX timestamp. A expiration time 0 represents never expire. + * ensures that any expired value will not be returned. The expiration time by + * the number of seconds. A expiration time 0 represents never expire. * * By definition, cache does not ensure the existence of a value * even if it never expires. Cache is not meant to be an persistent storage. @@ -40,7 +38,7 @@ * Do not use the same database file for multiple applications using TSqliteCache. * Also note, cache is shared by all user sessions of an application. * - * To use this module, the sqlite PHP extension must be loaded. Sqlite extension + * To use this module, the sqlite PHP extension must be loaded. Note, Sqlite extension * is no longer loaded by default since PHP 5.1. * * Some usage examples of TSqliteCache are as follows, @@ -55,8 +53,10 @@ * If loaded, TSqliteCache will register itself with {@link TApplication} as the * cache module. It can be accessed via {@link TApplication::getCache()}. * - * TMemCache may be configured in application configuration file as follows + * TSqliteCache may be configured in application configuration file as follows + * * + * * where {@link getDbFile DbFile} is a property specifying the location of the * SQLite DB file (in the namespace format). * @@ -65,7 +65,7 @@ * @package System.Caching * @since 3.0 */ -class TSqliteCache extends TModule implements ICache +class TSqliteCache extends TCache { /** * name of the table storing cache data @@ -75,10 +75,6 @@ class TSqliteCache extends TModule implements ICache * extension of the db file name */ const DB_FILE_EXT='.db'; - /** - * maximum number of seconds specified as expire - */ - const EXPIRE_LIMIT=2592000; // 30 days /** * @var boolean if the module has been initialized @@ -125,7 +121,7 @@ class TSqliteCache extends TModule implements ICache { if($res->numRows()===0) { - if($this->_db->query('CREATE TABLE '.self::CACHE_TABLE.' (key CHAR(128) PRIMARY KEY, value BLOB, serialized INT, expire INT)')===false) + if($this->_db->query('CREATE TABLE '.self::CACHE_TABLE.' (key CHAR(128) PRIMARY KEY, value BLOB, expire INT)')===false) throw new TConfigurationException('sqlitecache_table_creation_failed',sqlite_error_string(sqlite_last_error())); } } @@ -133,7 +129,7 @@ class TSqliteCache extends TModule implements ICache throw new TConfigurationException('sqlitecache_table_creation_failed',sqlite_error_string(sqlite_last_error())); $this->_db->query('DELETE FROM '.self::CACHE_TABLE.' WHERE expire<>0 AND expire<'.time()); $this->_initialized=true; - $this->getApplication()->setCache($this); + parent::init($config); } /** @@ -159,96 +155,58 @@ class TSqliteCache extends TModule implements ICache /** * Retrieves a value from cache with a specified key. - * @return mixed the value stored in cache, false if the value is not in the cache or expired. + * This is the implementation of the method declared in the parent class. + * @param string a unique key identifying the cached value + * @return string the value stored in cache, false if the value is not in the cache or expired. */ - public function get($key) + protected function getValue($key) { - $sql='SELECT serialized,value FROM '.self::CACHE_TABLE.' WHERE key=\''.md5($key).'\' AND (expire=0 OR expire>'.time().')'; + $sql='SELECT value FROM '.self::CACHE_TABLE.' WHERE key=\''.$key.'\' AND (expire=0 OR expire>'.time().')'; if(($ret=$this->_db->query($sql))!=false && ($row=$ret->fetch(SQLITE_ASSOC))!==false) - return $row['serialized']?Prado::unserialize($row['value']):$row['value']; + return $row['value']; else return false; } /** - * Stores a value identified by a key into cache. - * If the cache already contains such a key, the existing value and - * expiration time will be replaced with the new ones. - * - * Note, avoid using this method whenever possible. Database insertion is - * very expensive. Try using {@link add} instead, which will not store the value - * if the key is already in cache. + * Stores a value identified by a key in cache. + * This is the implementation of the method declared in the parent class. * * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. * @return boolean true if the value is successfully stored into cache, false otherwise */ - public function set($key,$value,$expire=0) + protected function setValue($key,$value,$expire) { - $serialized=is_string($value)?0:1; - $value1=sqlite_escape_string($serialized?Prado::serialize($value):$value); - if($expire && $expire<=self::EXPIRE_LIMIT) - $expire=time()+$expire; - $sql='REPLACE INTO '.self::CACHE_TABLE.' VALUES(\''.md5($key).'\',\''.$value1.'\','.$serialized.','.$expire.')'; + $sql='REPLACE INTO '.self::CACHE_TABLE.' VALUES(\''.$key.'\',\''.sqlite_escape_string($value).'\','.$expire.')'; return $this->_db->query($sql)!==false; } /** * Stores a value identified by a key into cache if the cache does not contain this key. - * Nothing will be done if the cache already contains the key. + * This is the implementation of the method declared in the parent class. + * * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. + * @param string the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. * @return boolean true if the value is successfully stored into cache, false otherwise */ - public function add($key,$value,$expire=0) + protected function addValue($key,$value,$expire) { - $serialized=is_string($value)?0:1; - $value1=sqlite_escape_string($serialized?Prado::serialize($value):$value); - if($expire && $expire<=self::EXPIRE_LIMIT) - $expire=time()+$expire; - $sql='INSERT INTO '.self::CACHE_TABLE.' VALUES(\''.md5($key).'\',\''.$value1.'\','.$serialized.','.$expire.')'; + $sql='INSERT INTO '.self::CACHE_TABLE.' VALUES(\''.$key.'\',\''.sqlite_escape_string($value).'\','.$expire.')'; return @$this->_db->query($sql)!==false; } - /** - * Stores a value identified by a key into cache only if the cache contains this key. - * The existing value and expiration time will be overwritten with the new ones. - * @param string the key identifying the value to be cached - * @param mixed the value to be cached - * @param integer the expiration time of the value, - * 0 means never expire, - * a number less or equal than 60*60*24*30 means the number of seconds that the value will remain valid. - * a number greater than 60*60*24*30 means a UNIX timestamp after which the value will expire. - * @return boolean true if the value is successfully stored into cache, false otherwise - */ - public function replace($key,$value,$expire=0) - { - $serialized=is_string($value)?0:1; - $value1=sqlite_escape_string($serialized?Prado::serialize($value):$value); - if($expire && $expire<=self::EXPIRE_LIMIT) - $expire=time()+$expire; - $sql='UPDATE '.self::CACHE_TABLE.' SET value=\''.$value1.'\', serialized='.$serialized.',expire='.$expire.' WHERE key=\''.md5($key).'\''; - $this->_db->query($sql); - $ret=$this->_db->query('SELECT serialized FROM '.self::CACHE_TABLE.' WHERE key=\''.md5($key).'\''); - return ($ret!=false && $ret->numRows()>0); - } - /** * Deletes a value with the specified key from cache + * This is the implementation of the method declared in the parent class. * @param string the key of the value to be deleted * @return boolean if no error happens during deletion */ - public function delete($key) + protected function deleteValue($key) { - $sql='DELETE FROM '.self::CACHE_TABLE.' WHERE key=\''.md5($key).'\''; + $sql='DELETE FROM '.self::CACHE_TABLE.' WHERE key=\''.$key.'\''; return $this->_db->query($sql)!==false; } diff --git a/framework/Web/UI/TThemeManager.php b/framework/Web/UI/TThemeManager.php index 29b48d90..f2de22f5 100644 --- a/framework/Web/UI/TThemeManager.php +++ b/framework/Web/UI/TThemeManager.php @@ -209,17 +209,20 @@ class TTheme extends TApplicationComponent implements ITheme { $this->_themeUrl=$themeUrl; $this->_name=basename($themePath); + $cacheValid=false; + // TODO: the following needs to be cleaned up (Qiang) if(($cache=$this->getApplication()->getCache())!==null) { $array=$cache->get(self::THEME_CACHE_PREFIX.$themePath); + //print_r($array);die('here'); if(is_array($array)) { list($skins,$cssFiles,$jsFiles,$timestamp)=$array; - $cacheValid=true; if($this->getApplication()->getMode()!==TApplication::STATE_PERFORMANCE) { if(($dir=opendir($themePath))===false) throw new TIOException('theme_path_inexistent',$themePath); + $cacheValid=true; while(($file=readdir($dir))!==false) { if($file==='.' || $file==='..') @@ -240,14 +243,18 @@ class TTheme extends TApplicationComponent implements ITheme } else { + $cacheValid=true; $this->_cssFiles=$cssFiles; $this->_jsFiles=$jsFiles; $this->_skins=$skins; } } } - if($this->_skins===null) + if(!$cacheValid) { + $this->_cssFiles=array(); + $this->_jsFiles=array(); + $this->_skins=array(); if(($dir=opendir($themePath))===false) throw new TIOException('theme_path_inexistent',$themePath); while(($file=readdir($dir))!==false) diff --git a/framework/interfaces.php b/framework/interfaces.php index f63da347..ca5c77bb 100644 --- a/framework/interfaces.php +++ b/framework/interfaces.php @@ -169,4 +169,77 @@ interface IStatePersister public function save($state); } + +/** + * ICache interface. + * + * This interface must be implemented by cache managers. + * + * @author Qiang Xue + * @version $Revision: $ $Date: $ + * @package System + * @since 3.0 + */ +interface ICache +{ + /** + * Retrieves a value from cache with a specified key. + * @param string a key identifying the cached value + * @return mixed the value stored in cache, false if the value is not in the cache or expired. + */ + public function get($id); + /** + * Stores a value identified by a key into cache. + * If the cache already contains such a key, the existing value and + * expiration time will be replaced with the new ones. + * + * @param string the key identifying the value to be cached + * @param mixed the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @param ICacheDependency dependency of the cached item. If the dependency changes, the item is labelled invalid. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + public function set($id,$value,$expire=0,$dependency=null); + /** + * Stores a value identified by a key into cache if the cache does not contain this key. + * Nothing will be done if the cache already contains the key. + * @param string the key identifying the value to be cached + * @param mixed the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @param ICacheDependency dependency of the cached item. If the dependency changes, the item is labelled invalid. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + public function add($id,$value,$expire=0,$dependency=null); + /** + * Deletes a value with the specified key from cache + * @param string the key of the value to be deleted + * @return boolean if no error happens during deletion + */ + public function delete($id); + /** + * Deletes all values from cache. + * Be careful of performing this operation if the cache is shared by multiple applications. + */ + public function flush(); +} + +/** + * ICacheDependency interface. + * + * This interface must be implemented by classes meant to be used as + * cache dependencies. + * + * @author Qiang Xue + * @version $Revision: $ $Date: $ + * @package System + * @since 3.0 + */ +interface ICacheDependency +{ + /** + * @return boolean whether the dependency has changed. Defaults to false. + */ + public function getHasChanged(); +} + ?> \ No newline at end of file -- cgit v1.2.3