Browse Source

#9465 better naming, code polish, changelog, docs wording

tags/3.0.0-alpha1
Alexander Makarov 9 years ago
parent
commit
76e8556d34
  1. 57
      docs/guide/db-migrations.md
  2. 1
      framework/CHANGELOG.md
  3. 64
      framework/console/controllers/BaseMigrateController.php
  4. 4
      framework/console/controllers/MigrateController.php
  5. 0
      framework/views/createJunctionMigration.php
  6. 24
      tests/framework/console/controllers/MigrateControllerTestTrait.php

57
docs/guide/db-migrations.md

@ -181,11 +181,14 @@ 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]]. 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 <span id="creating-migrations-with-generators"></span> ## Generating Migrations <span id="generating-migrations"></span>
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 ```php
yii migrate/create create_post yii migrate/create create_post
@ -210,7 +213,7 @@ 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 ```php
yii migrate/create create_post --fields=title:string,body:text yii migrate/create create_post --fields=title:string,body:text
@ -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 ```php
yii migrate/create create_post --fields=title:string(12):notNull:unique,body:text 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 > Note: primary key is added automatically and is named `id` by default. If you want to use another name you may
may specify in fields options, for example "--fields=name:primaryKey" > specify it explicitly like `--fields=name:primaryKey`.
Similarly, you can generate a migration to drop table from the command line: ### Drop Table
```php ```php
yii migrate/create drop_post 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 ```php
yii migrate/create add_position_from_post --fields=position:integer yii migrate/create add_position_to_post --fields=position:integer
``` ```
generates generates
```php ```php
class m150811_220037_add_position_from_post extends Migration class m150811_220037_add_position_to_post extends Migration
{ {
public function up() 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 ```php
yii migrate/create drop_position_from_post --fields=position:integer 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 ```php
yii create/migration create_join_post_and_tag yii create/migration create_junction_post_and_tag
``` ```
generates generates
```php ```php
class m150811_220037_create_join_post_and_tag extends Migration class m150811_220037_create_junction_post_and_tag extends Migration
{ {
public function up() public function up()
{ {
@ -370,7 +385,6 @@ class m150811_220037_create_join_post_and_tag extends Migration
} }
``` ```
### Transactional Migrations <span id="transactional-migrations"></span> ### Transactional Migrations <span id="transactional-migrations"></span>
While performing complex DB migrations, it is important to ensure each migration to either succeed or fail as a whole 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 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. named `$className` to get the migration class name.
* `generatorTemplateFile`: array (defaults to `[ * `generatorTemplateFiles`: array (defaults to `[
'create' => '@yii/views/createMigration.php', 'create' => '@yii/views/createMigration.php',
'drop' => '@yii/views/dropMigration.php', 'drop' => '@yii/views/dropMigration.php',
'add' => '@yii/views/addMigration.php', 'add' => '@yii/views/addMigration.php',
'remove' => '@yii/views/removeMigration.php', 'remove' => '@yii/views/removeMigration.php',
'create_join' => '@yii/views/createJoinMigration.php' 'create_junction' => '@yii/views/createJunctionMigration.php'
]`), specifies template files for generating migration code automatically. See [Creating Migrations with Generators](#creating-migrations-with-generators) ]`), specifies template files for generating migration code. See "[Generating Migrations](#generating-migrations)"
for more details. 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 * `fields`: array of column definition strings used for creating migration code. Defaults to `[]`. The format of each
`COLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR`, for example `--fields=name:string(12):notNull`, it specify string column with 12 size and not null. 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. The following example shows how you can use these options.

1
framework/CHANGELOG.md

@ -48,6 +48,7 @@ Yii Framework 2 Change Log
- Enh #8649: Added total applied migrations to final report (vernik91) - 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 #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 #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 #9476: Added DI injection via controller action method signature (mdmunir)
- Enh #9635: Added default CSS class for `\yii\grid\ActionColumn` header (arogachev, dynasource) - Enh #9635: Added default CSS class for `\yii\grid\ActionColumn` header (arogachev, dynasource)
- Enh #9643: Added migrations for DB cache (mdmunir) - Enh #9643: Added migrations for DB cache (mdmunir)

64
framework/console/controllers/BaseMigrateController.php

@ -42,12 +42,12 @@ abstract class BaseMigrateController extends Controller
*/ */
public $templateFile; public $templateFile;
/** /**
* @var array the template file for generating migration code automatically. * @var array a set of template files for generating migration code automatically.
* This can be either a path alias (e.g. "@app/migrations/template.php") * Each one can be either a path alias (e.g. "@app/migrations/template.php")
* or a file path. * or a file path.
* @since 2.0.7 * @since 2.0.7
*/ */
public $generatorTemplateFile; public $generatorTemplateFiles;
/** /**
* @var array Fields to be generated * @var array Fields to be generated
* @since 2.0.7 * @since 2.0.7
@ -63,9 +63,7 @@ abstract class BaseMigrateController extends Controller
return array_merge( return array_merge(
parent::options($actionID), parent::options($actionID),
['migrationPath'], // global for all actions ['migrationPath'], // global for all actions
($actionID === 'create') $actionID === 'create' ? ['templateFile', 'templateFileGenerators', 'fields'] : [] // action create
? ['templateFile', 'templateFileGenerators', 'fields']
: [] // action create
); );
} }
@ -87,7 +85,7 @@ abstract class BaseMigrateController extends Controller
FileHelper::createDirectory($path); FileHelper::createDirectory($path);
} }
$this->migrationPath = $path; $this->migrationPath = $path;
$this->parseField(); $this->parseFields();
$version = Yii::getVersion(); $version = Yii::getVersion();
$this->stdout("Yii Migration Tool (based on Yii v{$version})\n\n"); $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'; $file = $this->migrationPath . DIRECTORY_SEPARATOR . $className . '.php';
if ($this->confirm("Create new migration '$file'?")) { if ($this->confirm("Create new migration '$file'?")) {
if (preg_match('/^create_join_(.+)_and_(.+)$/', $name, $matches)) { if (preg_match('/^create_junction_(.+)_and_(.+)$/', $name, $matches)) {
$content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['create_join']), [ $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, 'className' => $className,
'table' => mb_strtolower($matches[1]) . '_' . mb_strtolower($matches[2]), 'table' => $firstTable . '_' . $secondTable,
'field_first' => mb_strtolower($matches[1]), 'field_first' => $firstTable,
'field_second' => mb_strtolower($matches[2]), 'field_second' => $secondTable,
]); ]);
} elseif (preg_match('/^add_(.+)from_(.+)$/', $name, $matches)) { } elseif (preg_match('/^add_(.+)_to_(.+)$/', $name, $matches)) {
$content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['add']), [ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['add']), [
'className' => $className, 'className' => $className,
'table' => mb_strtolower($matches[2]), 'table' => mb_strtolower($matches[2], Yii::$app->charset),
'fields' => $this->fields 'fields' => $this->fields
]); ]);
} elseif (preg_match('/^drop_(.+)from_(.+)$/', $name, $matches)) { } elseif (preg_match('/^drop_(.+)_from_(.+)$/', $name, $matches)) {
$content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['remove']), [ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['remove']), [
'className' => $className, 'className' => $className,
'table' => mb_strtolower($matches[2]), 'table' => mb_strtolower($matches[2], Yii::$app->charset),
'fields' => $this->fields 'fields' => $this->fields
]); ]);
} elseif (preg_match('/^create_(.+)$/', $name, $matches)) { } elseif (preg_match('/^create_(.+)$/', $name, $matches)) {
$this->checkPrimaryKey(); $this->addDefaultPrimaryKey();
$content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['create']), [ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['create']), [
'className' => $className, 'className' => $className,
'table' => mb_strtolower($matches[1]), 'table' => mb_strtolower($matches[1], Yii::$app->charset),
'fields' => $this->fields 'fields' => $this->fields
]); ]);
} elseif (preg_match('/^drop_(.+)$/', $name, $matches)) { } elseif (preg_match('/^drop_(.+)$/', $name, $matches)) {
$content = $this->renderFile(Yii::getAlias($this->generatorTemplateFile['drop']), [ $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['drop']), [
'className' => $className, 'className' => $className,
'table' => mb_strtolower($matches[1]), 'table' => mb_strtolower($matches[1], Yii::$app->charset),
'fields' => $this->fields 'fields' => $this->fields
]); ]);
} else { } 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 * @since 2.0.7
*/ */
protected function parseField() protected function parseFields()
{ {
if ($this->fields === null) { if ($this->fields === null) {
$this->fields = []; $this->fields = [];
@ -704,7 +705,7 @@ abstract class BaseMigrateController extends Controller
foreach ($chunks as &$chunk) { foreach ($chunks as &$chunk) {
if (!preg_match('/(.+?)\(([^)]+)\)/', $chunk)) { if (!preg_match('/(.+?)\(([^)]+)\)/', $chunk)) {
$chunk = $chunk . '()'; $chunk .= '()';
} }
} }
$this->fields[$index] = ['property' => $property, 'decorators' => implode('->', $chunks)]; $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 * @since 2.0.7
*/ */
protected function checkPrimaryKey() protected function addDefaultPrimaryKey()
{ {
$exitsPk = false;
foreach ($this->fields as $field) { foreach ($this->fields as $field) {
if ($field['decorators'] === 'primaryKey()') { 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()']);
}
} }
/** /**

4
framework/console/controllers/MigrateController.php

@ -66,12 +66,12 @@ class MigrateController extends BaseMigrateController
/** /**
* @inheritdoc * @inheritdoc
*/ */
public $generatorTemplateFile = [ public $generatorTemplateFiles = [
'create' => '@yii/views/createMigration.php', 'create' => '@yii/views/createMigration.php',
'drop' => '@yii/views/dropMigration.php', 'drop' => '@yii/views/dropMigration.php',
'add' => '@yii/views/addColumnMigration.php', 'add' => '@yii/views/addColumnMigration.php',
'remove' => '@yii/views/dropColumnMigration.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 * @var Connection|array|string the DB connection object or the application component ID of the DB connection to use

0
framework/views/createJoinMigration.php → framework/views/createJunctionMigration.php

24
tests/framework/console/controllers/MigrateControllerTestTrait.php

@ -363,14 +363,14 @@ CODE;
public function testGenerateAddColumnMigration() public function testGenerateAddColumnMigration()
{ {
$migrationName = 'add_columns_from_test'; $migrationName = 'add_columns_to_test';
$class = 'm' . gmdate('ymd_His') . '_' . $migrationName; $class = 'm' . gmdate('ymd_His') . '_' . $migrationName;
$this->runMigrateControllerAction('create', [ $this->runMigrateControllerAction('create', [
$migrationName, $migrationName,
'fields' => [ 'fields' => [
'title:string(10):notNull', 'title:string(10):notNull',
'body:text:notNull', 'body:text:notNull',
'create_at:dateTime' 'created_at:dateTime'
] ]
]); ]);
$files = FileHelper::findFiles($this->migrationPath); $files = FileHelper::findFiles($this->migrationPath);
@ -386,14 +386,14 @@ class {$class} extends Migration
{ {
\$this->addColumn('test', 'title', \$this->string(10)->notNull()); \$this->addColumn('test', 'title', \$this->string(10)->notNull());
\$this->addColumn('test', 'body', \$this->text()->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() public function down()
{ {
\$this->dropColumn('test', 'title'); \$this->dropColumn('test', 'title');
\$this->dropColumn('test', 'body'); \$this->dropColumn('test', 'body');
\$this->dropColumn('test', 'create_at'); \$this->dropColumn('test', 'created_at');
} }
} }
@ -410,7 +410,7 @@ CODE;
'fields' => [ 'fields' => [
'title:string(10):notNull', 'title:string(10):notNull',
'body:text:notNull', 'body:text:notNull',
'create_at:dateTime' 'created_at:dateTime'
] ]
]); ]);
$files = FileHelper::findFiles($this->migrationPath); $files = FileHelper::findFiles($this->migrationPath);
@ -426,14 +426,14 @@ class {$class} extends Migration
{ {
\$this->dropColumn('test', 'title'); \$this->dropColumn('test', 'title');
\$this->dropColumn('test', 'body'); \$this->dropColumn('test', 'body');
\$this->dropColumn('test', 'create_at'); \$this->dropColumn('test', 'created_at');
} }
public function down() public function down()
{ {
\$this->addColumn('test', 'title', \$this->string(10)->notNull()); \$this->addColumn('test', 'title', \$this->string(10)->notNull());
\$this->addColumn('test', 'body', \$this->text()->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' => [ 'fields' => [
'title:string(10):notNull', 'title:string(10):notNull',
'body:text:notNull', 'body:text:notNull',
'create_at:dateTime' 'created_at:dateTime'
] ]
]); ]);
$files = FileHelper::findFiles($this->migrationPath); $files = FileHelper::findFiles($this->migrationPath);
@ -462,14 +462,14 @@ class {$class} extends Migration
{ {
\$this->dropColumn('test', 'title'); \$this->dropColumn('test', 'title');
\$this->dropColumn('test', 'body'); \$this->dropColumn('test', 'body');
\$this->dropColumn('test', 'create_at'); \$this->dropColumn('test', 'created_at');
} }
public function down() public function down()
{ {
\$this->addColumn('test', 'title', \$this->string(10)->notNull()); \$this->addColumn('test', 'title', \$this->string(10)->notNull());
\$this->addColumn('test', 'body', \$this->text()->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])); $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; $class = 'm' . gmdate('ymd_His') . '_' . $migrationName;
$this->runMigrateControllerAction('create', [ $this->runMigrateControllerAction('create', [
$migrationName, $migrationName,

Loading…
Cancel
Save