Commit 8a048e99 by Alexander Makarov

Merge pull request #2499 from resurtm/migrate-to-datetime

Add an ability to downgrade migrations by the absolute apply time
parents ddb7141e 1974524e
...@@ -117,6 +117,7 @@ Yii Framework 2 Change Log ...@@ -117,6 +117,7 @@ Yii Framework 2 Change Log
- Enh #2436: Label of the attribute, which looks like `relatedModel.attribute`, will be received from the related model if it available (djagya) - Enh #2436: Label of the attribute, which looks like `relatedModel.attribute`, will be received from the related model if it available (djagya)
- Enh #2415: Added support for inverse relations (qiangxue) - Enh #2415: Added support for inverse relations (qiangxue)
- Enh #2490: `yii\db\Query::count()` and other query scalar methods now properly handle queries with GROUP BY clause (qiangxue) - Enh #2490: `yii\db\Query::count()` and other query scalar methods now properly handle queries with GROUP BY clause (qiangxue)
- Enh #2499: Added ability to downgrade migrations by their absolute apply time (resurtm, gorcer)
- Enh: Added support for using arrays as option values for console commands (qiangxue) - Enh: Added support for using arrays as option values for console commands (qiangxue)
- Enh: Added `favicon.ico` and `robots.txt` to default application templates (samdark) - Enh: Added `favicon.ico` and `robots.txt` to default application templates (samdark)
- Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue) - Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue)
......
...@@ -286,52 +286,39 @@ class MigrateController extends Controller ...@@ -286,52 +286,39 @@ class MigrateController extends Controller
/** /**
* Upgrades or downgrades till the specified version. * Upgrades or downgrades till the specified version.
* *
* Can also downgrade versions to the certain apply time in the past by providing
* a UNIX timestamp or a string parseable by the strtotime() function. This means
* that all the versions applied after the specified certain time would be reverted.
*
* This command will first revert the specified migrations, and then apply * This command will first revert the specified migrations, and then apply
* them again. For example, * them again. For example,
* *
* ~~~ * ~~~
* yii migrate/to 101129_185401 # using timestamp * yii migrate/to 101129_185401 # using timestamp
* yii migrate/to m101129_185401_create_user_table # using full name * yii migrate/to m101129_185401_create_user_table # using full name
* yii migrate/to 1392853618 # using UNIX timestamp
* yii migrate/to "2014-02-15 13:00:50" # using strtotime() parseable string
* ~~~ * ~~~
* *
* @param string $version the version name that the application should be migrated to. * @param string $version either the version name or the certain time value in the past
* This can be either the timestamp or the full name of the migration. * that the application should be migrated to. This can be either the timestamp,
* @throws Exception if the version argument is invalid * the full name of the migration, the UNIX timestamp, or the parseable datetime
* string.
* @throws Exception if the version argument is invalid.
*/ */
public function actionTo($version) public function actionTo($version)
{ {
$originalVersion = $version;
if (preg_match('/^m?(\d{6}_\d{6})(_.*?)?$/', $version, $matches)) { if (preg_match('/^m?(\d{6}_\d{6})(_.*?)?$/', $version, $matches)) {
$version = 'm' . $matches[1]; $this->migrateToVersion('m' . $matches[1]);
} else { } elseif ((string)(int)$version == $version) {
throw new Exception("The version argument must be either a timestamp (e.g. 101129_185401)\nor the full name of a migration (e.g. m101129_185401_create_user_table)."); $this->migrateToTime($version);
} } elseif (($time = strtotime($version)) !== false) {
$this->migrateToTime($time);
// try migrate up
$migrations = $this->getNewMigrations();
foreach ($migrations as $i => $migration) {
if (strpos($migration, $version . '_') === 0) {
$this->actionUp($i + 1);
return;
}
}
// try migrate down
$migrations = array_keys($this->getMigrationHistory(-1));
foreach ($migrations as $i => $migration) {
if (strpos($migration, $version . '_') === 0) {
if ($i === 0) {
echo "Already at '$originalVersion'. Nothing needs to be done.\n";
} else { } else {
$this->actionDown($i); throw new Exception("The version argument must be either a timestamp (e.g. 101129_185401),\n the full name of a migration (e.g. m101129_185401_create_user_table),\n a UNIX timestamp (e.g. 1392853000), or a datetime string parseable\nby the strtotime() function (e.g. 2014-02-15 13:00:50).");
}
return;
} }
} }
throw new Exception("Unable to find the version '$originalVersion'.");
}
/** /**
* Modifies the migration history to the specified version. * Modifies the migration history to the specified version.
* *
...@@ -568,6 +555,58 @@ class MigrateController extends Controller ...@@ -568,6 +555,58 @@ class MigrateController extends Controller
} }
/** /**
* Migrates to the specified apply time in the past.
* @param integer $time UNIX timestamp value.
*/
protected function migrateToTime($time)
{
$count = 0;
$migrations = array_values($this->getMigrationHistory(-1));
while ($count < count($migrations) && $migrations[$count] > $time) {
++$count;
}
if ($count === 0) {
echo "Nothing needs to be done.\n";
} else {
$this->actionDown($count);
}
}
/**
* Migrates to the certain version.
* @param string $version name in the full format.
* @throws Exception if the provided version cannot be found.
*/
protected function migrateToVersion($version)
{
$originalVersion = $version;
// try migrate up
$migrations = $this->getNewMigrations();
foreach ($migrations as $i => $migration) {
if (strpos($migration, $version . '_') === 0) {
$this->actionUp($i + 1);
return;
}
}
// try migrate down
$migrations = array_keys($this->getMigrationHistory(-1));
foreach ($migrations as $i => $migration) {
if (strpos($migration, $version . '_') === 0) {
if ($i === 0) {
echo "Already at '$originalVersion'. Nothing needs to be done.\n";
} else {
$this->actionDown($i);
}
return;
}
}
throw new Exception("Unable to find the version '$originalVersion'.");
}
/**
* Returns the migration history. * Returns the migration history.
* @param integer $limit the maximum number of records in the history to be returned * @param integer $limit the maximum number of records in the history to be returned
* @return array the migration history * @return array the migration history
......
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