diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 037e90ec2a..b37d039ee8 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -36,7 +36,7 @@ Yii Framework 2 Change Log - Enh #12881: Added `removeValue` method to `yii\helpers\BaseArrayHelper` (nilsburg) - Enh #12901: Added `getDefaultHelpHeader` method to the `yii\console\controllers\HelpController` class to be able to override default help header in a class heir (diezztsk) - Enh: Added constants for specifying `yii\validators\CompareValidator::$type` (cebe) -- Bug #12974: Changed order of migrations history in `yii\console\controllers\MigrateController::getMigrationHistory()` (evgen-d) +- Bug #12974: Fixed incorrect order of migrations history in case `yii\console\controllers\MigrateController::$migrationNamespaces` is in use (evgen-d, klimov-paul) 2.0.10 October 20, 2016 diff --git a/framework/console/controllers/MigrateController.php b/framework/console/controllers/MigrateController.php index 58941a3b3c..a91c6220ef 100644 --- a/framework/console/controllers/MigrateController.php +++ b/framework/console/controllers/MigrateController.php @@ -199,27 +199,48 @@ class MigrateController extends BaseMigrateController if ($this->db->schema->getTableSchema($this->migrationTable, true) === null) { $this->createMigrationHistoryTable(); } - $query = new Query; - $rows = $query->select(['version', 'apply_time']) + $query = (new Query()) + ->select(['version', 'apply_time']) ->from($this->migrationTable) - ->orderBy('apply_time DESC, version DESC') - ->limit($limit) - ->createCommand($this->db) - ->queryAll(); + ->orderBy(['apply_time' => SORT_DESC, 'version' => SORT_DESC]); + + if (empty($this->migrationNamespaces)) { + $query->limit($limit); + $rows = $query->all($this->db); + $history = ArrayHelper::map($rows, 'version', 'apply_time'); + unset($history[self::BASE_MIGRATION]); + return $history; + } + + $rows = $query->all($this->db); + $history = []; - foreach ($rows as $row) { + foreach ($rows as $key => $row) { if ($row['version'] === self::BASE_MIGRATION) { continue; } if (preg_match('/m?(\d{6}_?\d{6})(\D.*)?$/is', $row['version'], $matches)) { $time = str_replace('_', '', $matches[1]); - $history['m' . $time . $matches[2]] = $row; + $row['canonicalVersion'] = $time; + } else { + $row['canonicalVersion'] = $row['version']; } + $row['apply_time'] = (int)$row['apply_time']; + $history[] = $row; } - // sort history in desc order - uksort($history, function ($a, $b) { - return strcasecmp($b, $a); + + usort($history, function ($a, $b) { + if ($a['apply_time'] === $b['apply_time']) { + if (($compareResult = strcasecmp($b['canonicalVersion'], $a['canonicalVersion'])) !== 0) { + return $compareResult; + } + return strcasecmp($b['version'], $a['version']); + } + return ($a['apply_time'] > $b['apply_time']) ? -1 : +1; }); + + $history = array_slice($history, 0, $limit); + $history = ArrayHelper::map($history, 'version', 'apply_time'); return $history; diff --git a/tests/framework/console/controllers/MigrateControllerTest.php b/tests/framework/console/controllers/MigrateControllerTest.php index 1dbf4d4ae8..c22cd74733 100644 --- a/tests/framework/console/controllers/MigrateControllerTest.php +++ b/tests/framework/console/controllers/MigrateControllerTest.php @@ -218,4 +218,60 @@ class MigrateControllerTest extends TestCase $this->assertCommandCreatedFile('junction_test', $migrationName, 'post_tag'); } } + + /** + * @see https://github.com/yiisoft/yii2/issues/12980 + */ + public function testGetMigrationHistory() + { + $controllerConfig = [ + 'migrationPath' => null, + 'migrationNamespaces' => [$this->migrationNamespace] + ]; + $this->runMigrateControllerAction('history', [], $controllerConfig); + + $controller = $this->createMigrateController($controllerConfig); + $controller->db = Yii::$app->db; + + Yii::$app->db->createCommand() + ->batchInsert( + 'migration', + ['version', 'apply_time'], + [ + ['app\migrations\M140506102106One', 10], + ['app\migrations\M160909083544Two', 10], + ['app\modules\foo\migrations\M161018124749Three', 10], + ['app\migrations\M160930135248Four', 20], + ['app\modules\foo\migrations\M161025123028Five', 20], + ['app\migrations\M161110133341Six', 20], + ] + ) + ->execute(); + + $rows = $this->invokeMethod($controller, 'getMigrationHistory', [10]); + + $this->assertSame( + [ + 'app\migrations\M161110133341Six', + 'app\modules\foo\migrations\M161025123028Five', + 'app\migrations\M160930135248Four', + 'app\modules\foo\migrations\M161018124749Three', + 'app\migrations\M160909083544Two', + 'app\migrations\M140506102106One', + ], + array_keys($rows) + ); + + $rows = $this->invokeMethod($controller, 'getMigrationHistory', [4]); + + $this->assertSame( + [ + 'app\migrations\M161110133341Six', + 'app\modules\foo\migrations\M161025123028Five', + 'app\migrations\M160930135248Four', + 'app\modules\foo\migrations\M161018124749Three', + ], + array_keys($rows) + ); + } } \ No newline at end of file