Skip to content

Resolve Wrong migration for Pgsql is generated for string/varchar datatype #149 #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/lib/migrations/BaseMigrationBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -568,4 +568,12 @@ public function modifyDesiredFromDbInContextOfDesired(ColumnSchema $desired, Col
$desiredFromDb->dbType = 'timestamp';
}
}

public function modifyDesiredInContextOfDesiredFromDb(ColumnSchema $desired, ColumnSchema $desiredFromDb): void
{
if (property_exists($desired, 'xDbType') && is_string($desired->xDbType) && !empty($desired->xDbType)) {
return;
}
$desired->dbType = $desiredFromDb->dbType;
}
}
3 changes: 3 additions & 0 deletions src/lib/migrations/MysqlMigrationBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ protected function compareColumns(ColumnSchema $current, ColumnSchema $desired):

// Why this is needed? Often manually created ColumnSchem instance have dbType 'varchar' with size 255 and ColumnSchema fetched from db have 'varchar(255)'. So varchar !== varchar(255). such normal mistake was leading to errors. So desired column is saved in temporary table and it is fetched from that temp. table and then compared with current ColumnSchema
$desiredFromDb = $this->tmpSaveNewCol($tableAlias, $desired);

$this->modifyDesiredInContextOfDesiredFromDb($desired, $desiredFromDb);

$this->modifyDesired($desiredFromDb);
$this->modifyDesiredInContextOfCurrent($current, $desiredFromDb);
$this->modifyDesiredFromDbInContextOfDesired($desired, $desiredFromDb);
Expand Down
3 changes: 3 additions & 0 deletions src/lib/migrations/PostgresMigrationBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ protected function compareColumns(ColumnSchema $current, ColumnSchema $desired):

// for docs, please see MysqlMigrationBuilder file
$desiredFromDb = $this->tmpSaveNewCol($tableAlias, $desired);

$this->modifyDesiredInContextOfDesiredFromDb($desired, $desiredFromDb);

