[Solar-svn] Revision 3163

pmjones at solarphp.com pmjones at solarphp.com
Fri May 16 19:55:01 CDT 2008


Solar_Sql_Model_Cache: [NEW] Cache handler for models, for versioned caching of table data.


Added: trunk/Solar/Sql/Model/Cache.php
===================================================================
--- trunk/Solar/Sql/Model/Cache.php	                        (rev 0)
+++ trunk/Solar/Sql/Model/Cache.php	2008-05-17 00:55:01 UTC (rev 3163)
@@ -0,0 +1,239 @@
+<?php
+/**
+ * 
+ * Support class for models to work with with a Solar_Cache object.
+ * 
+ * This cache works slightly differently from "normal" caches, in that it
+ * tracks a version number for the data in the source table. When you "delete"
+ * the cache, what really happens is that the version number increases.  This
+ * makes it particularly effective for memcache and other memory-based
+ * caches, where old entries simply "drop out" when there's no more room.
+ * 
+ * This cache is not recommended for file-based caching. If you use
+ * a file-based cache here, be prepared to clear out old data versions on
+ * your own, as this system will not do it for you.
+ * 
+ * For background information on cache versioning, see the blog entry at
+ * <http://blog.leetsoft.com/2007/5/22/the-secret-to-memcached>.
+ * 
+ * @category Solar
+ * 
+ * @package Solar_Sql_Model
+ * 
+ * @author Paul M. Jones <pmjones at solarphp.com>
+ * 
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ * 
+ * @version $Id$
+ * 
+ */
+class Solar_Sql_Model_Cache extends Solar_Base
+{
+    /**
+     * 
+     * User-defined configuration values.
+     * 
+     * Keys are ...
+     * 
+     * `cache`
+     * : (dependency) A Solar_Cache dependency.
+     * 
+     * @var array
+     * 
+     */
+    protected $_Solar_Sql_Model_Cache = array(
+        'cache'  => array('adapter' => 'Solar_Cache_Adapter_Var'),
+    );
+    
+    /**
+     * 
+     * The cache object for model data.
+     * 
+     * @var Solar_Cache_Adapter
+     * 
+     */
+    protected $_cache;
+    
+    /**
+     * 
+     * The model this cache is working with.
+     * 
+     * @var Solar_Sql_Model
+     * 
+     */
+    protected $_model;
+    
+    /**
+     * 
+     * The SQL connection cache-key prefix; needed for deconfliction when
+     * there are multiple SQL connections.
+     * 
+     * @var string
+     * 
+     */
+    protected $_prefix;
+    
+    /**
+     * 
+     * Constructor.
+     * 
+     * @param array $config User-provided configuration values.
+     * 
+     */
+    public function __construct($config = null)
+    {
+        parent::__construct($config);
+        $this->_cache = Solar::dependency(
+            'Solar_Cache',
+            $this->_config['cache']
+        );
+    }
+    
+    /**
+     * 
+     * Sets the model this cache will work with; picks up the SQL cache key
+     * prefix along with it.
+     * 
+     * @param $model Solar_Sql_Model The model this cache will work with.
+     * 
+     * @return void
+     * 
+     */
+    public function setModel($model)
+    {
+        $this->_model = $model;
+        $this->_prefix = $model->sql->getCacheKeyPrefix();
+    }
+    
+    /**
+     * 
+     * Deletes the cache for this model.
+     * 
+     * Technically, this just increases the data version number.  This means
+     * that older versions will no longer be valid, causing a cache miss.
+     * 
+     * The version entry is keyed under `$prefix/tables/$tables/data_version`.
+     * 
+     * @return void
+     * 
+     */
+    public function delete()
+    {
+        $key = $this->_prefix
+             . "/tables"
+             . "/{$this->_model->table_name}"
+             . "/data_version";
+        
+        $this->_cache->increment($key);
+    }
+    
+    /**
+     * 
+     * Deletes the cache for this model and all related models.
+     * 
+     * @return void
+     * 
+     */
+    public function deleteAll()
+    {
+        $this->delete();
+        foreach ($this->_model->related as $name => $info) {
+            $model = $this->_model->getRelated($name)->getModel();
+            $model->cache->delete();
+        }
+    }
+    
+    /**
+     * 
+     * Gets the key for a cache entry based on fetch parameters for a select.
+     * 
+     * The entry is keyed under `$prefix/tables/$table/data/$version/$hash`,
+     * where $hash is an MD5 hash of the serialized parameters.
+     * 
+     * If the params include a `cache_key` entry, that value is used instead
+     * of $hash.
+     * 
+     * @param array $params The fetch parameters for a select.
+     * 
+     * @return string The versioned cache entry key.
+     * 
+     */
+    public function entry($params)
+    {
+        $version = (int) $this->_fetchVersion();
+        
+        if ($params['cache_key']) {
+            $key = $params['cache_key'];
+        } else {
+            unset($params['cache']);
+            unset($params['cache_key']);
+            $serial = serialize($params);
+            $key = hash('md5', $serial);
+        }
+        
+        $key = $this->_prefix
+             . "/tables"
+             . "/{$this->_model->table_name}"
+             . "/data"
+             . "/$version"
+             . "/$key";
+        
+        return $key;
+    }
+    
+    /**
+     * 
+     * Fetchs the data for a cache entry.
+     * 
+     * @param string $key The cache entry key.
+     * 
+     * @return mixed Boolean false if the fetch failed (cache miss), 
+     * otherwise the result of the fetch (cache hit).
+     * 
+     * @see Solar_Cache_Adapter::fetch()
+     * 
+     */
+    public function fetch($key)
+    {
+        return $this->_cache->fetch($key);
+    }
+    
+    /**
+     * 
+     * Adds data to the cache under a specified key.  Note that this is a
+     * race-condition safe add, not a save.
+     * 
+     * @param string $key The cache entry key.
+     * 
+     * @param mixed $data The data to add to the cache.
+     * 
+     * @return bool True on success, false on failure.
+     * 
+     * @see Solar_Cache_Adapter::add()
+     * 
+     */
+    public function add($key, $data)
+    {
+        return $this->_cache->add($key, $data);
+    }
+    
+    /**
+     * 
+     * Fetches the current model data version from the cache.
+     * 
+     * The entry is keyed under `$prefix/tables/$table/data_version`.
+     * 
+     * @return int The model data version.
+     * 
+     */
+    protected function _fetchVersion()
+    {
+        $key = $this->_prefix
+             . "/tables"
+             . "/{$this->_model->table_name}"
+             . "/data_version";
+        
+        $result = $this->_cache->fetch($key);
+        return $result;
+    }
+}
\ No newline at end of file




More information about the Solar-svn mailing list