From 54483a27ca494e72b7e239a20e1281e24c07ddde Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Thu, 2 May 2024 16:46:30 +0200 Subject: [PATCH 01/12] Failing test case for #168, can not define index for a relation key --- ...m200000_000000_create_table_deliveries.php | 20 +++ .../m200000_000001_create_table_users.php | 20 +++ .../m200000_000002_create_table_webhooks.php | 29 ++++ .../app/models/BaseModelFaker.php | 144 ++++++++++++++++++ .../fk_col_name_index/app/models/Delivery.php | 10 ++ .../app/models/DeliveryFaker.php | 41 +++++ .../fk_col_name_index/app/models/User.php | 10 ++ .../app/models/UserFaker.php | 41 +++++ .../fk_col_name_index/app/models/Webhook.php | 10 ++ .../app/models/WebhookFaker.php | 53 +++++++ .../app/models/base/Delivery.php | 26 ++++ .../app/models/base/User.php | 27 ++++ .../app/models/base/Webhook.php | 44 ++++++ .../fk_col_name_index/fk_col_name_index.php | 13 ++ .../fk_col_name_index/fk_col_name_index.yaml | 54 +++++++ tests/unit/ForeignKeyColumnNameTest.php | 16 ++ 16 files changed, 558 insertions(+) create mode 100644 tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000000_create_table_deliveries.php create mode 100644 tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000001_create_table_users.php create mode 100644 tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php create mode 100644 tests/specs/fk_col_name_index/app/models/BaseModelFaker.php create mode 100644 tests/specs/fk_col_name_index/app/models/Delivery.php create mode 100644 tests/specs/fk_col_name_index/app/models/DeliveryFaker.php create mode 100644 tests/specs/fk_col_name_index/app/models/User.php create mode 100644 tests/specs/fk_col_name_index/app/models/UserFaker.php create mode 100644 tests/specs/fk_col_name_index/app/models/Webhook.php create mode 100644 tests/specs/fk_col_name_index/app/models/WebhookFaker.php create mode 100644 tests/specs/fk_col_name_index/app/models/base/Delivery.php create mode 100644 tests/specs/fk_col_name_index/app/models/base/User.php create mode 100644 tests/specs/fk_col_name_index/app/models/base/Webhook.php create mode 100644 tests/specs/fk_col_name_index/fk_col_name_index.php create mode 100644 tests/specs/fk_col_name_index/fk_col_name_index.yaml diff --git a/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000000_create_table_deliveries.php b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000000_create_table_deliveries.php new file mode 100644 index 00000000..e88d0ea9 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000000_create_table_deliveries.php @@ -0,0 +1,20 @@ +createTable('{{%deliveries}}', [ + 'id' => $this->primaryKey(), + 'title' => $this->text()->null(), + ]); + } + + public function down() + { + $this->dropTable('{{%deliveries}}'); + } +} diff --git a/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000001_create_table_users.php b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000001_create_table_users.php new file mode 100644 index 00000000..e6e9afe4 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000001_create_table_users.php @@ -0,0 +1,20 @@ +createTable('{{%users}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->text()->notNull(), + ]); + } + + public function down() + { + $this->dropTable('{{%users}}'); + } +} diff --git a/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php new file mode 100644 index 00000000..cf3b0845 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php @@ -0,0 +1,29 @@ +createTable('{{%webhooks}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->text()->null(), + 'user_id' => $this->integer()->null()->defaultValue(null), + 'redelivery_of' => $this->integer()->null()->defaultValue(null), + ]); + $this->addForeignKey('fk_webhooks_user_id_users_id', '{{%webhooks}}', 'user_id', '{{%users}}', 'id'); + $this->addForeignKey('fk_webhooks_redelivery_of_deliveries_id', '{{%webhooks}}', 'redelivery_of', '{{%deliveries}}', 'id'); + // TOOD add index names + $this->createIndex('...', '{{%webhooks}}', ['user_id', 'name'], true); + $this->createIndex('...', '{{%webhooks}}', ['redelivery_of', 'name'], true); + } + + public function down() + { + $this->dropForeignKey('fk_webhooks_redelivery_of_deliveries_id', '{{%webhooks}}'); + $this->dropForeignKey('fk_webhooks_user_id_users_id', '{{%webhooks}}'); + $this->dropTable('{{%webhooks}}'); + } +} diff --git a/tests/specs/fk_col_name_index/app/models/BaseModelFaker.php b/tests/specs/fk_col_name_index/app/models/BaseModelFaker.php new file mode 100644 index 00000000..c367fbb4 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/models/BaseModelFaker.php @@ -0,0 +1,144 @@ +faker = FakerFactory::create(str_replace('-', '_', \Yii::$app->language)); + $this->uniqueFaker = new UniqueGenerator($this->faker); + } + + abstract public function generateModel($attributes = []); + + public function getFaker():Generator + { + return $this->faker; + } + + public function getUniqueFaker():UniqueGenerator + { + return $this->uniqueFaker; + } + + public function setFaker(Generator $faker):void + { + $this->faker = $faker; + } + + public function setUniqueFaker(UniqueGenerator $faker):void + { + $this->uniqueFaker = $faker; + } + + /** + * Generate and return model + * @param array|callable $attributes + * @param UniqueGenerator|null $uniqueFaker + * @return \yii\db\ActiveRecord + * @example MyFaker::makeOne(['user_id' => 1, 'title' => 'foo']); + * @example MyFaker::makeOne( function($model, $faker) { + * $model->scenario = 'create'; + * $model->setAttributes(['user_id' => 1, 'title' => $faker->sentence]); + * return $model; + * }); + */ + public static function makeOne($attributes = [], ?UniqueGenerator $uniqueFaker = null) + { + $fakeBuilder = new static(); + if ($uniqueFaker !== null) { + $fakeBuilder->setUniqueFaker($uniqueFaker); + } + $model = $fakeBuilder->generateModel($attributes); + return $model; + } + + /** + * Generate, save and return model + * @param array|callable $attributes + * @param UniqueGenerator|null $uniqueFaker + * @return \yii\db\ActiveRecord + * @example MyFaker::saveOne(['user_id' => 1, 'title' => 'foo']); + * @example MyFaker::saveOne( function($model, $faker) { + * $model->scenario = 'create'; + * $model->setAttributes(['user_id' => 1, 'title' => $faker->sentence]); + * return $model; + * }); + */ + public static function saveOne($attributes = [], ?UniqueGenerator $uniqueFaker = null) + { + $model = static::makeOne($attributes, $uniqueFaker); + $model->save(); + return $model; + } + + /** + * Generate and return multiple models + * @param int $number + * @param array|callable $commonAttributes + * @return \yii\db\ActiveRecord[]|array + * @example TaskFaker::make(5, ['project_id'=>1, 'user_id' => 2]); + * @example TaskFaker::make(5, function($model, $faker, $uniqueFaker) { + * $model->setAttributes(['name' => $uniqueFaker->username, 'state'=>$faker->boolean(20)]); + * return $model; + * }); + */ + public static function make(int $number, $commonAttributes = [], ?UniqueGenerator $uniqueFaker = null):array + { + if ($number < 1) { + return []; + } + $fakeBuilder = new static(); + if ($uniqueFaker !== null) { + $fakeBuilder->setUniqueFaker($uniqueFaker); + } + return array_map(function () use ($commonAttributes, $fakeBuilder) { + $model = $fakeBuilder->generateModel($commonAttributes); + return $model; + }, range(0, $number -1)); + } + + /** + * Generate, save and return multiple models + * @param int $number + * @param array|callable $commonAttributes + * @return \yii\db\ActiveRecord[]|array + * @example TaskFaker::save(5, ['project_id'=>1, 'user_id' => 2]); + * @example TaskFaker::save(5, function($model, $faker, $uniqueFaker) { + * $model->setAttributes(['name' => $uniqueFaker->username, 'state'=>$faker->boolean(20)]); + * return $model; + * }); + */ + public static function save(int $number, $commonAttributes = [], ?UniqueGenerator $uniqueFaker = null):array + { + if ($number < 1) { + return []; + } + $fakeBuilder = new static(); + if ($uniqueFaker !== null) { + $fakeBuilder->setUniqueFaker($uniqueFaker); + } + return array_map(function () use ($commonAttributes, $fakeBuilder) { + $model = $fakeBuilder->generateModel($commonAttributes); + $model->save(); + return $model; + }, range(0, $number -1)); + } +} diff --git a/tests/specs/fk_col_name_index/app/models/Delivery.php b/tests/specs/fk_col_name_index/app/models/Delivery.php new file mode 100644 index 00000000..1249e2b3 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/models/Delivery.php @@ -0,0 +1,10 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new Delivery(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->title = $faker->sentence; + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } +} diff --git a/tests/specs/fk_col_name_index/app/models/User.php b/tests/specs/fk_col_name_index/app/models/User.php new file mode 100644 index 00000000..9b837d6e --- /dev/null +++ b/tests/specs/fk_col_name_index/app/models/User.php @@ -0,0 +1,10 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new User(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->sentence; + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } +} diff --git a/tests/specs/fk_col_name_index/app/models/Webhook.php b/tests/specs/fk_col_name_index/app/models/Webhook.php new file mode 100644 index 00000000..e02ca284 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/models/Webhook.php @@ -0,0 +1,10 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new Webhook(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->sentence; + $model->user_id = $faker->randomElement(\app\models\User::find()->select("id")->column()); + $model->redelivery_of = $faker->numberBetween(0, 1000000); + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } + + public static function dependentOn() + { + return [ + // just model class names + 'User', + 'Delivery', + + ]; + } +} diff --git a/tests/specs/fk_col_name_index/app/models/base/Delivery.php b/tests/specs/fk_col_name_index/app/models/base/Delivery.php new file mode 100644 index 00000000..ae7cbd83 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/models/base/Delivery.php @@ -0,0 +1,26 @@ + [['title'], 'trim'], + 'title_string' => [['title'], 'string'], + ]; + } +} diff --git a/tests/specs/fk_col_name_index/app/models/base/User.php b/tests/specs/fk_col_name_index/app/models/base/User.php new file mode 100644 index 00000000..d76c3f4d --- /dev/null +++ b/tests/specs/fk_col_name_index/app/models/base/User.php @@ -0,0 +1,27 @@ + [['name'], 'trim'], + 'required' => [['name'], 'required'], + 'name_string' => [['name'], 'string'], + ]; + } +} diff --git a/tests/specs/fk_col_name_index/app/models/base/Webhook.php b/tests/specs/fk_col_name_index/app/models/base/Webhook.php new file mode 100644 index 00000000..8746e8f0 --- /dev/null +++ b/tests/specs/fk_col_name_index/app/models/base/Webhook.php @@ -0,0 +1,44 @@ + [['name'], 'trim'], + 'user_id_integer' => [['user_id'], 'integer'], + 'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'User'], + 'redelivery_of_integer' => [['redelivery_of'], 'integer'], + 'redelivery_of_exist' => [['redelivery_of'], 'exist', 'targetRelation' => 'RedeliveryOf'], + 'name_string' => [['name'], 'string'], + ]; + } + + public function getUser() + { + return $this->hasOne(\app\models\User::class, ['id' => 'user_id']); + } + + public function getRedeliveryOf() + { + return $this->hasOne(\app\models\Delivery::class, ['id' => 'redelivery_of']); + } +} diff --git a/tests/specs/fk_col_name_index/fk_col_name_index.php b/tests/specs/fk_col_name_index/fk_col_name_index.php new file mode 100644 index 00000000..e952e245 --- /dev/null +++ b/tests/specs/fk_col_name_index/fk_col_name_index.php @@ -0,0 +1,13 @@ + '@specs/fk_col_name_index/fk_col_name_index.yaml', + 'generateUrls' => false, + 'generateModels' => true, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => false, + 'generateMigrations' => true, + 'generateModelFaker' => true, +]; diff --git a/tests/specs/fk_col_name_index/fk_col_name_index.yaml b/tests/specs/fk_col_name_index/fk_col_name_index.yaml new file mode 100644 index 00000000..fb4976ce --- /dev/null +++ b/tests/specs/fk_col_name_index/fk_col_name_index.yaml @@ -0,0 +1,54 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: ID not in rules test +paths: + /: + get: + summary: List + operationId: list + responses: + '200': + description: The information + +components: + schemas: + User: + type: object + description: Test model for model code generation that should not contain id column in rules + required: + - id + - name + properties: + id: + type: integer + name: + type: string + Delivery: + x-table: deliveries + required: + - id + properties: + id: + type: integer + title: + type: string + Webhook: + x-indexes: + - 'unique:user_id,name' + - 'unique:redelivery_of,name' + type: object + description: example for x-fk-column-name + properties: + id: + type: integer + name: + type: string + user: + $ref: '#/components/schemas/User' # this will automatically create `user_id` column + redelivery_of: + allOf: + - $ref: '#/components/schemas/Delivery' + # this will automatically create `redelivery_of_id` column, but to avoid that use below extension + - x-fk-column-name: redelivery_of # this will create `redelivery_of` column instead of `redelivery_of_id` + diff --git a/tests/unit/ForeignKeyColumnNameTest.php b/tests/unit/ForeignKeyColumnNameTest.php index 24401ea5..119bfdf8 100644 --- a/tests/unit/ForeignKeyColumnNameTest.php +++ b/tests/unit/ForeignKeyColumnNameTest.php @@ -30,4 +30,20 @@ public function testIndex() $this->checkFiles($actualFiles, $expectedFiles); $this->runActualMigrations('mysql', 3); } + + public function testIndexForColumnWithCustomName() + { + // default DB is Mysql ---------------------------------- + + $testFile = Yii::getAlias("@specs/fk_col_name_index/fk_col_name_index.php"); + $this->runGenerator($testFile, 'mysql'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/fk_col_name_index/app"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); + $this->runActualMigrations('mysql', 3); + } } From aa90a669d1a0943d8b1945d78994a8eac7afd7a5 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 16:06:26 +0530 Subject: [PATCH 02/12] Initial commit of this PR --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index df87e47a..86e77ce8 100644 --- a/README.md +++ b/README.md @@ -564,3 +564,4 @@ Professional support, consulting as well as software development services are av https://www.cebe.cc/en/contact Development of this library is sponsored by [cebe.:cloud: "Your Professional Deployment Platform"](https://cebe.cloud). + From 7d723c4fb1ba2265cec9cd4098c93c1c6eaae42c Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 18:45:13 +0530 Subject: [PATCH 03/12] Docs changes --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 86e77ce8..020f478c 100644 --- a/README.md +++ b/README.md @@ -285,7 +285,7 @@ Allow to set foreign key constraint in migrations for ON UPDATE event of row in ### `x-fk-column-name` -Provide custom column name in case of relationship column. Example: +Provide custom database table column name in case of relationship column. This will not reflect in models, faker etc. Example: ```yaml components: @@ -564,4 +564,3 @@ Professional support, consulting as well as software development services are av https://www.cebe.cc/en/contact Development of this library is sponsored by [cebe.:cloud: "Your Professional Deployment Platform"](https://cebe.cloud). - From 701f374c48b38d1bcaff684304301d4d253a99cd Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 18:45:29 +0530 Subject: [PATCH 04/12] Implement issue --- src/lib/AttributeResolver.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lib/AttributeResolver.php b/src/lib/AttributeResolver.php index 4007389c..3d987df8 100644 --- a/src/lib/AttributeResolver.php +++ b/src/lib/AttributeResolver.php @@ -436,10 +436,25 @@ protected function prepareIndexes(array $indexes):array } $props = array_map('trim', explode(',', trim($props))); $columns = []; + $xFkColumnNames = []; + foreach ($this->attributes as $key => $value) { + if (!empty($value->fkColName)) { + $xFkColumnNames[$value->fkColName] = $key; + } + } foreach ($props as $prop) { if (!isset($this->attributes[$prop])) { - throw new InvalidDefinitionException('Invalid index definition - property ' . $prop - . ' not declared'); + if (!in_array($prop, array_keys($xFkColumnNames))) { + $refPropName = (substr($prop, -3) === '_id') ? rtrim($prop, '_id') : null; + if ($refPropName && !isset($this->attributes[$refPropName])) { + throw new InvalidDefinitionException('Invalid index definition - property ' . $prop + . ' not declared'); + } else { + $prop = $refPropName; + } + } else { + $prop = $xFkColumnNames[$prop]; + } } $columns[] = $this->attributes[$prop]->columnName; } From db8eb255d7baf6fc7fda5cc6c964fbefb4c11ef8 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 18:45:58 +0530 Subject: [PATCH 05/12] More test cases --- tests/specs/fk_col_name_index/fk_col_name_index.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/specs/fk_col_name_index/fk_col_name_index.yaml b/tests/specs/fk_col_name_index/fk_col_name_index.yaml index fb4976ce..4ea88661 100644 --- a/tests/specs/fk_col_name_index/fk_col_name_index.yaml +++ b/tests/specs/fk_col_name_index/fk_col_name_index.yaml @@ -37,6 +37,8 @@ components: x-indexes: - 'unique:user_id,name' - 'unique:redelivery_of,name' + # - 'unique:rd2,name' + - 'unique:rd_abc_2,name' type: object description: example for x-fk-column-name properties: @@ -51,4 +53,8 @@ components: - $ref: '#/components/schemas/Delivery' # this will automatically create `redelivery_of_id` column, but to avoid that use below extension - x-fk-column-name: redelivery_of # this will create `redelivery_of` column instead of `redelivery_of_id` + rd2: + allOf: + - $ref: '#/components/schemas/Delivery' + - x-fk-column-name: rd_abc_2 From 81279ae5ec78c408078ef3dfb8d4c1caa7ab46a2 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 19:09:54 +0530 Subject: [PATCH 06/12] Use array instead of string in multiple values --- README.md | 2 +- src/lib/FakerStubResolver.php | 2 +- src/lib/migrations/MigrationRecordBuilder.php | 12 ++++++++---- .../migrations/m200000_000001_create_table_users.php | 2 +- .../m200000_000001_create_table_users.php | 2 +- .../m200000_000001_create_table_users.php | 2 +- .../m200000_000001_create_table_users.php | 2 +- .../m200000_000004_change_table_v2_users.php | 2 +- .../m200000_000004_change_table_v2_users.php | 2 +- .../m200000_000004_change_table_v2_users.php | 2 +- 10 files changed, 17 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 020f478c..b04e500f 100644 --- a/README.md +++ b/README.md @@ -285,7 +285,7 @@ Allow to set foreign key constraint in migrations for ON UPDATE event of row in ### `x-fk-column-name` -Provide custom database table column name in case of relationship column. This will not reflect in models, faker etc. Example: +Provide custom database table column name in case of relationship column. This will not reflect in models relations, faker etc. Example: ```yaml components: diff --git a/src/lib/FakerStubResolver.php b/src/lib/FakerStubResolver.php index b239ff8b..bd11bc2a 100644 --- a/src/lib/FakerStubResolver.php +++ b/src/lib/FakerStubResolver.php @@ -62,7 +62,7 @@ public function resolve():?string } // column name ends with `_id` - if (substr($this->attribute->columnName, -strlen('_id'))==='_id') { + if (substr($this->attribute->columnName, -3) === '_id' || !empty($this->attribute->fkColName)) { $config = $this->config; if (!$config) { $config = new Config; diff --git a/src/lib/migrations/MigrationRecordBuilder.php b/src/lib/migrations/MigrationRecordBuilder.php index 89db1fb9..b3048541 100644 --- a/src/lib/migrations/MigrationRecordBuilder.php +++ b/src/lib/migrations/MigrationRecordBuilder.php @@ -24,8 +24,8 @@ final class MigrationRecordBuilder public const DROP_FK = MigrationRecordBuilder::INDENT . "\$this->dropForeignKey('%s', '%s');"; public const DROP_PK = MigrationRecordBuilder::INDENT . "\$this->dropPrimaryKey('%s', '%s');"; public const ADD_TABLE = MigrationRecordBuilder::INDENT . "\$this->createTable('%s', %s);"; - public const ADD_UNIQUE = MigrationRecordBuilder::INDENT . "\$this->createIndex('%s', '%s', '%s', true);"; - public const ADD_INDEX = MigrationRecordBuilder::INDENT . "\$this->createIndex('%s', '%s', '%s', %s);"; + public const ADD_UNIQUE = MigrationRecordBuilder::INDENT . "\$this->createIndex('%s', '%s', %s, true);"; + public const ADD_INDEX = MigrationRecordBuilder::INDENT . "\$this->createIndex('%s', '%s', %s, %s);"; public const DROP_COLUMN = MigrationRecordBuilder::INDENT . "\$this->dropColumn('%s', '%s');"; public const ADD_ENUM = MigrationRecordBuilder::INDENT . "\$this->execute('CREATE TYPE \"enum_%s_%s\" AS ENUM(%s)');"; public const DROP_ENUM = MigrationRecordBuilder::INDENT . "\$this->execute('DROP TYPE \"enum_%s_%s\"');"; @@ -231,13 +231,17 @@ public function addFk(string $fkName, string $tableAlias, string $fkCol, string public function addUniqueIndex(string $tableAlias, string $indexName, array $columns):string { - return sprintf(self::ADD_UNIQUE, $indexName, $tableAlias, implode(',', $columns)); + return sprintf(self::ADD_UNIQUE, $indexName, $tableAlias, + count($columns) === 1 ? "'{$columns[0]}'" : '["'.implode('", "', $columns).'"]' + ); } public function addIndex(string $tableAlias, string $indexName, array $columns, ?string $using = null):string { $indexType = $using === null ? 'false' : "'".ColumnToCode::escapeQuotes($using)."'"; - return sprintf(self::ADD_INDEX, $indexName, $tableAlias, implode(',', $columns), $indexType); + return sprintf(self::ADD_INDEX, $indexName, $tableAlias, + count($columns) === 1 ? "'{$columns[0]}'" : '["'.implode('", "', $columns).'"]', + $indexType); } public function addPrimaryKey(string $tableAlias, array $columns, string $pkName= null):string diff --git a/tests/specs/blog/migrations/m200000_000001_create_table_users.php b/tests/specs/blog/migrations/m200000_000001_create_table_users.php index 69e23f8e..22583a78 100644 --- a/tests/specs/blog/migrations/m200000_000001_create_table_users.php +++ b/tests/specs/blog/migrations/m200000_000001_create_table_users.php @@ -18,7 +18,7 @@ public function up() ]); $this->createIndex('users_username_key', '{{%users}}', 'username', true); $this->createIndex('users_email_key', '{{%users}}', 'email', true); - $this->createIndex('users_role_flags_index', '{{%users}}', 'role,flags', false); + $this->createIndex('users_role_flags_index', '{{%users}}', ["role", "flags"], false); } public function down() diff --git a/tests/specs/blog/migrations_maria_db/m200000_000001_create_table_users.php b/tests/specs/blog/migrations_maria_db/m200000_000001_create_table_users.php index 69e23f8e..22583a78 100644 --- a/tests/specs/blog/migrations_maria_db/m200000_000001_create_table_users.php +++ b/tests/specs/blog/migrations_maria_db/m200000_000001_create_table_users.php @@ -18,7 +18,7 @@ public function up() ]); $this->createIndex('users_username_key', '{{%users}}', 'username', true); $this->createIndex('users_email_key', '{{%users}}', 'email', true); - $this->createIndex('users_role_flags_index', '{{%users}}', 'role,flags', false); + $this->createIndex('users_role_flags_index', '{{%users}}', ["role", "flags"], false); } public function down() diff --git a/tests/specs/blog/migrations_mysql_db/m200000_000001_create_table_users.php b/tests/specs/blog/migrations_mysql_db/m200000_000001_create_table_users.php index 69e23f8e..22583a78 100644 --- a/tests/specs/blog/migrations_mysql_db/m200000_000001_create_table_users.php +++ b/tests/specs/blog/migrations_mysql_db/m200000_000001_create_table_users.php @@ -18,7 +18,7 @@ public function up() ]); $this->createIndex('users_username_key', '{{%users}}', 'username', true); $this->createIndex('users_email_key', '{{%users}}', 'email', true); - $this->createIndex('users_role_flags_index', '{{%users}}', 'role,flags', false); + $this->createIndex('users_role_flags_index', '{{%users}}', ["role", "flags"], false); } public function down() diff --git a/tests/specs/blog/migrations_pgsql_db/m200000_000001_create_table_users.php b/tests/specs/blog/migrations_pgsql_db/m200000_000001_create_table_users.php index 00fd8c91..b845e46e 100644 --- a/tests/specs/blog/migrations_pgsql_db/m200000_000001_create_table_users.php +++ b/tests/specs/blog/migrations_pgsql_db/m200000_000001_create_table_users.php @@ -18,7 +18,7 @@ public function safeUp() ]); $this->createIndex('users_username_key', '{{%users}}', 'username', true); $this->createIndex('users_email_key', '{{%users}}', 'email', true); - $this->createIndex('users_role_flags_index', '{{%users}}', 'role,flags', false); + $this->createIndex('users_role_flags_index', '{{%users}}', ["role", "flags"], false); } public function safeDown() diff --git a/tests/specs/blog_v2/migrations_maria_db/m200000_000004_change_table_v2_users.php b/tests/specs/blog_v2/migrations_maria_db/m200000_000004_change_table_v2_users.php index e70f0b9b..d9c99f76 100644 --- a/tests/specs/blog_v2/migrations_maria_db/m200000_000004_change_table_v2_users.php +++ b/tests/specs/blog_v2/migrations_maria_db/m200000_000004_change_table_v2_users.php @@ -14,7 +14,7 @@ public function up() $this->alterColumn('{{%v2_users}}', 'created_at', $this->timestamp()->null()->defaultValue(null)); $this->dropIndex('v2_users_username_key', '{{%v2_users}}'); $this->createIndex('v2_users_login_key', '{{%v2_users}}', 'login', true); - $this->createIndex('v2_users_role_flags_hash_index', '{{%v2_users}}', 'role,flags', 'hash'); + $this->createIndex('v2_users_role_flags_hash_index', '{{%v2_users}}', ["role", "flags"], 'hash'); } public function down() diff --git a/tests/specs/blog_v2/migrations_mysql_db/m200000_000004_change_table_v2_users.php b/tests/specs/blog_v2/migrations_mysql_db/m200000_000004_change_table_v2_users.php index 82a160cf..45515e1b 100644 --- a/tests/specs/blog_v2/migrations_mysql_db/m200000_000004_change_table_v2_users.php +++ b/tests/specs/blog_v2/migrations_mysql_db/m200000_000004_change_table_v2_users.php @@ -14,7 +14,7 @@ public function up() $this->alterColumn('{{%v2_users}}', 'created_at', $this->timestamp()->null()->defaultValue(null)); $this->dropIndex('v2_users_username_key', '{{%v2_users}}'); $this->createIndex('v2_users_login_key', '{{%v2_users}}', 'login', true); - $this->createIndex('v2_users_role_flags_hash_index', '{{%v2_users}}', 'role,flags', 'hash'); + $this->createIndex('v2_users_role_flags_hash_index', '{{%v2_users}}', ["role", "flags"], 'hash'); } public function down() diff --git a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000004_change_table_v2_users.php b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000004_change_table_v2_users.php index 82e409fb..a57ea8df 100644 --- a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000004_change_table_v2_users.php +++ b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000004_change_table_v2_users.php @@ -16,7 +16,7 @@ public function safeUp() $this->alterColumn('{{%v2_users}}', 'created_at', "DROP DEFAULT"); $this->dropIndex('v2_users_username_key', '{{%v2_users}}'); $this->createIndex('v2_users_login_key', '{{%v2_users}}', 'login', true); - $this->createIndex('v2_users_role_flags_hash_index', '{{%v2_users}}', 'role,flags', 'hash'); + $this->createIndex('v2_users_role_flags_hash_index', '{{%v2_users}}', ["role", "flags"], 'hash'); } public function safeDown() From 1940d22aa0812093f540e8ea9ca51736217527d6 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 19:59:42 +0530 Subject: [PATCH 07/12] Fix https://stackoverflow.com/questions/8482346/mysql-cannot-drop-index-needed-in-a-foreign-key-constraint --- src/lib/migrations/BaseMigrationBuilder.php | 21 ++++++++++--------- .../m200000_000002_create_table_webhooks.php | 14 +++++++++---- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/lib/migrations/BaseMigrationBuilder.php b/src/lib/migrations/BaseMigrationBuilder.php index 67336341..39985f85 100644 --- a/src/lib/migrations/BaseMigrationBuilder.php +++ b/src/lib/migrations/BaseMigrationBuilder.php @@ -141,6 +141,14 @@ public function buildFresh():MigrationModel $this->migration->addUpCode($builder->addPrimaryKey($tableName, $this->model->junctionCols)) ->addDownCode($builder->dropPrimaryKey($tableName, $this->model->junctionCols)); } + + foreach ($this->model->indexes as $index) { + $upCode = $index->isUnique ? $builder->addUniqueIndex($tableName, $index->name, $index->columns) + : $builder->addIndex($tableName, $index->name, $index->columns, $index->type); + $this->migration->addUpCode($upCode) + ->addDownCode($builder->dropIndex($tableName, $index->name)); + } + foreach ($this->model->getHasOneRelations() as $relation) { $fkCol = $relation->getColumnName(); $refCol = $relation->getForeignName(); @@ -153,13 +161,6 @@ public function buildFresh():MigrationModel } } - foreach ($this->model->indexes as $index) { - $upCode = $index->isUnique ? $builder->addUniqueIndex($tableName, $index->name, $index->columns) - : $builder->addIndex($tableName, $index->name, $index->columns, $index->type); - $this->migration->addUpCode($upCode) - ->addDownCode($builder->dropIndex($tableName, $index->name)); - } - return $this->migration; } @@ -211,14 +212,14 @@ function (string $unknownColumn) { } $this->buildColumnChanges($current, $desired, $changedAttributes); } + if (!$relation) { + $this->buildIndexChanges(); + } if ($relation) { $this->buildRelationsForJunction($relation); } else { $this->buildRelations(); } - if (!$relation) { - $this->buildIndexChanges(); - } return $this->migration; } diff --git a/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php index cf3b0845..783d58b0 100644 --- a/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php +++ b/tests/specs/fk_col_name_index/app/migrations_mysql_db/m200000_000002_create_table_webhooks.php @@ -9,21 +9,27 @@ public function up() { $this->createTable('{{%webhooks}}', [ 'id' => $this->primaryKey(), - 'name' => $this->text()->null(), + 'name' => $this->string(255)->null()->defaultValue(null), 'user_id' => $this->integer()->null()->defaultValue(null), 'redelivery_of' => $this->integer()->null()->defaultValue(null), + 'rd_abc_2' => $this->integer()->null()->defaultValue(null), ]); + $this->createIndex('webhooks_user_id_name_key', '{{%webhooks}}', ["user_id", "name"], true); + $this->createIndex('webhooks_redelivery_of_name_key', '{{%webhooks}}', ["redelivery_of", "name"], true); + $this->createIndex('webhooks_rd_abc_2_name_key', '{{%webhooks}}', ["rd_abc_2", "name"], true); $this->addForeignKey('fk_webhooks_user_id_users_id', '{{%webhooks}}', 'user_id', '{{%users}}', 'id'); $this->addForeignKey('fk_webhooks_redelivery_of_deliveries_id', '{{%webhooks}}', 'redelivery_of', '{{%deliveries}}', 'id'); - // TOOD add index names - $this->createIndex('...', '{{%webhooks}}', ['user_id', 'name'], true); - $this->createIndex('...', '{{%webhooks}}', ['redelivery_of', 'name'], true); + $this->addForeignKey('fk_webhooks_rd_abc_2_deliveries_id', '{{%webhooks}}', 'rd_abc_2', '{{%deliveries}}', 'id'); } public function down() { + $this->dropForeignKey('fk_webhooks_rd_abc_2_deliveries_id', '{{%webhooks}}'); $this->dropForeignKey('fk_webhooks_redelivery_of_deliveries_id', '{{%webhooks}}'); $this->dropForeignKey('fk_webhooks_user_id_users_id', '{{%webhooks}}'); + $this->dropIndex('webhooks_rd_abc_2_name_key', '{{%webhooks}}'); + $this->dropIndex('webhooks_redelivery_of_name_key', '{{%webhooks}}'); + $this->dropIndex('webhooks_user_id_name_key', '{{%webhooks}}'); $this->dropTable('{{%webhooks}}'); } } From 63a22e2590110cfc1d26b4ee32813d6a80d496c6 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 20:00:02 +0530 Subject: [PATCH 08/12] Fix https://stackoverflow.com/a/1827099 --- .../app/models/WebhookFaker.php | 5 ++-- .../app/models/base/Webhook.php | 23 ++++++++++++++++++- .../fk_col_name_index/fk_col_name_index.yaml | 1 + 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/tests/specs/fk_col_name_index/app/models/WebhookFaker.php b/tests/specs/fk_col_name_index/app/models/WebhookFaker.php index ea0d6854..11a768a1 100644 --- a/tests/specs/fk_col_name_index/app/models/WebhookFaker.php +++ b/tests/specs/fk_col_name_index/app/models/WebhookFaker.php @@ -30,9 +30,10 @@ public function generateModel($attributes = []) $uniqueFaker = $this->uniqueFaker; $model = new Webhook(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); - $model->name = $faker->sentence; + $model->name = substr($faker->text(255), 0, 255); $model->user_id = $faker->randomElement(\app\models\User::find()->select("id")->column()); - $model->redelivery_of = $faker->numberBetween(0, 1000000); + $model->redelivery_of = $faker->randomElement(\app\models\Delivery::find()->select("id")->column()); + $model->rd_abc_2 = $faker->randomElement(\app\models\Delivery::find()->select("id")->column()); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { diff --git a/tests/specs/fk_col_name_index/app/models/base/Webhook.php b/tests/specs/fk_col_name_index/app/models/base/Webhook.php index 8746e8f0..29a40568 100644 --- a/tests/specs/fk_col_name_index/app/models/base/Webhook.php +++ b/tests/specs/fk_col_name_index/app/models/base/Webhook.php @@ -9,9 +9,11 @@ * @property string $name * @property int $user_id Test model for model code generation that should not contain id column in rules * @property int $redelivery_of + * @property int $rd_abc_2 * * @property \app\models\User $user * @property \app\models\Delivery $redeliveryOf + * @property \app\models\Delivery $rd2 */ abstract class Webhook extends \yii\db\ActiveRecord { @@ -28,7 +30,21 @@ public function rules() 'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'User'], 'redelivery_of_integer' => [['redelivery_of'], 'integer'], 'redelivery_of_exist' => [['redelivery_of'], 'exist', 'targetRelation' => 'RedeliveryOf'], - 'name_string' => [['name'], 'string'], + 'rd_abc_2_integer' => [['rd_abc_2'], 'integer'], + 'rd_abc_2_exist' => [['rd_abc_2'], 'exist', 'targetRelation' => 'Rd2'], + 'user_id_name_unique' => [['user_id', 'name'], 'unique', 'targetAttribute' => [ + 'user_id', + 'name', + ]], + 'redelivery_of_name_unique' => [['redelivery_of', 'name'], 'unique', 'targetAttribute' => [ + 'redelivery_of', + 'name', + ]], + 'rd_abc_2_name_unique' => [['rd_abc_2', 'name'], 'unique', 'targetAttribute' => [ + 'rd_abc_2', + 'name', + ]], + 'name_string' => [['name'], 'string', 'max' => 255], ]; } @@ -41,4 +57,9 @@ public function getRedeliveryOf() { return $this->hasOne(\app\models\Delivery::class, ['id' => 'redelivery_of']); } + + public function getRd2() + { + return $this->hasOne(\app\models\Delivery::class, ['id' => 'rd_abc_2']); + } } diff --git a/tests/specs/fk_col_name_index/fk_col_name_index.yaml b/tests/specs/fk_col_name_index/fk_col_name_index.yaml index 4ea88661..c51e9646 100644 --- a/tests/specs/fk_col_name_index/fk_col_name_index.yaml +++ b/tests/specs/fk_col_name_index/fk_col_name_index.yaml @@ -46,6 +46,7 @@ components: type: integer name: type: string + maxLength: 255 # https://stackoverflow.com/a/1827099 user: $ref: '#/components/schemas/User' # this will automatically create `user_id` column redelivery_of: From 93c8d9e2f8c3407aa51ab885791b5f95c60f6df8 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 20:08:09 +0530 Subject: [PATCH 09/12] Fix https://stackoverflow.com/a/8482400 --- .../migrations/m200000_000002_create_table_blog_posts.php | 8 ++++---- .../m200000_000002_create_table_blog_posts.php | 8 ++++---- .../m200000_000002_create_table_blog_posts.php | 8 ++++---- .../m200000_000002_create_table_blog_posts.php | 8 ++++---- tests/specs/fk_col_name/app/models/WebhookFaker.php | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/specs/blog/migrations/m200000_000002_create_table_blog_posts.php b/tests/specs/blog/migrations/m200000_000002_create_table_blog_posts.php index 64cce2eb..b0b8e371 100644 --- a/tests/specs/blog/migrations/m200000_000002_create_table_blog_posts.php +++ b/tests/specs/blog/migrations/m200000_000002_create_table_blog_posts.php @@ -17,18 +17,18 @@ public function up() 'created_by_id' => $this->integer()->null()->defaultValue(null), ]); $this->addPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}', 'uid'); - $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); - $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); $this->createIndex('blog_posts_title_key', '{{%blog_posts}}', 'title', true); $this->createIndex('blog_posts_slug_key', '{{%blog_posts}}', 'slug', true); + $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); + $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); } public function down() { - $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); - $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}'); $this->dropTable('{{%blog_posts}}'); } diff --git a/tests/specs/blog/migrations_maria_db/m200000_000002_create_table_blog_posts.php b/tests/specs/blog/migrations_maria_db/m200000_000002_create_table_blog_posts.php index 64cce2eb..b0b8e371 100644 --- a/tests/specs/blog/migrations_maria_db/m200000_000002_create_table_blog_posts.php +++ b/tests/specs/blog/migrations_maria_db/m200000_000002_create_table_blog_posts.php @@ -17,18 +17,18 @@ public function up() 'created_by_id' => $this->integer()->null()->defaultValue(null), ]); $this->addPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}', 'uid'); - $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); - $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); $this->createIndex('blog_posts_title_key', '{{%blog_posts}}', 'title', true); $this->createIndex('blog_posts_slug_key', '{{%blog_posts}}', 'slug', true); + $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); + $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); } public function down() { - $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); - $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}'); $this->dropTable('{{%blog_posts}}'); } diff --git a/tests/specs/blog/migrations_mysql_db/m200000_000002_create_table_blog_posts.php b/tests/specs/blog/migrations_mysql_db/m200000_000002_create_table_blog_posts.php index 64cce2eb..b0b8e371 100644 --- a/tests/specs/blog/migrations_mysql_db/m200000_000002_create_table_blog_posts.php +++ b/tests/specs/blog/migrations_mysql_db/m200000_000002_create_table_blog_posts.php @@ -17,18 +17,18 @@ public function up() 'created_by_id' => $this->integer()->null()->defaultValue(null), ]); $this->addPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}', 'uid'); - $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); - $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); $this->createIndex('blog_posts_title_key', '{{%blog_posts}}', 'title', true); $this->createIndex('blog_posts_slug_key', '{{%blog_posts}}', 'slug', true); + $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); + $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); } public function down() { - $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); - $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}'); $this->dropTable('{{%blog_posts}}'); } diff --git a/tests/specs/blog/migrations_pgsql_db/m200000_000002_create_table_blog_posts.php b/tests/specs/blog/migrations_pgsql_db/m200000_000002_create_table_blog_posts.php index 9e9d85dd..8639040d 100644 --- a/tests/specs/blog/migrations_pgsql_db/m200000_000002_create_table_blog_posts.php +++ b/tests/specs/blog/migrations_pgsql_db/m200000_000002_create_table_blog_posts.php @@ -17,18 +17,18 @@ public function safeUp() 'created_by_id' => $this->integer()->null()->defaultValue(null), ]); $this->addPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}', 'uid'); - $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); - $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); $this->createIndex('blog_posts_title_key', '{{%blog_posts}}', 'title', true); $this->createIndex('blog_posts_slug_key', '{{%blog_posts}}', 'slug', true); + $this->addForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}', 'category_id', '{{%categories}}', 'id'); + $this->addForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}', 'created_by_id', '{{%users}}', 'id'); } public function safeDown() { - $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); - $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_created_by_id_users_id', '{{%blog_posts}}'); $this->dropForeignKey('fk_blog_posts_category_id_categories_id', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_slug_key', '{{%blog_posts}}'); + $this->dropIndex('blog_posts_title_key', '{{%blog_posts}}'); $this->dropPrimaryKey('pk_blog_posts_uid', '{{%blog_posts}}'); $this->dropTable('{{%blog_posts}}'); } diff --git a/tests/specs/fk_col_name/app/models/WebhookFaker.php b/tests/specs/fk_col_name/app/models/WebhookFaker.php index ea0d6854..061e20e5 100644 --- a/tests/specs/fk_col_name/app/models/WebhookFaker.php +++ b/tests/specs/fk_col_name/app/models/WebhookFaker.php @@ -32,7 +32,7 @@ public function generateModel($attributes = []) //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = $faker->sentence; $model->user_id = $faker->randomElement(\app\models\User::find()->select("id")->column()); - $model->redelivery_of = $faker->numberBetween(0, 1000000); + $model->redelivery_of = $faker->randomElement(\app\models\Delivery::find()->select("id")->column()); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { From 5b8fd2af948340a6b07ea34a3ef9250d292ce9de Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 20:12:43 +0530 Subject: [PATCH 10/12] Fix style --- src/lib/migrations/MigrationRecordBuilder.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/lib/migrations/MigrationRecordBuilder.php b/src/lib/migrations/MigrationRecordBuilder.php index b3048541..420cb25b 100644 --- a/src/lib/migrations/MigrationRecordBuilder.php +++ b/src/lib/migrations/MigrationRecordBuilder.php @@ -231,7 +231,10 @@ public function addFk(string $fkName, string $tableAlias, string $fkCol, string public function addUniqueIndex(string $tableAlias, string $indexName, array $columns):string { - return sprintf(self::ADD_UNIQUE, $indexName, $tableAlias, + return sprintf( + self::ADD_UNIQUE, + $indexName, + $tableAlias, count($columns) === 1 ? "'{$columns[0]}'" : '["'.implode('", "', $columns).'"]' ); } @@ -239,9 +242,13 @@ public function addUniqueIndex(string $tableAlias, string $indexName, array $col public function addIndex(string $tableAlias, string $indexName, array $columns, ?string $using = null):string { $indexType = $using === null ? 'false' : "'".ColumnToCode::escapeQuotes($using)."'"; - return sprintf(self::ADD_INDEX, $indexName, $tableAlias, + return sprintf( + self::ADD_INDEX, + $indexName, + $tableAlias, count($columns) === 1 ? "'{$columns[0]}'" : '["'.implode('", "', $columns).'"]', - $indexType); + $indexType + ); } public function addPrimaryKey(string $tableAlias, array $columns, string $pkName= null):string From 91587f046207e1b7cc514360a3ef4bc7fb10afab Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 20:17:47 +0530 Subject: [PATCH 11/12] Add docs --- src/lib/AttributeResolver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/AttributeResolver.php b/src/lib/AttributeResolver.php index 3d987df8..0063d8df 100644 --- a/src/lib/AttributeResolver.php +++ b/src/lib/AttributeResolver.php @@ -443,8 +443,13 @@ protected function prepareIndexes(array $indexes):array } } foreach ($props as $prop) { + // for more info see test tests/specs/fk_col_name/fk_col_name.yaml + // File: ForeignKeyColumnNameTest::testIndexForColumnWithCustomName + // first check direct column names if (!isset($this->attributes[$prop])) { + // then check x-fk-column-name if (!in_array($prop, array_keys($xFkColumnNames))) { + // then check relations/reference e.g. `user`/`user_id` $refPropName = (substr($prop, -3) === '_id') ? rtrim($prop, '_id') : null; if ($refPropName && !isset($this->attributes[$refPropName])) { throw new InvalidDefinitionException('Invalid index definition - property ' . $prop From f64aba20380bb5f6386b3d15c1b395ba5deeb11b Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 7 May 2024 20:20:45 +0530 Subject: [PATCH 12/12] Add more docs --- tests/specs/fk_col_name_index/fk_col_name_index.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/specs/fk_col_name_index/fk_col_name_index.yaml b/tests/specs/fk_col_name_index/fk_col_name_index.yaml index c51e9646..c3c6dd94 100644 --- a/tests/specs/fk_col_name_index/fk_col_name_index.yaml +++ b/tests/specs/fk_col_name_index/fk_col_name_index.yaml @@ -37,8 +37,8 @@ components: x-indexes: - 'unique:user_id,name' - 'unique:redelivery_of,name' - # - 'unique:rd2,name' - - 'unique:rd_abc_2,name' + # - 'unique:rd2,name' # incorrect way + - 'unique:rd_abc_2,name' # correct way type: object description: example for x-fk-column-name properties: