diff --git a/docs/guide/db-migrations.md b/docs/guide/db-migrations.md
index 5349a07..5c83cea 100644
--- a/docs/guide/db-migrations.md
+++ b/docs/guide/db-migrations.md
@@ -181,17 +181,20 @@ class m150101_185401_create_news_table extends Migration
A list of all available methods for defining the column types is available in the API documentation of [[yii\db\SchemaBuilderTrait]].
-## Creating Migrations with Generators
+## Generating Migrations
-Since version 2.0.7 migration console which provides convenient way creating migrations.
+Since version 2.0.7 migration console provides a convenient way to create migrations.
-If the migration name is of the form "create_xxx" or "drop_xxx" then a migration creating the table xxx with the columns listed will be generated. For example:
+If the migration name is of a special form including but not limited to `create_xxx` or `drop_xxx` then migration
+file would contain extra code when generated.
+
+### Create Table
```php
yii migrate/create create_post
```
-generates
+generates
```php
class m150811_220037_create_post extends Migration
@@ -210,13 +213,13 @@ class m150811_220037_create_post extends Migration
}
```
-For create column schema you may use fields option with as follows:
+To create table fields right away, specify them via `--fields` option.
```php
yii migrate/create create_post --fields=title:string,body:text
```
-generates
+generates
```php
class m150811_220037_create_post extends Migration
@@ -237,7 +240,7 @@ class m150811_220037_create_post extends Migration
}
```
-You are not limited to one magically generated column. For example:
+You can specify more field parameters.
```php
yii migrate/create create_post --fields=title:string(12):notNull:unique,body:text
@@ -264,10 +267,11 @@ class m150811_220037_create_post extends Migration
}
```
-> Note: primary Key is added automatically, if you want to use another name for primary key, you
-may specify in fields options, for example "--fields=name:primaryKey"
+> Note: primary key is added automatically and is named `id` by default. If you want to use another name you may
+> specify it explicitly like `--fields=name:primaryKey`.
+
-Similarly, you can generate a migration to drop table from the command line:
+### Drop Table
```php
yii migrate/create drop_post
@@ -291,16 +295,21 @@ class m150811_220037_drop_post extends Migration
}
```
-If the migration name is of the form "add_xxx_from_yyy" or "drop_xxx_from_yyy" then a migration containing the appropriate addColumn and dropColumn statements will be created.
+### Add Column
+
+If the migration name is of the form `add_xxx_to_yyy` then the file content would contain `addColumn` and `dropColumn`
+statements necessary.
+
+To add column:
```php
-yii migrate/create add_position_from_post --fields=position:integer
+yii migrate/create add_position_to_post --fields=position:integer
```
generates
```php
-class m150811_220037_add_position_from_post extends Migration
+class m150811_220037_add_position_to_post extends Migration
{
public function up()
{
@@ -314,7 +323,10 @@ class m150811_220037_add_position_from_post extends Migration
}
```
-Similarly, you can generate a migration to remove a column from the command line:
+### Drop Column
+
+If the migration name is of the form `drop_xxx_from_yyy` then the file content would contain `addColumn` and `dropColumn`
+statements necessary.
```php
yii migrate/create drop_position_from_post --fields=position:integer
@@ -337,16 +349,19 @@ class m150811_220037_remove_position_from_post extends Migration
}
```
-There is also a generator which will produce join tables If the migration name is of the form "create_join_xxx_and_yyy"
+### Add Junction Table
+
+If the migration name is in if the form of `create_junction_xxx_and_yyy` then code necessary to create junction table
+will be generated.
```php
-yii create/migration create_join_post_and_tag
+yii create/migration create_junction_post_and_tag
```
generates
```php
-class m150811_220037_create_join_post_and_tag extends Migration
+class m150811_220037_create_junction_post_and_tag extends Migration
{
public function up()
{
@@ -370,7 +385,6 @@ class m150811_220037_create_join_post_and_tag extends Migration
}
```
-
### Transactional Migrations
While performing complex DB migrations, it is important to ensure each migration to either succeed or fail as a whole
@@ -599,17 +613,18 @@ The migration command comes with a few command-line options that can be used to
or a path [alias](concept-aliases.md). The template file is a PHP script in which you can use a predefined variable
named `$className` to get the migration class name.
-* `generatorTemplateFile`: array (defaults to `[
+* `generatorTemplateFiles`: array (defaults to `[
'create' => '@yii/views/createMigration.php',
'drop' => '@yii/views/dropMigration.php',
'add' => '@yii/views/addMigration.php',
'remove' => '@yii/views/removeMigration.php',
- 'create_join' => '@yii/views/createJoinMigration.php'
- ]`), specifies template files for generating migration code automatically. See [Creating Migrations with Generators](#creating-migrations-with-generators)
+ 'create_junction' => '@yii/views/createJunctionMigration.php'
+ ]`), specifies template files for generating migration code. See "[Generating Migrations](#generating-migrations)"
for more details.
-* `fields`: array (defaults to `[]`), specifies the fields column use to creating migration automatically. The format that it use when declaring any applicable schema it is
-`COLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR`, for example `--fields=name:string(12):notNull`, it specify string column with 12 size and not null.
+* `fields`: array of column definition strings used for creating migration code. Defaults to `[]`. The format of each
+ definition is `COLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR`. For example, `--fields=name:string(12):notNull` produces
+ a string column of size 12 which is not null.
The following example shows how you can use these options.
diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md
index b4ecf23..ea2e709 100644
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -48,6 +48,7 @@ Yii Framework 2 Change Log
- Enh #8649: Added total applied migrations to final report (vernik91)
- Enh #9282: Improved JSON error handling to support PHP 5.5 error codes (freezy-sk)
- Enh #9337: Added `yii\db\ColumnSchemaBuilder::defaultExpression()` to support DB Expression as default value (kotchuprik)
+- Enh #9465: ./yii migrate/create now generates code based on migration name and --fields (pana1990)
- Enh #9476: Added DI injection via controller action method signature (mdmunir)
- Enh #9635: Added default CSS class for `\yii\grid\ActionColumn` header (arogachev, dynasource)
- Enh #9643: Added migrations for DB cache (mdmunir)
diff --git a/framework/console/controllers/BaseMigrateController.php b/framework/console/controllers/BaseMigrateController.php
index d8f3c72..48c8df6 100644
--- a/framework/console/controllers/BaseMigrateController.php
+++ b/framework/console/controllers/BaseMigrateController.php
@@ -42,12 +42,12 @@ abstract class BaseMigrateController extends Controller
*/
public $templateFile;
/**
- * @var array the template file for generating migration code automatically.
- * This can be either a path alias (e.g. "@app/migrations/template.php")
+ * @var array a set of template files for generating migration code automatically.
+ * Each one can be either a path alias (e.g. "@app/migrations/template.php")
* or a file path.
* @since 2.0.7
*/
- public $generatorTemplateFile;
+ public $generatorTemplateFiles;
/**
* @var array Fields to be generated
* @since 2.0.7
@@ -63,9 +63,7 @@ abstract class BaseMigrateController extends Controller
return array_merge(
parent::options($actionID),
['migrationPath'], // global for all actions
- ($actionID === 'create')
- ? ['templateFile', 'templateFileGenerators', 'fields']
- : [] // action create
+ $actionID === 'create' ? ['templateFile', 'templateFileGenerators', 'fields'] : [] // action create
);
}
@@ -87,7 +85,7 @@ abstract class BaseMigrateController extends Controller
FileHelper::createDirectory($path);
}
$this->migrationPath = $path;
- $this->parseField();
+ $this->parseFields();
$version = Yii::getVersion();
$this->stdout("Yii Migration Tool (based on Yii v{$version})\n\n");
@@ -494,36 +492,39 @@ abstract class BaseMigrateController extends Controller
$file = $this->migrationPath . DIRECTORY_SEPARATOR . $className . '.php';
if ($this->confirm("Create new migration '$file'?")) {
- if (preg_match('/^create_join_(.+)_and_(.+)$/', $name, $matches)) {
- $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['create_join']), [
+ if (preg_match('/^create_junction_(.+)_and_(.+)$/', $name, $matches)) {
+ $firstTable = mb_strtolower($matches[1], Yii::$app->charset);
+ $secondTable = mb_strtolower($matches[2], Yii::$app->charset);
+
+ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['create_junction']), [
'className' => $className,
- 'table' => mb_strtolower($matches[1]) . '_' . mb_strtolower($matches[2]),
- 'field_first' => mb_strtolower($matches[1]),
- 'field_second' => mb_strtolower($matches[2]),
+ 'table' => $firstTable . '_' . $secondTable,
+ 'field_first' => $firstTable,
+ 'field_second' => $secondTable,
]);
- } elseif (preg_match('/^add_(.+)from_(.+)$/', $name, $matches)) {
- $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['add']), [
+ } elseif (preg_match('/^add_(.+)_to_(.+)$/', $name, $matches)) {
+ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['add']), [
'className' => $className,
- 'table' => mb_strtolower($matches[2]),
+ 'table' => mb_strtolower($matches[2], Yii::$app->charset),
'fields' => $this->fields
]);
- } elseif (preg_match('/^drop_(.+)from_(.+)$/', $name, $matches)) {
- $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['remove']), [
+ } elseif (preg_match('/^drop_(.+)_from_(.+)$/', $name, $matches)) {
+ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['remove']), [
'className' => $className,
- 'table' => mb_strtolower($matches[2]),
+ 'table' => mb_strtolower($matches[2], Yii::$app->charset),
'fields' => $this->fields
]);
} elseif (preg_match('/^create_(.+)$/', $name, $matches)) {
- $this->checkPrimaryKey();
- $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['create']), [
+ $this->addDefaultPrimaryKey();
+ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['create']), [
'className' => $className,
- 'table' => mb_strtolower($matches[1]),
+ 'table' => mb_strtolower($matches[1], Yii::$app->charset),
'fields' => $this->fields
]);
} elseif (preg_match('/^drop_(.+)$/', $name, $matches)) {
- $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['drop']), [
+ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['drop']), [
'className' => $className,
- 'table' => mb_strtolower($matches[1]),
+ 'table' => mb_strtolower($matches[1], Yii::$app->charset),
'fields' => $this->fields
]);
} else {
@@ -689,10 +690,10 @@ abstract class BaseMigrateController extends Controller
}
/**
- * Parse the command line migration fields.
+ * Parse the command line migration fields
* @since 2.0.7
*/
- protected function parseField()
+ protected function parseFields()
{
if ($this->fields === null) {
$this->fields = [];
@@ -704,7 +705,7 @@ abstract class BaseMigrateController extends Controller
foreach ($chunks as &$chunk) {
if (!preg_match('/(.+?)\(([^)]+)\)/', $chunk)) {
- $chunk = $chunk . '()';
+ $chunk .= '()';
}
}
$this->fields[$index] = ['property' => $property, 'decorators' => implode('->', $chunks)];
@@ -712,20 +713,17 @@ abstract class BaseMigrateController extends Controller
}
/**
- * Check fields option contain primaryKey, if fields do not contain primary key it is added
+ * Adds default primary key to fields list if there's no primary key specified
* @since 2.0.7
*/
- protected function checkPrimaryKey()
+ protected function addDefaultPrimaryKey()
{
- $exitsPk = false;
foreach ($this->fields as $field) {
if ($field['decorators'] === 'primaryKey()') {
- $exitsPk = true;
+ return;
}
}
- if (!$exitsPk) {
- array_unshift($this->fields, ['property' => 'id', 'decorators' => 'primaryKey()']);
- }
+ array_unshift($this->fields, ['property' => 'id', 'decorators' => 'primaryKey()']);
}
/**
diff --git a/framework/console/controllers/MigrateController.php b/framework/console/controllers/MigrateController.php
index 8e6f833..8359979 100644
--- a/framework/console/controllers/MigrateController.php
+++ b/framework/console/controllers/MigrateController.php
@@ -66,12 +66,12 @@ class MigrateController extends BaseMigrateController
/**
* @inheritdoc
*/
- public $generatorTemplateFile = [
+ public $generatorTemplateFiles = [
'create' => '@yii/views/createMigration.php',
'drop' => '@yii/views/dropMigration.php',
'add' => '@yii/views/addColumnMigration.php',
'remove' => '@yii/views/dropColumnMigration.php',
- 'create_join' => '@yii/views/createJoinMigration.php'
+ 'create_junction' => '@yii/views/createJunctionMigration.php'
];
/**
* @var Connection|array|string the DB connection object or the application component ID of the DB connection to use
diff --git a/framework/views/createJoinMigration.php b/framework/views/createJunctionMigration.php
similarity index 100%
rename from framework/views/createJoinMigration.php
rename to framework/views/createJunctionMigration.php
diff --git a/tests/framework/console/controllers/MigrateControllerTestTrait.php b/tests/framework/console/controllers/MigrateControllerTestTrait.php
index aa8dfaf..e2d4325 100644
--- a/tests/framework/console/controllers/MigrateControllerTestTrait.php
+++ b/tests/framework/console/controllers/MigrateControllerTestTrait.php
@@ -363,14 +363,14 @@ CODE;
public function testGenerateAddColumnMigration()
{
- $migrationName = 'add_columns_from_test';
+ $migrationName = 'add_columns_to_test';
$class = 'm' . gmdate('ymd_His') . '_' . $migrationName;
$this->runMigrateControllerAction('create', [
$migrationName,
'fields' => [
'title:string(10):notNull',
'body:text:notNull',
- 'create_at:dateTime'
+ 'created_at:dateTime'
]
]);
$files = FileHelper::findFiles($this->migrationPath);
@@ -386,14 +386,14 @@ class {$class} extends Migration
{
\$this->addColumn('test', 'title', \$this->string(10)->notNull());
\$this->addColumn('test', 'body', \$this->text()->notNull());
- \$this->addColumn('test', 'create_at', \$this->dateTime());
+ \$this->addColumn('test', 'created_at', \$this->dateTime());
}
public function down()
{
\$this->dropColumn('test', 'title');
\$this->dropColumn('test', 'body');
- \$this->dropColumn('test', 'create_at');
+ \$this->dropColumn('test', 'created_at');
}
}
@@ -410,7 +410,7 @@ CODE;
'fields' => [
'title:string(10):notNull',
'body:text:notNull',
- 'create_at:dateTime'
+ 'created_at:dateTime'
]
]);
$files = FileHelper::findFiles($this->migrationPath);
@@ -426,14 +426,14 @@ class {$class} extends Migration
{
\$this->dropColumn('test', 'title');
\$this->dropColumn('test', 'body');
- \$this->dropColumn('test', 'create_at');
+ \$this->dropColumn('test', 'created_at');
}
public function down()
{
\$this->addColumn('test', 'title', \$this->string(10)->notNull());
\$this->addColumn('test', 'body', \$this->text()->notNull());
- \$this->addColumn('test', 'create_at', \$this->dateTime());
+ \$this->addColumn('test', 'created_at', \$this->dateTime());
}
}
@@ -446,7 +446,7 @@ CODE;
'fields' => [
'title:string(10):notNull',
'body:text:notNull',
- 'create_at:dateTime'
+ 'created_at:dateTime'
]
]);
$files = FileHelper::findFiles($this->migrationPath);
@@ -462,14 +462,14 @@ class {$class} extends Migration
{
\$this->dropColumn('test', 'title');
\$this->dropColumn('test', 'body');
- \$this->dropColumn('test', 'create_at');
+ \$this->dropColumn('test', 'created_at');
}
public function down()
{
\$this->addColumn('test', 'title', \$this->string(10)->notNull());
\$this->addColumn('test', 'body', \$this->text()->notNull());
- \$this->addColumn('test', 'create_at', \$this->dateTime());
+ \$this->addColumn('test', 'created_at', \$this->dateTime());
}
}
@@ -477,9 +477,9 @@ CODE;
$this->assertEqualsWithoutLE($code, file_get_contents($files[0]));
}
- public function testGenerateCreateJoinMigration()
+ public function testGenerateCreateJunctionMigration()
{
- $migrationName = 'create_join_post_and_tag';
+ $migrationName = 'create_junction_post_and_tag';
$class = 'm' . gmdate('ymd_His') . '_' . $migrationName;
$this->runMigrateControllerAction('create', [
$migrationName,