i have a webapplication which upgrades themself its database. (so users have only copy the files of the new application version and db upgrading is done automatically)
i have extended the MigrateCommand-class to use the integrated yii migration feature. this works fine.
my problem is:
i have to execute this db-migration code. (first check if db upgrade is required and ugrade if necessary)
it would be great to execute it directly before the first action is called. this means i already need all yii functions for db-migration, but it should be executed BEFORE the action.
is there any documention about the start process of YII? maybe i can extend some class and inject my db-upgrade code
We added a filter to our base controller (protected/components/Controller.php)
public function filters()
{
return array('checkDatabase','accessControl');
}
public function filterCheckDatabase($filterChain)
{
Installer::checkDatabase();
$filterChain->run();
}
And then checkDatabase looks like this:
public static function checkDatabase()
{
$run_migration = false;
$very_first_run = false;
if (defined('RUNNING_TESTS'))
return;
// check database
$connection=Yii::app()->db;
// if we can't get connection then fail
if (!$connection)
return;
// count loaded migrations
$sql = "select count(*) from tbl_migration";
$command=$connection->createCommand($sql);
try {
$db_migs = @$command->queryScalar();
} catch (CDbException $e) {
// if we fail the query do migration
$very_first_run = true;
}
if ($db_migs === false)
$run_migration = true;
else
{
// don't count "base" migration
$db_migs--;
// count file migrations
$pattern = dirname(__FILE__).'/../migrations/m*.php';
$files = glob($pattern);
$run_migration = count($files) > $db_migs;
}
if ($run_migration)
{
self::runMigration();
Alerts::log("Database structure updated.", Alerts::SEVERITY_INFO);
if (! $very_first_run)
Yii::app()->user->setFlash('success', "Updated database structure.");
Yii::app()->poller->reloadSystemSettings();
}
}
public static function runMigration($down = false)
{
$runner = new CConsoleCommandRunner();
$commandPath = Yii::getFrameworkPath() . DIRECTORY_SEPARATOR . 'cli' . DIRECTORY_SEPARATOR . 'commands';
$runner->addCommands($commandPath);
$args = array('yiic', 'migrate', '--interactive=0');
if ($down)
$args[] = 'down';
ob_start();
$runner->run($args);
return ob_get_clean();
}