Commit eaf8ece5 by Alexander Makarov

Fixes #5627: Added `yii cache/flush-schema` console command to flush DB schema…

Fixes #5627: Added `yii cache/flush-schema` console command to flush DB schema cache of a given database connection
parent 89d1dde9
...@@ -322,6 +322,7 @@ Yii Framework 2 Change Log ...@@ -322,6 +322,7 @@ Yii Framework 2 Change Log
- Enh #5124: Added support to prevent duplicated form submission when using `ActiveForm` (qiangxue) - Enh #5124: Added support to prevent duplicated form submission when using `ActiveForm` (qiangxue)
- Enh #5131: Added `$autoRenew` parameter to `yii\web\User::getIdentity()` (qiangxue) - Enh #5131: Added `$autoRenew` parameter to `yii\web\User::getIdentity()` (qiangxue)
- Enh #5164: Added `Inlfector::$transliterator` that can be used to customize intl transliteration (zinzinday) - Enh #5164: Added `Inlfector::$transliterator` that can be used to customize intl transliteration (zinzinday)
- Enh #5627: Added `yii cache/flush-schema` console command to flush DB schema cache of a given database connection (6pblcb, samdark)
- Enh: Added support for using sub-queries when building a DB query with `IN` condition (qiangxue) - Enh: Added support for using sub-queries when building a DB query with `IN` condition (qiangxue)
- Enh: Supported adding a new response formatter without the need to reconfigure existing formatters (qiangxue) - Enh: Supported adding a new response formatter without the need to reconfigure existing formatters (qiangxue)
- Enh: Added `yii\web\UrlManager::addRules()` to simplify adding new URL rules (qiangxue) - Enh: Added `yii\web\UrlManager::addRules()` to simplify adding new URL rules (qiangxue)
......
...@@ -125,6 +125,45 @@ class CacheController extends Controller ...@@ -125,6 +125,45 @@ class CacheController extends Controller
} }
/** /**
* Clears DB schema cache for a given connection component.
*
* ~~~
* # clears cache schema specified by component id: "db"
* yii cache/flush-schema db
* ~~~
*
* @param string $db id connection component
* @return int exit code
* @throws Exception
* @throws \yii\base\InvalidConfigException
*
* @since 2.0.1
*/
public function actionFlushSchema($db = 'db')
{
$connection = Yii::$app->get($db, false);
if ($connection === null) {
$this->stdout("Unknown component \"$db\".\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
}
if (!$connection instanceof \yii\db\Connection) {
$this->stdout("\"$db\" component doesn't inherit \\yii\\db\\Connection.\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
} else if (!$this->confirm("Flush cache schema for \"$db\" connection?")) {
return static::EXIT_CODE_NORMAL;
}
try {
$schema = $connection->getSchema();
$schema->refresh();
$this->stdout("Schema cache for component \"$db\", was flushed.\n\n", Console::FG_GREEN);
} catch (\Exception $e) {
$this->stdout($e->getMessage() . "\n\n", Console::FG_RED);
}
}
/**
* Notifies user that given caches are found and can be flushed. * Notifies user that given caches are found and can be flushed.
* @param array $caches array of cache component classes * @param array $caches array of cache component classes
*/ */
......
...@@ -20,6 +20,8 @@ class CacheControllerTest extends TestCase ...@@ -20,6 +20,8 @@ class CacheControllerTest extends TestCase
*/ */
private $_cacheController; private $_cacheController;
private $driverName = 'mysql';
protected function setUp() protected function setUp()
{ {
parent::setUp(); parent::setUp();
...@@ -28,14 +30,41 @@ class CacheControllerTest extends TestCase ...@@ -28,14 +30,41 @@ class CacheControllerTest extends TestCase
'class' => 'yiiunit\framework\console\controllers\CacheConsoledController', 'class' => 'yiiunit\framework\console\controllers\CacheConsoledController',
'interactive' => false, 'interactive' => false,
],[null, null]); //id and module are null ],[null, null]); //id and module are null
$databases = self::getParam('databases');
$config = $databases[$this->driverName];
$pdoDriver = 'pdo_' . $this->driverName;
if (!extension_loaded('pdo') || !extension_loaded($pdoDriver)) {
$this->markTestSkipped('pdo and ' . $pdoDriver . ' extensions are required.');
}
$this->mockApplication([ $this->mockApplication([
'components' => [ 'components' => [
'firstCache' => 'yii\caching\ArrayCache', 'firstCache' => 'yii\caching\ArrayCache',
'secondCache' => 'yii\caching\ArrayCache', 'secondCache' => 'yii\caching\ArrayCache',
'session' => 'yii\web\CacheSession', // should be ignored at `actionFlushAll()` 'session' => 'yii\web\CacheSession', // should be ignored at `actionFlushAll()`
'db' => [
'class' => isset($config['class']) ? $config['class'] : 'yii\db\Connection',
'dsn' => $config['dsn'],
'username' => isset($config['username']) ? $config['username'] : null,
'password' => isset($config['password']) ? $config['password'] : null,
'enableSchemaCache' => true,
'schemaCache' => 'firstCache',
],
], ],
]); ]);
if(isset($config['fixture'])) {
Yii::$app->db->open();
$lines = explode(';', file_get_contents($config['fixture']));
foreach ($lines as $line) {
if (trim($line) !== '') {
Yii::$app->db->pdo->exec($line);
}
}
}
} }
public function testFlushOne() public function testFlushOne()
...@@ -50,6 +79,25 @@ class CacheControllerTest extends TestCase ...@@ -50,6 +79,25 @@ class CacheControllerTest extends TestCase
$this->assertFalse(Yii::$app->firstCache->get('secondKey'),'first cache data should be flushed'); $this->assertFalse(Yii::$app->firstCache->get('secondKey'),'first cache data should be flushed');
$this->assertEquals('thirdValue', Yii::$app->secondCache->get('thirdKey'), 'second cache data should not be flushed'); $this->assertEquals('thirdValue', Yii::$app->secondCache->get('thirdKey'), 'second cache data should not be flushed');
} }
public function testClearSchema()
{
$schema = Yii::$app->db->schema;
Yii::$app->db->createCommand()->createTable('test_schema_cache', ['id' => 'pk'])->execute();
$noCacheSchemas = $schema->getTableSchemas('', true);
$cacheSchema = $schema->getTableSchemas('', false);
$this->assertEquals($noCacheSchemas, $cacheSchema, 'Schema should not be modified.');
Yii::$app->db->createCommand()->dropTable('test_schema_cache')->execute();
$noCacheSchemas = $schema->getTableSchemas('', true);
$this->assertNotEquals($noCacheSchemas, $cacheSchema, 'Schemas should be different.');
$this->_cacheController->actionFlushSchema('db');
$cacheSchema = $schema->getTableSchemas('', false);
$this->assertEquals($noCacheSchemas, $cacheSchema, 'Schema cache should be flushed.');
}
public function testFlushBoth() public function testFlushBoth()
{ {
......
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