From 4a0d2863f64d77731e010a609f054a3fcc413548 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 12 Jun 2013 21:59:30 -0400 Subject: [PATCH] Fixes issue #421: yii\db\Schema:refresh() does not clear all cache --- framework/yii/caching/GroupDependency.php | 17 ++++++++++------- framework/yii/db/Schema.php | 23 ++++++++++++++++++----- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/framework/yii/caching/GroupDependency.php b/framework/yii/caching/GroupDependency.php index be77344..af07d8a 100644 --- a/framework/yii/caching/GroupDependency.php +++ b/framework/yii/caching/GroupDependency.php @@ -42,11 +42,11 @@ class GroupDependency extends Dependency */ protected function generateDependencyData($cache) { - if ($cache->get(array(__CLASS__, $this->group)) === false) { - // If the cutoff timestamp is not initialized or is swapped out of the cache, we need to set it. - $this->invalidate($cache, array(__CLASS__, $this->group)); + $version = $cache->get(array(__CLASS__, $this->group)); + if ($version === false) { + $version = $this->invalidate($cache, array(__CLASS__, $this->group)); } - return microtime(true); + return $version; } /** @@ -56,17 +56,20 @@ class GroupDependency extends Dependency */ public function getHasChanged($cache) { - $time = $cache->get(array(__CLASS__, $this->group)); - return $time === false || $time > $this->data; + $version = $cache->get(array(__CLASS__, $this->group)); + return $version === false || $version !== $this->data; } /** * Invalidates all of the cached data items that have the same [[group]]. * @param Cache $cache the cache component that caches the data items * @param string $group the group name + * @return string the current version number */ public static function invalidate($cache, $group) { - $cache->set(array(__CLASS__, $group), microtime(true)); + $version = microtime(); + $cache->set(array(__CLASS__, $group), $version); + return $version; } } diff --git a/framework/yii/db/Schema.php b/framework/yii/db/Schema.php index c961244..6ae9ab7 100644 --- a/framework/yii/db/Schema.php +++ b/framework/yii/db/Schema.php @@ -11,6 +11,7 @@ use Yii; use yii\base\NotSupportedException; use yii\base\InvalidCallException; use yii\caching\Cache; +use yii\caching\GroupDependency; /** * Schema is the base class for concrete DBMS-specific schema classes. @@ -93,7 +94,7 @@ abstract class Schema extends \yii\base\Object if ($refresh || ($table = $cache->get($key)) === false) { $table = $this->loadTableSchema($realName); if ($table !== null) { - $cache->set($key, $table, $db->schemaCacheDuration); + $cache->set($key, $table, $db->schemaCacheDuration, new GroupDependency($this->getCacheGroup())); } } return $this->_tables[$name] = $table; @@ -107,7 +108,7 @@ abstract class Schema extends \yii\base\Object * @param string $name the table name * @return mixed the cache key */ - public function getCacheKey($name) + protected function getCacheKey($name) { return array( __CLASS__, @@ -118,6 +119,20 @@ abstract class Schema extends \yii\base\Object } /** + * Returns the cache group name. + * This allows [[refresh()]] to invalidate all cached table schemas. + * @return string the cache group name + */ + protected function getCacheGroup() + { + return md5(serialize(array( + __CLASS__, + $this->db->dsn, + $this->db->username, + ))); + } + + /** * Returns the metadata for all tables in the database. * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema name. * @param boolean $refresh whether to fetch the latest available table schemas. If this is false, @@ -176,9 +191,7 @@ abstract class Schema extends \yii\base\Object /** @var $cache Cache */ $cache = is_string($this->db->schemaCache) ? Yii::$app->getComponent($this->db->schemaCache) : $this->db->schemaCache; if ($this->db->enableSchemaCache && $cache instanceof Cache) { - foreach ($this->_tables as $name => $table) { - $cache->delete($this->getCacheKey($name)); - } + GroupDependency::invalidate($cache, $this->getCacheGroup()); } $this->_tableNames = array(); $this->_tables = array();