Commit 4a0d2863 by Qiang Xue

Fixes issue #421: yii\db\Schema:refresh() does not clear all cache

parent 00df1e88
...@@ -42,11 +42,11 @@ class GroupDependency extends Dependency ...@@ -42,11 +42,11 @@ class GroupDependency extends Dependency
*/ */
protected function generateDependencyData($cache) protected function generateDependencyData($cache)
{ {
if ($cache->get(array(__CLASS__, $this->group)) === false) { $version = $cache->get(array(__CLASS__, $this->group));
// If the cutoff timestamp is not initialized or is swapped out of the cache, we need to set it. if ($version === false) {
$this->invalidate($cache, array(__CLASS__, $this->group)); $version = $this->invalidate($cache, array(__CLASS__, $this->group));
} }
return microtime(true); return $version;
} }
/** /**
...@@ -56,17 +56,20 @@ class GroupDependency extends Dependency ...@@ -56,17 +56,20 @@ class GroupDependency extends Dependency
*/ */
public function getHasChanged($cache) public function getHasChanged($cache)
{ {
$time = $cache->get(array(__CLASS__, $this->group)); $version = $cache->get(array(__CLASS__, $this->group));
return $time === false || $time > $this->data; return $version === false || $version !== $this->data;
} }
/** /**
* Invalidates all of the cached data items that have the same [[group]]. * Invalidates all of the cached data items that have the same [[group]].
* @param Cache $cache the cache component that caches the data items * @param Cache $cache the cache component that caches the data items
* @param string $group the group name * @param string $group the group name
* @return string the current version number
*/ */
public static function invalidate($cache, $group) public static function invalidate($cache, $group)
{ {
$cache->set(array(__CLASS__, $group), microtime(true)); $version = microtime();
$cache->set(array(__CLASS__, $group), $version);
return $version;
} }
} }
...@@ -11,6 +11,7 @@ use Yii; ...@@ -11,6 +11,7 @@ use Yii;
use yii\base\NotSupportedException; use yii\base\NotSupportedException;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
use yii\caching\Cache; use yii\caching\Cache;
use yii\caching\GroupDependency;
/** /**
* Schema is the base class for concrete DBMS-specific schema classes. * Schema is the base class for concrete DBMS-specific schema classes.
...@@ -93,7 +94,7 @@ abstract class Schema extends \yii\base\Object ...@@ -93,7 +94,7 @@ abstract class Schema extends \yii\base\Object
if ($refresh || ($table = $cache->get($key)) === false) { if ($refresh || ($table = $cache->get($key)) === false) {
$table = $this->loadTableSchema($realName); $table = $this->loadTableSchema($realName);
if ($table !== null) { if ($table !== null) {
$cache->set($key, $table, $db->schemaCacheDuration); $cache->set($key, $table, $db->schemaCacheDuration, new GroupDependency($this->getCacheGroup()));
} }
} }
return $this->_tables[$name] = $table; return $this->_tables[$name] = $table;
...@@ -107,7 +108,7 @@ abstract class Schema extends \yii\base\Object ...@@ -107,7 +108,7 @@ abstract class Schema extends \yii\base\Object
* @param string $name the table name * @param string $name the table name
* @return mixed the cache key * @return mixed the cache key
*/ */
public function getCacheKey($name) protected function getCacheKey($name)
{ {
return array( return array(
__CLASS__, __CLASS__,
...@@ -118,6 +119,20 @@ abstract class Schema extends \yii\base\Object ...@@ -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. * 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 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, * @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 ...@@ -176,9 +191,7 @@ abstract class Schema extends \yii\base\Object
/** @var $cache Cache */ /** @var $cache Cache */
$cache = is_string($this->db->schemaCache) ? Yii::$app->getComponent($this->db->schemaCache) : $this->db->schemaCache; $cache = is_string($this->db->schemaCache) ? Yii::$app->getComponent($this->db->schemaCache) : $this->db->schemaCache;
if ($this->db->enableSchemaCache && $cache instanceof Cache) { if ($this->db->enableSchemaCache && $cache instanceof Cache) {
foreach ($this->_tables as $name => $table) { GroupDependency::invalidate($cache, $this->getCacheGroup());
$cache->delete($this->getCacheKey($name));
}
} }
$this->_tableNames = array(); $this->_tableNames = array();
$this->_tables = array(); $this->_tables = array();
......
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