Commit 392b293d by Qiang Xue

FragmentCache WIP

parent 379e48a4
...@@ -11,9 +11,19 @@ namespace yii\base; ...@@ -11,9 +11,19 @@ namespace yii\base;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Filter extends Behavior class ActionFilter extends Behavior
{ {
/** /**
* @var array list of action IDs that this filter should apply to. If this property is not set,
* then the filter applies to all actions, unless they are listed in [[except]].
*/
public $only;
/**
* @var array list of action IDs that this filter should not apply to.
*/
public $except = array();
/**
* Declares event handlers for the [[owner]]'s events. * Declares event handlers for the [[owner]]'s events.
* @return array events (array keys) and the corresponding event handler methods (array values). * @return array events (array keys) and the corresponding event handler methods (array values).
*/ */
......
...@@ -337,15 +337,16 @@ class View extends Component ...@@ -337,15 +337,16 @@ class View extends Component
* ~~~ * ~~~
* *
* @param string $id a unique ID identifying the fragment to be cached. * @param string $id a unique ID identifying the fragment to be cached.
* @param array $properties initial property values for [[\yii\widgets\OutputCache]] * @param array $properties initial property values for [[\yii\widgets\FragmentCache]]
* @return boolean whether you should generate the content for caching. * @return boolean whether you should generate the content for caching.
* False if the cached version is available. * False if the cached version is available.
*/ */
public function beginCache($id, $properties = array()) public function beginCache($id, $properties = array())
{ {
$properties['id'] = $id; $properties['id'] = $id;
/** @var $cache \yii\widgets\FragmentCache */
$cache = $this->beginWidget('yii\widgets\OutputCache', $properties); $cache = $this->beginWidget('yii\widgets\OutputCache', $properties);
if ($cache->getIsContentCached()) { if ($cache->getCachedContent() !== false) {
$this->endCache(); $this->endCache();
return false; return false;
} else { } else {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace yii\caching; namespace yii\caching;
use yii\base\Component; use yii\base\Component;
use yii\helpers\StringHelper;
/** /**
* Cache is the base class for cache classes supporting different cache storage implementation. * Cache is the base class for cache classes supporting different cache storage implementation.
...@@ -70,13 +71,13 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -70,13 +71,13 @@ abstract class Cache extends Component implements \ArrayAccess
/** /**
* Builds a normalized cache key from one or multiple parameters. * Builds a normalized cache key from a given key.
* *
* The generated key contains letters and digits only, and its length is no more than 32. * The generated key contains letters and digits only, and its length is no more than 32.
* *
* If only one parameter is given and it is already a normalized key, then * If the given key is a string containing alphanumeric characters only and no more than 32 characters,
* it will be returned back without change. Otherwise, a normalized key * then the key will be returned back without change. Otherwise, a normalized key
* is generated by serializing all given parameters and applying MD5 hashing. * is generated by serializing the given key and applying MD5 hashing.
* *
* The following example builds a cache key using three parameters: * The following example builds a cache key using three parameters:
* *
...@@ -84,16 +85,15 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -84,16 +85,15 @@ abstract class Cache extends Component implements \ArrayAccess
* $key = $cache->buildKey($className, $method, $id); * $key = $cache->buildKey($className, $method, $id);
* ~~~ * ~~~
* *
* @param string $key the first parameter * @param array|string $key the key to be normalized
* @return string the generated cache key * @return string the generated cache key
*/ */
public function buildKey($key) public function buildKey($key)
{ {
if (func_num_args() === 1 && ctype_alnum($key) && strlen($key) <= 32) { if (is_string($key)) {
return (string)$key; return ctype_alnum($key) && StringHelper::strlen($key) <= 32 ? $key : md5($key);
} else { } else {
$params = func_get_args(); return md5(json_encode($key));
return md5(json_encode($params));
} }
} }
......
...@@ -7,15 +7,15 @@ ...@@ -7,15 +7,15 @@
namespace yii\caching; namespace yii\caching;
use Yii;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\db\Connection; use yii\db\Connection;
use yii\db\Query;
/** /**
* DbDependency represents a dependency based on the query result of a SQL statement. * DbDependency represents a dependency based on the query result of a SQL statement.
* *
* If the query result changes, the dependency is considered as changed. * If the query result changes, the dependency is considered as changed.
* The query is specified via the [[query]] property. * The query is specified via the [[sql]] property.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
...@@ -27,23 +27,25 @@ class DbDependency extends Dependency ...@@ -27,23 +27,25 @@ class DbDependency extends Dependency
*/ */
public $connectionID = 'db'; public $connectionID = 'db';
/** /**
* @var Query the SQL query whose result is used to determine if the dependency has been changed. * @var string the SQL query whose result is used to determine if the dependency has been changed.
* Only the first row of the query result will be used. * Only the first row of the query result will be used.
*/ */
public $query; public $sql;
/** /**
* @var Connection the DB connection instance * @var array the parameters (name=>value) to be bound to the SQL statement specified by [[sql]].
*/ */
private $_db; public $params;
/** /**
* Constructor. * Constructor.
* @param Query $query the SQL query whose result is used to determine if the dependency has been changed. * @param string $sql the SQL query whose result is used to determine if the dependency has been changed.
* @param array $params the parameters (name=>value) to be bound to the SQL statement specified by [[sql]].
* @param array $config name-value pairs that will be used to initialize the object properties * @param array $config name-value pairs that will be used to initialize the object properties
*/ */
public function __construct($query = null, $config = array()) public function __construct($sql, $params = array(), $config = array())
{ {
$this->query = $query; $this->sql = $sql;
$this->params = $params;
parent::__construct($config); parent::__construct($config);
} }
...@@ -66,22 +68,23 @@ class DbDependency extends Dependency ...@@ -66,22 +68,23 @@ class DbDependency extends Dependency
protected function generateDependencyData() protected function generateDependencyData()
{ {
$db = $this->getDb(); $db = $this->getDb();
/**
* @var \yii\db\Command $command
*/
$command = $this->query->createCommand($db);
if ($db->enableQueryCache) { if ($db->enableQueryCache) {
// temporarily disable and re-enable query caching // temporarily disable and re-enable query caching
$db->enableQueryCache = false; $db->enableQueryCache = false;
$result = $command->queryRow(); $result = $db->createCommand($this->sql, $this->params)->queryRow();
$db->enableQueryCache = true; $db->enableQueryCache = true;
} else { } else {
$result = $command->queryRow(); $result = $db->createCommand($this->sql, $this->params)->queryRow();
} }
return $result; return $result;
} }
/** /**
* @var Connection the DB connection instance
*/
private $_db;
/**
* Returns the DB connection instance used for caching purpose. * Returns the DB connection instance used for caching purpose.
* @return Connection the DB connection instance * @return Connection the DB connection instance
* @throws InvalidConfigException if [[connectionID]] does not point to a valid application component. * @throws InvalidConfigException if [[connectionID]] does not point to a valid application component.
...@@ -89,11 +92,11 @@ class DbDependency extends Dependency ...@@ -89,11 +92,11 @@ class DbDependency extends Dependency
public function getDb() public function getDb()
{ {
if ($this->_db === null) { if ($this->_db === null) {
$db = \Yii::$app->getComponent($this->connectionID); $db = Yii::$app->getComponent($this->connectionID);
if ($db instanceof Connection) { if ($db instanceof Connection) {
$this->_db = $db; $this->_db = $db;
} else { } else {
throw new InvalidConfigException("DbCache::connectionID must refer to the ID of a DB application component."); throw new InvalidConfigException("DbCacheDependency::connectionID must refer to the ID of a DB application component.");
} }
} }
return $this->_db; return $this->_db;
......
...@@ -389,7 +389,13 @@ class Command extends \yii\base\Component ...@@ -389,7 +389,13 @@ class Command extends \yii\base\Component
} }
if (isset($cache)) { if (isset($cache)) {
$cacheKey = $cache->buildKey(__CLASS__, $db->dsn, $db->username, $sql, $paramLog); $cacheKey = $cache->buildKey(array(
__CLASS__,
$db->dsn,
$db->username,
$sql,
$paramLog,
));
if (($result = $cache->get($cacheKey)) !== false) { if (($result = $cache->get($cacheKey)) !== false) {
\Yii::trace('Query result found in cache', __CLASS__); \Yii::trace('Query result found in cache', __CLASS__);
return $result; return $result;
......
...@@ -109,7 +109,12 @@ abstract class Schema extends \yii\base\Object ...@@ -109,7 +109,12 @@ abstract class Schema extends \yii\base\Object
*/ */
public function getCacheKey($cache, $name) public function getCacheKey($cache, $name)
{ {
return $cache->buildKey(__CLASS__, $this->db->dsn, $this->db->username, $name); return $cache->buildKey(array(
__CLASS__,
$this->db->dsn,
$this->db->username,
$name,
));
} }
/** /**
......
...@@ -7,15 +7,7 @@ ...@@ -7,15 +7,7 @@
namespace yii\helpers; namespace yii\helpers;
// todo define how subclassing will work
// todo add a run() or render() method
// todo test this on all kinds of terminals, especially windows (check out lib ncurses) // todo test this on all kinds of terminals, especially windows (check out lib ncurses)
// todo not sure if all methods should be static
// todo subclass DetailView
// todo subclass GridView
// todo more subclasses
/** /**
* Console View is the base class for console view components * Console View is the base class for console view components
......
...@@ -45,6 +45,7 @@ class CacheSession extends Session ...@@ -45,6 +45,7 @@ class CacheSession extends Session
{ {
return true; return true;
} }
/** /**
* Returns the cache instance used for storing session data. * Returns the cache instance used for storing session data.
* @return Cache the cache instance * @return Cache the cache instance
...@@ -114,6 +115,6 @@ class CacheSession extends Session ...@@ -114,6 +115,6 @@ class CacheSession extends Session
*/ */
protected function calculateKey($id) protected function calculateKey($id)
{ {
return $this->getCache()->buildKey(__CLASS__, $id); return $this->getCache()->buildKey(array(__CLASS__, $id));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment