A migration means a set of persistent changes to the application environment
that is shared among different developers. For example, in an application
backed by a database, a migration may refer to a set of changes to
the database, such as creating a new table, adding a new table column.
This command provides support for tracking the migration history, upgrading
or downloading with migrations, and creating new migration skeletons.
The migration history is stored in a database table named
as [[migrationTable]]. The table will be automatically created the first time
this command is executed, if it does not exist. You may also manually
create it as follows:
~~~
CREATE TABLE migration (
version varchar(180) PRIMARY KEY,
apply_time integer
)
~~~
Below are some common usages of this command:
~~~
# creates a new migration named 'create_user_table'
yii migrate/create create_user_table
# applies ALL new migrations
yii migrate
# reverts the last applied migration
yii migrate/down
~~~
/** * Установка миграций * Копирует миграции в папку миграций ($this->migrationPath = /console/migrations/) */ protected function migrates($migrationPath) { if (!is_dir($migrationPath)) { return 0; } if (!is_dir($this->migrationPath)) { FileHelper::createDirectory($this->migrationPath); } $this->output("> migrates from " . $migrationPath); $migrateFiles = FileHelper::findFiles($migrationPath, ['only' => ['m*.php'], 'recursive' => false]); $migration = new MigrateController("module-migration", Yii::$app, ['migrationPath' => $this->migrationPath, 'db' => Yii::$app->db, 'interactive' => false]); $cnt = 0; foreach ($migrateFiles as $migrateFile) { $version = basename($migrateFile); try { copy($migrateFile, $this->migrationPath . '/' . $version); $migration->actionTo($version); $cnt++; } catch (\Exception $exception) { $this->output($exception->getMessage()); } } if ($cnt > 0) { $this->output(" - To cancel migations:"); $this->output(" yii migrate/down " . $cnt); } return $cnt; }
public function setUp() { $this->migrateControllerClass = MigrateController::className(); $this->migrationBaseClass = Migration::className(); $this->mockApplication(['components' => ['db' => ['class' => 'yii\\db\\Connection', 'dsn' => 'sqlite::memory:']]]); $this->setUpMigrationPath(); parent::setUp(); }
/** * @inheritdoc */ public function beforeAction($action) { echo "\n"; if ($this->showBaseMigration) { $this->additionalPaths = ArrayHelper::merge([['name' => $this->baseMigrationName, 'path' => $this->migrationPath]], $this->additionalPaths); } $this->selectModule(); return parent::beforeAction($action); }
public function beforeAction($action) { if (parent::beforeAction($action)) { $this->initModuleMigrationDirectories(); return true; } else { return false; } }
/** * @inheritDoc */ public function actionDown($limit = 'all') { $ret = parent::actionDown('all'); $query = new Query(); $query->from($this->migrationTable); if (1 == $query->count()) { $this->deleteMigrationHistoryTable(); } return $ret; }
/** * @inheritDoc */ public function actionDown($limit = 'all') { $ret = parent::actionDown('all'); $query = new Query(); $query->from($this->migrationTable); if (1 == $query->count()) { $tableName = $this->db->schema->getRawTableName($this->migrationTable); $this->stdout("Deleting migration history table \"{$tableName}\"...", Console::FG_YELLOW); $this->db->createCommand()->dropTable($this->migrationTable)->execute(); $this->stdout("Done.\n", Console::FG_GREEN); } return $ret; }
/** * Returns the migrations that are not applied. * @return array list of new migrations */ protected function getNewMigrations() { $applied = []; foreach ($this->getMigrationHistory(-1) as $version => $time) { $applied[substr($version, 1, 13)] = true; } $migrations = parent::getNewMigrations(); $handle = opendir($this->migrationPlatformPath); while (($file = readdir($handle)) !== false) { if ($file === '.' || $file === '..') { continue; } $path = $this->migrationPlatformPath . DIRECTORY_SEPARATOR . $file; if (preg_match('/^(m(\\d{6}_\\d{6})_.*?)\\.php$/', $file, $matches) && is_file($path) && !isset($applied[$matches[2]])) { $migrations[] = $matches[1]; } } closedir($handle); sort($migrations); return $migrations; }
/** @inheritdoc */ public function confirm($message, $default = false) { $this->stdout($message); $this->stdout(" YES\n", self::FG_WHITE); return parent::confirm($message, $default); }
/** * @inheritdoc */ public function options($actionId) { return array_merge(parent::options($actionId), $actionId == 'create' ? ['lang'] : []); }
/** * Filter migrations only with namespace * @return array */ protected function getNewMigrations() { $migrations = parent::getNewMigrations(); $migrations = array_filter($migrations, [$this, 'nameHasNamespace']); return $migrations; }
/** * Creates a new migration instance. * @param string $class the migration class name * @return \yii\db\MigrationInterface the migration instance */ protected function createMigration($class) { if ($this->includeModuleMigrations) { $this->migrationPath = $this->getMigrationPath($class); } return parent::createMigration($class); }
/** * @inheritdoc */ public function stderr($string) { if (Yii::$app instanceof \yii\web\Application) { print $string; } else { return parent::stderr($string); } }
<?php Yii::setAlias('@tests', dirname(__DIR__) . '/tests'); use yii\helpers\ArrayHelper; $sfCommon = __DIR__ . DIRECTORY_SEPARATOR . 'common.php'; $sfCommonLocal = __DIR__ . DIRECTORY_SEPARATOR . 'common-local.php'; $sfConLocal = __DIR__ . DIRECTORY_SEPARATOR . 'console-local.php'; $config = ['id' => 'basic-console', 'controllerNamespace' => 'app\\commands', 'controllerMap' => ['migrate' => ['class' => \yii\console\controllers\MigrateController::className(), 'templateFile' => '@app/views/migration.php']], 'modules' => ['gii' => 'yii\\gii\\Module'], 'components' => ['log' => ['targets' => [['class' => 'yii\\log\\FileTarget', 'levels' => ['error', 'warning', 'info'], 'logFile' => '@app/runtime/logs/console.log', 'maxFileSize' => 300, 'maxLogFiles' => 3]]]]]; $config = ArrayHelper::merge(require $sfCommon, file_exists($sfCommonLocal) ? require $sfCommonLocal : [], $config, file_exists($sfConLocal) ? require $sfConLocal : []); //print_r($config); //die(); return $config; /* return [ 'id' => 'basic-console', 'basePath' => dirname(__DIR__), 'bootstrap' => ['log', 'gii'], 'controllerNamespace' => 'app\commands', 'modules' => [ 'gii' => 'yii\gii\Module', ], 'components' => [ 'cache' => [ 'class' => 'yii\caching\FileCache', ], 'log' => [ 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], ],
public function getNewMigrations() { return parent::getNewMigrations(); }
public function options($actionID) { return array_merge(parent::options($actionID), ['migrationPaths']); }
<?php $config = ['id' => 'app-console', 'basePath' => \Yii::getAlias('@tests'), 'runtimePath' => \Yii::getAlias('@tests/_output'), 'controllerMap' => ['migrate' => ['class' => \yii\console\controllers\MigrateController::className(), 'migrationPath' => dirname(\Yii::getAlias('@tests')) . '/src/migrations']], 'components' => ['scheduler' => ['class' => \understeam\scheduler\Scheduler::className(), 'executor' => ['class' => \understeam\scheduler\CommandBusExecutor::className(), 'commandBus' => 'commandBus']], 'db' => ['class' => \yii\db\Connection::className(), 'dsn' => 'sqlite:' . \Yii::getAlias('@tests/_output/scheduler.db')], 'commandBus' => \trntv\bus\CommandBus::className()]]; new yii\console\Application($config);
/** * Gives the user an option to choose from. Giving '?' as an input will show * a list of options to choose from and their explanations. * * @param string $prompt the prompt message * @param array $options Key-value array of options to choose from * * @return string An option character the user chose */ public function options($actionID) { return array_merge(parent::options($actionID), ['class', 'host', 'name', 'username', 'password', 'language', 'charset']); }
public function __construct($id, $module, $config = []) { parent::__construct($id, $module, $config); // TODO: Change the autogenerated stub }
protected function getMigrationHistory($limit) { if ($this->moduleId) { $module = Yii::$app->getModule($this->moduleId); if ($module === null) { throw new Exception('Module "' . $this->moduleId . '" not found'); } $migrationHistory = parent::getMigrationHistory(false); $modulesMigration = $this->getModuleMigrations($this->moduleId); $filteredMigration = []; foreach ($migrationHistory as $key => $migration) { if (isset($modulesMigration[$key])) { $filteredMigration[$key] = $migration; } } $migrationHistory = $filteredMigration; } else { $migrationHistory = parent::getMigrationHistory($limit); } return $migrationHistory; }
/** * @inheritdoc */ public function options($actionId) { return array_merge(parent::options($actionId), ['migrationLookup']); }
/** * This method is invoked right before an action is to be executed (after all possible filters.) * It checks the existence of the [[migrationPath]]. * @param \yii\base\Action $action the action to be executed. * @return boolean whether the action should continue to be executed. */ public function beforeAction($action) { $this->migrationPath = \Yii::getAlias($this->_runtimeMigrationPath); $this->_copyMigrations(); return parent::beforeAction($action); }
public function actionUp($limit = 0, $version = null) { $this->appVersion = $version; parent::actionUp($limit); }
/** * @inheritdoc */ public function options($actionID) { return array_merge(parent::options($actionID), $actionID == 'create' ? ['command', 'columnType', 'column', 'tableOptions', 'table'] : []); }
public function stdout($string) { return Yii::$app instanceof Application ? parent::stdout($string) : true; }