$this->modifyDesired($desiredFromDb);
$this->modifyDesiredInContextOfCurrent($current, $desiredFromDb);
$this->modifyDesiredFromDbInContextOfDesired($desired, $desiredFromDb);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public function safeUp()
$this->execute('CREATE TYPE "enum_itt_v2_posts_lang" AS ENUM(\'ru\', \'eng\')');
$this->addColumn('{{%v2_posts}}', 'lang', '"enum_itt_v2_posts_lang" NULL DEFAULT \'ru\'');
$this->dropColumn('{{%v2_posts}}', 'uid');
$this->alterColumn('{{%v2_posts}}', 'category_id', 'bigint NOT NULL USING "category_id"::bigint');
$this->alterColumn('{{%v2_posts}}', 'category_id', 'int8 NOT NULL USING "category_id"::int8');
$this->alterColumn('{{%v2_posts}}', 'active', "DROP DEFAULT");
$this->alterColumn('{{%v2_posts}}', 'created_by_id', 'bigint NULL USING "created_by_id"::bigint');
$this->alterColumn('{{%v2_posts}}', 'created_by_id', 'int8 NULL USING "created_by_id"::int8');
$this->dropIndex('v2_posts_slug_key', '{{%v2_posts}}');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class m200000_000003_change_table_v2_categories extends \yii\db\Migration
public function safeUp()
{
$this->addColumn('{{%v2_categories}}', 'cover', $this->text()->notNull());
$this->alterColumn('{{%v2_categories}}', 'title', 'string(100) NOT NULL USING "title"::string');
$this->alterColumn('{{%v2_categories}}', 'title', $this->string(100)->notNull());
$this->alterColumn('{{%v2_categories}}', 'active', "DROP DEFAULT");
$this->dropIndex('v2_categories_title_key', '{{%v2_categories}}');
$this->createIndex('v2_categories_title_index', '{{%v2_categories}}', 'title', false);
Expand All @@ -18,7 +18,7 @@ public function safeDown()
{
$this->dropIndex('v2_categories_title_index', '{{%v2_categories}}');
$this->createIndex('v2_categories_title_key', '{{%v2_categories}}', 'title', true);
$this->alterColumn('{{%v2_categories}}', 'title', 'varchar(255) NOT NULL USING "title"::varchar');
$this->alterColumn('{{%v2_categories}}', 'title', $this->string(255)->notNull());
$this->dropColumn('{{%v2_categories}}', 'cover');
$this->alterColumn('{{%v2_categories}}', 'active', "SET DEFAULT 'f'");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ public function safeUp()
$this->dropColumn('{{%v2_comments}}', 'author_id');
$this->alterColumn('{{%v2_comments}}', 'message', 'text NOT NULL USING "message"::text');
$this->alterColumn('{{%v2_comments}}', 'message', "DROP DEFAULT");
$this->alterColumn('{{%v2_comments}}', 'meta_data', 'string(300) NULL USING "meta_data"::string');
$this->alterColumn('{{%v2_comments}}', 'meta_data', 'varchar(300) NULL USING "meta_data"::varchar');
$this->alterColumn('{{%v2_comments}}', 'meta_data', "DROP NOT NULL");
$this->alterColumn('{{%v2_comments}}', 'meta_data', "SET DEFAULT ''");
$this->alterColumn('{{%v2_comments}}', 'created_at', 'datetime NOT NULL USING "created_at"::datetime');
$this->alterColumn('{{%v2_comments}}', 'created_at', 'timestamp NOT NULL USING "created_at"::timestamp');
$this->addForeignKey('fk_v2_comments_post_id_v2_posts_id', '{{%v2_comments}}', 'post_id', '{{%v2_posts}}', 'id');
$this->addForeignKey('fk_v2_comments_user_id_v2_users_id', '{{%v2_comments}}', 'user_id', '{{%v2_users}}', 'id');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/**
* Table for Fruit
*/
class m200000_000000_change_table_fruits extends \yii\db\Migration
{
public function safeUp()
{
$this->alterColumn('{{%fruits}}', 'name', $this->string(151)->notNull());
$this->alterColumn('{{%fruits}}', 'name', "SET NOT NULL");
}

public function safeDown()
{
$this->alterColumn('{{%fruits}}', 'name', $this->string(150)->null());
$this->alterColumn('{{%fruits}}', 'name', "DROP NOT NULL");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

return [
'openApiPath' => '@specs/issue_fix/wrong_migration_for_pgsql_is_generated_for_string_varchar_datatype_149/wrong_migration_for_pgsql_is_generated_for_string_varchar_datatype_149.yaml',
'generateUrls' => false,
'generateModels' => false,
'excludeModels' => [
'Error',
],
'generateControllers' => false,
'generateMigrations' => true,
'generateModelFaker' => false,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Fix https://github.com/cebe/yii2-openapi/issues/149 wrong_migration_for_pgsql_is_generated_for_string_varchar_datatype_149
paths:
/:
get:
summary: List
operationId: list
responses:
'200':
description: The information

components:
schemas:
Fruit:
type: object
description: A table to fix \#149
required:
- id
- name
properties:
id:
type: integer
name:
type: string
example: desc
maxLength: 151
36 changes: 36 additions & 0 deletions tests/unit/IssueFixTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ private function deleteTables()
$this->deleteTablesForNoSyntaxError107();
$this->deleteTableForQuoteInAlterColumn();
$this->deleteTableForTimestampIssue143();
$this->deleteTablesForWrongMigrationForPgsqlForStringVarcharDatatype149();
}

private function deleteTablesForFloatIssue()
Expand Down Expand Up @@ -221,4 +222,39 @@ public function testModelNameMoreThanOnceInFakerIssue148()
]);
$this->checkFiles($actualFiles, $expectedFiles);
}

// https://github.com/cebe/yii2-openapi/issues/149
// wrongMigrationForPgsqlForStringVarcharDatatype
// wrong_migration_for_pgsql_is_generated_for_string_varchar_datatype
public function testWrongMigrationForPgsqlForStringVarcharDatatype149()
{
$this->changeDbToPgsql();
$this->deleteTablesForWrongMigrationForPgsqlForStringVarcharDatatype149();
$this->createTableForWrongMigrationForPgsqlForStringVarcharDatatype149();
$testFile = Yii::getAlias("@specs/issue_fix/wrong_migration_for_pgsql_is_generated_for_string_varchar_datatype_149/wrong_migration_for_pgsql_is_generated_for_string_varchar_datatype_149.php");
$this->runGenerator($testFile, 'pgsql');
$actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [
'recursive' => true,
]);

$expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/wrong_migration_for_pgsql_is_generated_for_string_varchar_datatype_149/app"), [
'recursive' => true,
]);
$this->checkFiles($actualFiles, $expectedFiles);
$this->runActualMigrations('pgsql', 1);
$this->deleteTables();
}

private function createTableForWrongMigrationForPgsqlForStringVarcharDatatype149()
{
Yii::$app->db->createCommand()->createTable('{{%fruits}}', [
'id' => 'pk',
'name' => 'string(150)', # not null
])->execute();
}

private function deleteTablesForWrongMigrationForPgsqlForStringVarcharDatatype149()
{
Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%fruits}}')->execute();
}
}