diff --git a/README.md b/README.md index 0084d741..aae945c5 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,23 @@ Provide custom database table column name in case of relationship column. This w - x-fk-column-name: redelivery_of # this will create `redelivery_of` column instead of `redelivery_of_id` ``` + +### `x-deleted-schemas` + +This is root level key used to generate "drop table" migration for the deleted component schema. If a component schema (DB model) is removed from OpenAPI spec then its following entities should be also deleted from the code: + + - DB table (migrations) + - model + - faker + +So to generate appropriate migration for the removed schema, explicitly setting schema name or schema name + custom table name is required in this key. Only then the migrations will be generated. It should be set as: + +```yaml +x-deleted-schemas: + - Fruit # Example: table name is evaluated to `itt_fruits`, if `itt_` is prefix set in DB config + - Mango: the_mango_table_name # custom table name; see `x-table` in README.md +``` + ### `x-no-relation` To differentiate a component schema property from one-to-many or many-to-many relation in favour of array(json) of @@ -443,7 +460,7 @@ paths: Generated URL rules config for above is (in `urls.rest.php` or pertinent file): ```php 'GET a1/b1' => 'abc/xyz', - 'POST a1/b1' => 'abc/xyz', + 'POST a1/b1' => 'abc/xyz', 'a1/b1' => 'abc/options', ``` `x-route` does not support [Yii Modules](https://www.yiiframework.com/doc/guide/2.0/en/structure-modules). diff --git a/composer.json b/composer.json index c8994ba8..115ef883 100644 --- a/composer.json +++ b/composer.json @@ -23,11 +23,11 @@ "yiisoft/yii2": "~2.0.48", "yiisoft/yii2-gii": "~2.0.0 | ~2.1.0 | ~2.2.0| ~2.3.0", "laminas/laminas-code": ">=3.4 <=4.13", - "php-openapi/yii2-fractal": "^1.0.0", + "php-openapi/yii2-fractal": "^1.4", "fakerphp/faker": "^1.9", "sam-it/yii2-mariadb": "^2.0", "symfony/var-exporter": "^5.4", - "symfony/polyfill-php80": "^1.30" + "symfony/polyfill-php80": "^1.31" }, "require-dev": { "cebe/indent": "*", diff --git a/src/generator/ApiGenerator.php b/src/generator/ApiGenerator.php index 0c8b7c91..40df4315 100644 --- a/src/generator/ApiGenerator.php +++ b/src/generator/ApiGenerator.php @@ -7,6 +7,9 @@ namespace cebe\yii2openapi\generator; +use cebe\openapi\exceptions\IOException; +use cebe\openapi\exceptions\TypeErrorException; +use cebe\openapi\exceptions\UnresolvableReferenceException; use cebe\yii2openapi\lib\items\DbModel; use cebe\openapi\Reader; use cebe\openapi\spec\OpenApi; @@ -22,6 +25,7 @@ use cebe\yii2openapi\lib\items\RestAction; use cebe\yii2openapi\lib\PathAutoCompletion; use cebe\yii2openapi\lib\SchemaToDatabase; +use Exception; use Yii; use yii\db\mysql\Schema as MySqlSchema; use SamIT\Yii2\MariaDb\Schema as MariaDbSchema; @@ -190,7 +194,7 @@ class ApiGenerator extends Generator private $_openApiWithoutRef; /** - * @var \cebe\yii2openapi\lib\Config $config + * @var Config $config **/ private $config; @@ -297,11 +301,11 @@ public function rules() /** * @param $attribute - * @throws \cebe\openapi\exceptions\IOException - * @throws \cebe\openapi\exceptions\TypeErrorException - * @throws \cebe\openapi\exceptions\UnresolvableReferenceException + * @throws IOException + * @throws TypeErrorException + * @throws UnresolvableReferenceException */ - public function validateSpec($attribute):void + public function validateSpec($attribute): void { if ($this->ignoreSpecErrors) { return; @@ -313,7 +317,7 @@ public function validateSpec($attribute):void } } - public function validateUrlPrefixes($attribute):void + public function validateUrlPrefixes($attribute): void { if (empty($this->urlPrefixes)) { return; @@ -441,7 +445,7 @@ public function stickyAttributes() ); } - public function makeConfig():Config + public function makeConfig(): Config { if (!$this->config) { $props = get_object_vars($this); @@ -471,11 +475,12 @@ public function makeConfig():Config * Please refer to [[\yii\gii\generators\controller\Generator::generate()]] as an example * on how to implement this method. * @return CodeFile[] a list of code files to be created. - * @throws \Exception + * @throws Exception */ - public function generate():array + public function generate(): array { $config = $this->makeConfig(); + $actionsGenerator = $this->useJsonApi ? Yii::createObject(JsonActionGenerator::class, [$config]) : Yii::createObject(RestActionGenerator::class, [$config]); @@ -504,12 +509,12 @@ public function generate():array } /** - * @return \cebe\openapi\spec\OpenApi - * @throws \cebe\openapi\exceptions\IOException - * @throws \cebe\openapi\exceptions\TypeErrorException - * @throws \cebe\openapi\exceptions\UnresolvableReferenceException + * @return OpenApi + * @throws IOException + * @throws TypeErrorException + * @throws UnresolvableReferenceException */ - protected function getOpenApiWithoutReferences():OpenApi + protected function getOpenApiWithoutReferences(): OpenApi { if ($this->_openApiWithoutRef === null) { $file = Yii::getAlias($this->openApiPath); @@ -522,17 +527,17 @@ protected function getOpenApiWithoutReferences():OpenApi return $this->_openApiWithoutRef; } - public static function isPostgres():bool + public static function isPostgres(): bool { return Yii::$app->db->schema instanceof PgSqlSchema; } - public static function isMysql():bool + public static function isMysql(): bool { return (Yii::$app->db->schema instanceof MySqlSchema && !static::isMariaDb()); } - public static function isMariaDb():bool + public static function isMariaDb(): bool { return strpos(Yii::$app->db->schema->getServerVersion(), 'MariaDB') !== false; } diff --git a/src/lib/AttributeResolver.php b/src/lib/AttributeResolver.php index 25f262bf..92014c6e 100644 --- a/src/lib/AttributeResolver.php +++ b/src/lib/AttributeResolver.php @@ -139,7 +139,8 @@ protected function resolveJunctionTableProperty(PropertySchema $property, bool $ ->asReference($junkAttribute['relatedClassName']) ->setPhpType($junkAttribute['phpType']) ->setDbType($junkAttribute['dbType']) - ->setForeignKeyColumnName($property->fkColName); + ->setForeignKeyColumnName($property->fkColName) + ->setTableName($this->componentSchema->resolveTableName($this->schemaName)); $relation = Yii::createObject(AttributeRelation::class, [ $property->getName(), $junkAttribute['relatedTableName'], @@ -205,7 +206,7 @@ protected function resolveHasMany2ManyTableProperty(PropertySchema $property, bo */ protected function resolveProperty( PropertySchema $property, - bool $isRequired, + bool $isRequired, $nullableValue = 'ARG_ABSENT' ): void { if ($nullableValue === 'ARG_ABSENT') { @@ -227,7 +228,8 @@ protected function resolveProperty( ->setNullable($nullableValue) ->setIsPrimary($property->isPrimaryKey()) ->setForeignKeyColumnName($property->fkColName) - ->setFakerStub($this->guessFakerStub($attribute, $property)); + ->setFakerStub($this->guessFakerStub($attribute, $property)) + ->setTableName($this->componentSchema->resolveTableName($this->schemaName)); if ($property->isReference()) { if ($property->isVirtual()) { throw new InvalidDefinitionException('References not supported for virtual attributes'); @@ -374,9 +376,9 @@ protected function resolveProperty( * @throws InvalidConfigException|InvalidDefinitionException */ protected function catchManyToMany( - string $propertyName, - string $relatedSchemaName, - string $relatedTableName, + string $propertyName, + string $relatedSchemaName, + string $relatedTableName, ComponentSchema $refSchema ): bool { if (strtolower(Inflector::id2camel($propertyName, '_')) diff --git a/src/lib/ColumnToCode.php b/src/lib/ColumnToCode.php index b7394388..fdbdfc72 100644 --- a/src/lib/ColumnToCode.php +++ b/src/lib/ColumnToCode.php @@ -399,8 +399,9 @@ private function getIsBuiltinType($type, $dbType) private function resolveEnumType():void { if (ApiGenerator::isPostgres()) { - $rawTableName = $this->dbSchema->getRawTableName($this->tableAlias); - $this->rawParts['type'] = '"enum_'.$rawTableName.'_' . $this->column->name.'"'; + // $rawTableName = $this->dbSchema->getRawTableName($this->tableAlias); + // $this->rawParts['type'] = '"enum_'.$rawTableName.'_' . $this->column->name.'"'; + $this->rawParts['type'] = '"'.$this->column->dbType.'"'; return; } $this->rawParts['type'] = 'enum(' . self::mysqlEnumToString($this->column->enumValues) . ')'; diff --git a/src/lib/CustomSpecAttr.php b/src/lib/CustomSpecAttr.php index 550f6827..e4638746 100644 --- a/src/lib/CustomSpecAttr.php +++ b/src/lib/CustomSpecAttr.php @@ -41,6 +41,12 @@ class CustomSpecAttr */ public const FK_COLUMN_NAME = 'x-fk-column-name'; + /** + * Drop table Migrations to be generated from removed component schemas + * See README for docs + */ + public const DELETED_SCHEMAS = 'x-deleted-schemas'; + /** * Foreign key column name. See README for usage docs */ diff --git a/src/lib/SchemaToDatabase.php b/src/lib/SchemaToDatabase.php index af2521b2..ccb230a3 100644 --- a/src/lib/SchemaToDatabase.php +++ b/src/lib/SchemaToDatabase.php @@ -10,7 +10,9 @@ use cebe\openapi\exceptions\IOException; use cebe\openapi\exceptions\TypeErrorException; use cebe\openapi\exceptions\UnresolvableReferenceException; +use cebe\yii2openapi\generator\ApiGenerator; use cebe\yii2openapi\lib\exceptions\InvalidDefinitionException; +use cebe\yii2openapi\lib\items\Attribute; use cebe\yii2openapi\lib\items\AttributeRelation; use cebe\yii2openapi\lib\items\DbModel; use cebe\yii2openapi\lib\items\JunctionSchemas; @@ -18,6 +20,10 @@ use Yii; use yii\base\Exception; use yii\base\InvalidConfigException; +use yii\db\ColumnSchema; +use yii\db\Schema; +use yii\helpers\ArrayHelper; +use yii\helpers\Inflector; use yii\helpers\StringHelper; use function count; @@ -57,7 +63,7 @@ * minLength: #(numeric value, can be applied for validation rules) * default: #(int|string, default value, used for database migration and model rules) * x-db-type: #(Custom database type like JSON, JSONB, CHAR, VARCHAR, UUID, etc ) - * x-faker: #(custom faker generator, for ex '$faker->gender') + * x-faker: #(custom faker generator, for ex '$faker->gender'; PHP code as string) * description: #(optional, used for comment) */ class SchemaToDatabase @@ -97,7 +103,7 @@ public function prepareModels(): array if ($junctions->isJunctionSchema($schemaName)) { $schemaName = $junctions->trimPrefix($schemaName); } - /**@var AttributeResolver $resolver */ + /** @var AttributeResolver $resolver */ $resolver = Yii::createObject(AttributeResolver::class, [$schemaName, $schema, $junctions, $this->config]); // $models[$schemaName] = $resolver->resolve(); @@ -125,7 +131,14 @@ public function prepareModels(): array } } - return $models; + // for drop table/schema https://github.com/cebe/yii2-openapi/issues/132 + $modelsToDrop = []; + if (isset($this->config->getOpenApi()->{CustomSpecAttr::DELETED_SCHEMAS})) { + $tablesToDrop = $this->config->getOpenApi()->{CustomSpecAttr::DELETED_SCHEMAS}; // for removed (components) schemas + $modelsToDrop = static::dbModelsForDropTable($tablesToDrop); + } + + return ArrayHelper::merge($models, $modelsToDrop); } /** @@ -244,4 +257,123 @@ private function canGenerateModel(string $schemaName, ComponentSchema $schema): } return true; } + + /** + * @param array $schemasToDrop . Example structure: + * ``` + * array(2) { + * [0]=> + * string(5) "Fruit" + * [1]=> + * array(1) { + * ["Mango"]=> + * string(10) "the_mango_custom_table_name" + * } + * } + * ``` + * @return DbModel[] + */ + public static function dbModelsForDropTable(array $schemasToDrop): array + { + $dbModelsToDrop = []; + foreach ($schemasToDrop as $key => $value) { + if (is_string($value)) { // schema name + $schemaName = $value; + $tableName = static::resolveTableName($schemaName); + } elseif (is_array($value)) { + $schemaName = array_key_first($value); + $tableName = $value[$schemaName]; + } else { + throw new \Exception('Malformed list of schemas to delete'); + } + + $table = Yii::$app->db->schema->getTableSchema("{{%$tableName}}", true); + if ($table) { + $localDbModel = new DbModel([ + 'pkName' => $table->primaryKey[0], + 'name' => $schemaName, + 'tableName' => $tableName, + 'attributes' => static::attributesFromColumnSchemas(static::enhanceColumnSchemas($table->columns)), + 'drop' => true + ]); + $dbModelsToDrop[$key] = $localDbModel; + } + } + return $dbModelsToDrop; + } + + public static function resolveTableName(string $schemaName): string + { + return Inflector::camel2id(StringHelper::basename(Inflector::pluralize($schemaName)), '_'); + } + + /** + * @return Attribute[] + */ + public static function attributesFromColumnSchemas(array $columnSchemas): array + { + $attributes = []; + foreach ($columnSchemas as $columnName => $columnSchema) { + /** @var $columnName string */ + /** @var $columnSchema ColumnSchema */ + unset($attribute); + $attribute = new Attribute($columnSchema->name, [ + 'phpType' => $columnSchema->phpType, + 'dbType' => $columnSchema->dbType, + 'fkColName' => $columnSchema->name, + + 'required' => !$columnSchema->allowNull && ($columnSchema->defaultValue === null), + 'nullable' => $columnSchema->allowNull, + 'size' => $columnSchema->size, + + 'primary' => $columnSchema->isPrimaryKey, + 'enumValues' => $columnSchema->enumValues, + 'defaultValue' => $columnSchema->defaultValue, + 'description' => $columnSchema->comment, + ]); + $attributes[] = $attribute; + } + return $attributes; + } + + public static function enhanceColumnSchemas(array $columnSchemas) + { + foreach ($columnSchemas as $columnSchema) { + // PgSQL array + if (property_exists($columnSchema, 'dimension') && $columnSchema->dimension !== 0) { + for ($i = 0; $i < $columnSchema->dimension; $i++) { + $columnSchema->dbType .= '[]'; + } + } + + if (ApiGenerator::isPostgres() && $columnSchema->type === Schema::TYPE_DECIMAL) { + $columnSchema->dbType .= '('.$columnSchema->precision.','.$columnSchema->scale.')'; + } + + // generate PK using `->primaryKeys()` or similar methods instead of separate SQL statement which sets only PK to a column of table + // https://github.com/cebe/yii2-openapi/issues/132 + if (in_array($columnSchema->phpType, [ + 'integer', + 'string' # https://github.com/yiisoft/yii2/issues/14663 + ]) + && $columnSchema->isPrimaryKey === true && $columnSchema->autoIncrement + ) { + str_ireplace(['BIGINT', 'int8', 'bigserial', 'serial8'], 'nothing', $columnSchema->dbType, $count); # can be refactored if https://github.com/yiisoft/yii2/issues/20209 is fixed + if ($count) { + if ($columnSchema->unsigned) { + $columnSchema->dbType = Schema::TYPE_UBIGPK; + } else { + $columnSchema->dbType = Schema::TYPE_BIGPK; + } + } else { + if ($columnSchema->unsigned) { + $columnSchema->dbType = Schema::TYPE_UPK; + } else { + $columnSchema->dbType = Schema::TYPE_PK; + } + } + } + } + return $columnSchemas; + } } diff --git a/src/lib/generators/MigrationsGenerator.php b/src/lib/generators/MigrationsGenerator.php index 4b5ddee0..1c0dfb51 100644 --- a/src/lib/generators/MigrationsGenerator.php +++ b/src/lib/generators/MigrationsGenerator.php @@ -12,6 +12,7 @@ use cebe\yii2openapi\lib\items\DbModel; use cebe\yii2openapi\lib\items\MigrationModel; use cebe\yii2openapi\lib\migrations\BaseMigrationBuilder; +use cebe\yii2openapi\lib\migrations\MigrationRecordBuilder; use cebe\yii2openapi\lib\migrations\MysqlMigrationBuilder; use cebe\yii2openapi\lib\migrations\PostgresMigrationBuilder; use Exception; @@ -110,7 +111,10 @@ public function generate():CodeFiles public function buildMigrations():array { $junctions = []; + foreach ($this->models as $model) { + /** @var DbModel $model */ + $migration = $this->createBuilder($model)->build(); if ($migration->notEmpty()) { $this->migrations[$model->tableAlias] = $migration; @@ -126,6 +130,7 @@ public function buildMigrations():array $junctions[] = $relation->viaTableName; } } + return !empty($this->migrations) ? $this->sortMigrationsByDeps() : []; } @@ -147,7 +152,9 @@ protected function createBuilder(DbModel $model):BaseMigrationBuilder protected function sortMigrationsByDeps():array { $this->sorted = []; - ksort($this->migrations); + if ($this->shouldSortMigrationsForDropTables($this->migrations)) { + ksort($this->migrations); + } foreach ($this->migrations as $migration) { //echo "adding {$migration->tableAlias}\n"; $this->sortByDependencyRecurse($migration); @@ -171,10 +178,36 @@ protected function sortByDependencyRecurse(MigrationModel $migration):void //echo "adding dep $dependency\n"; $this->sortByDependencyRecurse($this->migrations[$dependency]); } - unset($this->sorted[$migration->tableAlias]);//necessary for provide valid order + unset($this->sorted[$migration->tableAlias]); // necessary for provide valid order $this->sorted[$migration->tableAlias] = $migration; } elseif ($this->sorted[$migration->tableAlias] === false) { throw new Exception("A circular dependency is detected for table '{$migration->tableAlias}'."); } } + + /** + * Are tables to drop are internally dependent? If yes then don't sort (ksort) + * @param $migrations array (tableAlias => MigrationModel)[] + */ + public function shouldSortMigrationsForDropTables(array $migrations): bool + { + $tables = array_keys($migrations); + + foreach ($this->models as $dbModel) { + /** @var DbModel $dbModel */ + if ($dbModel->drop) { + $ts = Yii::$app->db->getTableSchema('{{%'.$dbModel->tableName.'}}', true); + if ($ts) { + foreach ($ts->foreignKeys as $fk) { + $fkTableName = str_replace(Yii::$app->db->tablePrefix, '{{%', $fk[0]); + $fkTableName .= '}}'; + if (in_array($fkTableName, $tables)) { + return false; + } + } + } + } + } + return true; + } } diff --git a/src/lib/items/Attribute.php b/src/lib/items/Attribute.php index 909a485d..8b0306c9 100644 --- a/src/lib/items/Attribute.php +++ b/src/lib/items/Attribute.php @@ -8,9 +8,11 @@ namespace cebe\yii2openapi\lib\items; use cebe\yii2openapi\db\ColumnSchema; +use cebe\yii2openapi\generator\ApiGenerator; use cebe\yii2openapi\lib\exceptions\InvalidDefinitionException; use cebe\yii2openapi\lib\helpers\FormatHelper; use cebe\yii2openapi\lib\openapi\PropertySchema; +use Yii; use yii\base\BaseObject; use yii\base\InvalidConfigException; use yii\base\NotSupportedException; @@ -48,8 +50,8 @@ class Attribute extends BaseObject /** * @var string * Contains foreign key column name - * @example 'redelivery_of' - * See usage docs in README for more info + * @example 'redelivery_of' instead of 'redelivery_of_id' + * @see `x-fk-column-name` in README.md */ public $fkColName; @@ -119,6 +121,8 @@ class Attribute extends BaseObject **/ public $fakerStub; + public $tableName; // required for PgSQL enum + /** * @var bool **/ @@ -143,6 +147,12 @@ public function setDbType(string $dbType):Attribute return $this; } + public function setTableName(string $tableName): Attribute + { + $this->tableName = $tableName; + return $this; + } + public function setXDbType($xDbType):Attribute { $this->xDbType = $xDbType; @@ -325,6 +335,9 @@ public function toColumnSchema(): ColumnSchema } if (is_array($this->enumValues)) { $column->enumValues = $this->enumValues; + if (ApiGenerator::isPostgres() && empty($this->xDbType)) { + $column->dbType = 'enum_'.Yii::$app->db->tablePrefix.$this->tableName.'_' . $column->name; + } } $this->handleDecimal($column); diff --git a/src/lib/items/DbModel.php b/src/lib/items/DbModel.php index 9d51a244..1deb9fbc 100644 --- a/src/lib/items/DbModel.php +++ b/src/lib/items/DbModel.php @@ -93,6 +93,13 @@ class DbModel extends BaseObject */ private $_scenarios; + /** + * @var bool + * Drop table if schema is removed. + * @see `x-deleted-schemas` in README.md + * @see https://github.com/cebe/yii2-openapi/issues/132 + */ + public $drop = false; public function getTableAlias(): string { diff --git a/src/lib/items/MigrationModel.php b/src/lib/items/MigrationModel.php index a8ba6611..7f5f6314 100644 --- a/src/lib/items/MigrationModel.php +++ b/src/lib/items/MigrationModel.php @@ -62,13 +62,18 @@ public function __construct(DbModel $model, bool $isFresh = true, ManyToManyRela $this->model = $model; $this->relation = $relation; if ($relation === null) { - $this->fileName = $isFresh - ? 'create_table_' . $model->tableName - : 'change_table_' . $model->tableName; + $this->fileName = $model->drop ? + 'delete_table_' . $model->tableName : + ($isFresh + ? 'create_table_' . $model->tableName + : 'change_table_' . $model->tableName); } else { - $this->fileName = $isFresh - ? 'create_table_' . $relation->viaTableName - : 'change_table_' . $relation->viaTableName; + $this->fileName = + $model->drop ? + 'delete_table_' . $relation->viaTableName : + ($isFresh + ? 'create_table_' . $relation->viaTableName + : 'change_table_' . $relation->viaTableName); } } @@ -132,7 +137,8 @@ public function addUpCode($code, bool $toTop = false):MigrationModel return $this; } - /**add down code, by default to top + /** + * Add down code, by default to top * @param array|string $code * @param bool $toBottom * @return $this diff --git a/src/lib/migrations/BaseMigrationBuilder.php b/src/lib/migrations/BaseMigrationBuilder.php index 58cc61e7..f059c9f4 100644 --- a/src/lib/migrations/BaseMigrationBuilder.php +++ b/src/lib/migrations/BaseMigrationBuilder.php @@ -12,6 +12,7 @@ use cebe\yii2openapi\lib\items\DbModel; use cebe\yii2openapi\lib\items\ManyToManyRelation; use cebe\yii2openapi\lib\items\MigrationModel; +use cebe\yii2openapi\lib\SchemaToDatabase; use Yii; use yii\db\ColumnSchema; use yii\db\Connection; @@ -171,6 +172,7 @@ public function buildSecondary(?ManyToManyRelation $relation = null):MigrationMo { $this->migration = Yii::createObject(MigrationModel::class, [$this->model, false, $relation, []]); $this->newColumns = $relation->columnSchema ?? $this->model->attributesToColumnSchema(); + $this->setColumnsPositions(); $wantNames = array_keys($this->newColumns); $haveNames = $this->tableSchema->columnNames; @@ -190,6 +192,14 @@ function (string $unknownColumn) { $columnsForChange = array_intersect($wantNames, $haveNames); + if ($this->model->drop) { + $this->newColumns = []; + $wantNames = []; + $columnsForCreate = []; + $columnsForChange = []; + $columnsForDrop = []; + } + $this->buildColumnsCreation($columnsForCreate); if ($this->model->junctionCols && !isset($this->model->attributes[$this->model->pkName])) { if (!empty(array_intersect($columnsForDrop, $this->model->junctionCols))) { @@ -202,6 +212,7 @@ function (string $unknownColumn) { $this->buildColumnsDrop($columnsForDrop); foreach ($columnsForChange as $commonColumn) { $current = $this->tableSchema->columns[$commonColumn]; + /** @var \cebe\yii2openapi\db\ColumnSchema|\yii\db\ColumnSchema $desired */ $desired = $this->newColumns[$commonColumn]; if ($current->isPrimaryKey || in_array($desired->dbType, ['pk', 'upk', 'bigpk', 'ubigpk'])) { // do not adjust existing primary keys @@ -222,6 +233,8 @@ function (string $unknownColumn) { $this->buildRelations(); } + $this->buildTablesDrop(); + return $this->migration; } @@ -326,9 +339,9 @@ protected function buildRelations():void $tableAlias = $this->model->getTableAlias(); $existedRelations = []; foreach ($this->tableSchema->foreignKeys as $fkName => $relation) { - $refTable = $this->unPrefixTableName(array_shift($relation)); - $refCol = array_keys($relation)[0]; - $fkCol = $relation[$refCol]; + $refTable = array_shift($relation); + $fkCol = array_keys($relation)[0]; + $refCol = $relation[$fkCol]; $existedRelations[$fkName] = ['refTable' => $refTable, 'refCol' => $refCol, 'fkCol' => $fkCol]; } @@ -434,11 +447,14 @@ public function tmpSaveNewCol(string $tableAlias, \cebe\yii2openapi\db\ColumnSch $name = MigrationRecordBuilder::quote($columnSchema->name); $column = [$name.' '.$this->newColStr($tmpTableName, $columnSchema)]; if (ApiGenerator::isPostgres() && static::isEnum($columnSchema)) { - $column = strtr($column, [$innerEnumTypeName => $tmpEnumName($columnSchema->name)]); + $column = strtr($column[0], [$innerEnumTypeName => $tmpEnumName($columnSchema->name)]); } } else { $column = [$columnSchema->name => $this->newColStr($tmpTableName, $columnSchema)]; if (ApiGenerator::isPostgres() && static::isEnum($columnSchema)) { + $clonedSchema = clone $columnSchema; + $clonedSchema->dbType = trim($innerEnumTypeName, '"'); + $column = [$columnSchema->name => $this->newColStr($tmpTableName, $clonedSchema)]; $column[$columnSchema->name] = strtr($column[$columnSchema->name], [$innerEnumTypeName => $tmpEnumName($columnSchema->name)]); } } @@ -536,6 +552,21 @@ public function modifyDesiredInContextOfDesiredFromDb(ColumnSchema $desired, Col $desired->dbType = $desiredFromDb->dbType; } + public function buildTablesDrop(): void + { + if (!$this->model->drop) { + return; + } + + $this->migration->addUpCode($this->recordBuilder->dropTable($this->model->getTableAlias())) + ->addDownCode( + $this->recordBuilder->createTable( + $this->model->getTableAlias(), + SchemaToDatabase::enhanceColumnSchemas($this->tableSchema->columns) + ) + ); + } + /** * Only for MySQL and MariaDB * Given a column, compute its previous column name present in OpenAPI schema diff --git a/src/lib/migrations/MigrationRecordBuilder.php b/src/lib/migrations/MigrationRecordBuilder.php index 3cf66f0f..0648589f 100644 --- a/src/lib/migrations/MigrationRecordBuilder.php +++ b/src/lib/migrations/MigrationRecordBuilder.php @@ -72,7 +72,7 @@ public function createTable(string $tableAlias, array $columns):string { $codeColumns = []; foreach ($columns as $columnName => $cebeDbColumnSchema) { - if (is_string($cebeDbColumnSchema->xDbType) && !empty($cebeDbColumnSchema->xDbType)) { + if (!empty($cebeDbColumnSchema->xDbType) && is_string($cebeDbColumnSchema->xDbType)) { $name = static::quote($columnName); $codeColumns[] = $name.' '.$this->columnToCode($tableAlias, $cebeDbColumnSchema, false)->getCode(); } else { diff --git a/src/lib/migrations/MysqlMigrationBuilder.php b/src/lib/migrations/MysqlMigrationBuilder.php index b28040a0..2a3f9642 100644 --- a/src/lib/migrations/MysqlMigrationBuilder.php +++ b/src/lib/migrations/MysqlMigrationBuilder.php @@ -50,7 +50,7 @@ protected function compareColumns(ColumnSchema $current, ColumnSchema $desired): $this->modifyDesired($desired); $this->modifyDesiredInContextOfCurrent($current, $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 + // Why this is needed? Often manually created ColumnSchema 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); @@ -131,6 +131,8 @@ public static function getColumnSchemaBuilderClass(): string return \yii\db\mysql\ColumnSchemaBuilder::class; } elseif (ApiGenerator::isMariaDb()) { return \SamIT\Yii2\MariaDb\ColumnSchemaBuilder::class; + } else { + throw new \Exception('Unknown database'); } } @@ -144,7 +146,7 @@ public function modifyCurrent(ColumnSchema $current): void public function modifyDesired(ColumnSchema $desired): void { - /** @var $desired cebe\yii2openapi\db\ColumnSchema|\yii\db\mysql\ColumnSchema */ + /** @var $desired \cebe\yii2openapi\db\ColumnSchema|\yii\db\mysql\ColumnSchema */ if ($desired->phpType === 'int' && $desired->defaultValue !== null) { $desired->defaultValue = (int)$desired->defaultValue; } @@ -158,7 +160,7 @@ public function modifyDesired(ColumnSchema $desired): void public function modifyDesiredInContextOfCurrent(ColumnSchema $current, ColumnSchema $desired): void { /** @var $current \yii\db\mysql\ColumnSchema */ - /** @var $desired cebe\yii2openapi\db\ColumnSchema|\yii\db\mysql\ColumnSchema */ + /** @var $desired \cebe\yii2openapi\db\ColumnSchema|\yii\db\mysql\ColumnSchema */ if ($current->dbType === 'tinyint(1)' && $desired->type === 'boolean') { if (is_bool($desired->defaultValue) || is_string($desired->defaultValue)) { $desired->defaultValue = (int)$desired->defaultValue; diff --git a/src/lib/migrations/PostgresMigrationBuilder.php b/src/lib/migrations/PostgresMigrationBuilder.php index 27efbf8f..8281ca3e 100644 --- a/src/lib/migrations/PostgresMigrationBuilder.php +++ b/src/lib/migrations/PostgresMigrationBuilder.php @@ -17,6 +17,7 @@ final class PostgresMigrationBuilder extends BaseMigrationBuilder * @param array|ColumnSchema[] $columns * @throws \yii\base\InvalidConfigException */ + #[\Override] protected function buildColumnsCreation(array $columns):void { foreach ($columns as $column) { @@ -34,6 +35,7 @@ protected function buildColumnsCreation(array $columns):void * @param array|ColumnSchema[] $columns * @throws \yii\base\InvalidConfigException */ + #[\Override] protected function buildColumnsDrop(array $columns):void { foreach ($columns as $column) { @@ -233,7 +235,7 @@ public function modifyCurrent(ColumnSchema $current): void public function modifyDesired(ColumnSchema $desired): void { - /** @var $desired cebe\yii2openapi\db\ColumnSchema|\yii\db\pgsql\ColumnSchema */ + /** @var $desired \cebe\yii2openapi\db\ColumnSchema|\yii\db\pgsql\ColumnSchema */ if (in_array($desired->phpType, ['int', 'integer']) && $desired->defaultValue !== null) { $desired->defaultValue = (int)$desired->defaultValue; } @@ -246,7 +248,7 @@ public function modifyDesired(ColumnSchema $desired): void public function modifyDesiredInContextOfCurrent(ColumnSchema $current, ColumnSchema $desired): void { /** @var $current \yii\db\pgsql\ColumnSchema */ - /** @var $desired cebe\yii2openapi\db\ColumnSchema|\yii\db\pgsql\ColumnSchema */ + /** @var $desired \cebe\yii2openapi\db\ColumnSchema|\yii\db\pgsql\ColumnSchema */ if ($current->type === $desired->type && !$desired->size && $this->isDbDefaultSize($current)) { $desired->size = $current->size; } diff --git a/src/lib/openapi/ComponentSchema.php b/src/lib/openapi/ComponentSchema.php index 1fc9f92f..809f0958 100644 --- a/src/lib/openapi/ComponentSchema.php +++ b/src/lib/openapi/ComponentSchema.php @@ -11,6 +11,7 @@ use cebe\openapi\spec\Reference; use cebe\openapi\SpecObjectInterface; use cebe\yii2openapi\lib\CustomSpecAttr; +use cebe\yii2openapi\lib\SchemaToDatabase; use Generator; use Yii; use yii\helpers\Inflector; @@ -111,7 +112,7 @@ public function isNonDb():bool public function resolveTableName(string $schemaName):string { return $this->schema->{CustomSpecAttr::TABLE} ?? - Inflector::camel2id(StringHelper::basename(Inflector::pluralize($schemaName)), '_'); + SchemaToDatabase::resolveTableName($schemaName); } public function hasCustomTableName():bool diff --git a/tests/DbTestCase.php b/tests/DbTestCase.php index ca7b17ff..3c02fa95 100644 --- a/tests/DbTestCase.php +++ b/tests/DbTestCase.php @@ -180,8 +180,16 @@ protected function runDownMigrations(string $db = 'mysql', int $number = 2): voi exec('cd tests; php -dxdebug.mode=develop ./yii migrate-'.$db.'/down --interactive=0 '.$number, $downOutput, $downExitCode); $last = count($downOutput) - 1; $lastThird = count($downOutput) - 3; - $this->assertSame($downExitCode, 0); $this->assertSame($downOutput[$last], 'Migrated down successfully.'); + $this->assertSame($downExitCode, 0); $this->assertSame($downOutput[$lastThird], $number.' '.(($number === 1) ? 'migration was' : 'migrations were').' reverted.'); } + + protected function dropFkIfExists(string $table, string $fk): void + { + $tableSchema = Yii::$app->db->schema->getTableSchema($table); + if ($tableSchema && array_key_exists($fk, $tableSchema->foreignKeys)) { + Yii::$app->db->createCommand()->dropForeignKey($fk, $table)->execute(); + } + } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 61f13cfc..d3e05290 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -3,6 +3,7 @@ error_reporting(-1); ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); +ini_set('memory_limit', '150M'); defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'test'); diff --git a/tests/specs/blog_v2/migrations_maria_db/m200000_000005_change_table_v2_comments.php b/tests/specs/blog_v2/migrations_maria_db/m200000_000005_change_table_v2_comments.php index ead3128c..8b655559 100644 --- a/tests/specs/blog_v2/migrations_maria_db/m200000_000005_change_table_v2_comments.php +++ b/tests/specs/blog_v2/migrations_maria_db/m200000_000005_change_table_v2_comments.php @@ -27,7 +27,7 @@ public function down() $this->alterColumn('{{%v2_comments}}', 'message', 'json NOT NULL DEFAULT \'[]\''); $this->addColumn('{{%v2_comments}}', 'author_id', $this->integer(11)->notNull()->after('post_id')); $this->dropColumn('{{%v2_comments}}', 'user_id'); - $this->addForeignKey('fk_v2_comments_author_id_v2_users_id', '{{%v2_comments}}', 'id', 'v2_users', 'author_id'); - $this->addForeignKey('fk_v2_comments_post_id_v2_posts_uid', '{{%v2_comments}}', 'uid', 'v2_posts', 'post_id'); + $this->addForeignKey('fk_v2_comments_author_id_v2_users_id', '{{%v2_comments}}', 'author_id', 'itt_v2_users', 'id'); + $this->addForeignKey('fk_v2_comments_post_id_v2_posts_uid', '{{%v2_comments}}', 'post_id', 'itt_v2_posts', 'uid'); } } diff --git a/tests/specs/blog_v2/migrations_mysql_db/m200000_000005_change_table_v2_comments.php b/tests/specs/blog_v2/migrations_mysql_db/m200000_000005_change_table_v2_comments.php index 497550fc..0051469e 100644 --- a/tests/specs/blog_v2/migrations_mysql_db/m200000_000005_change_table_v2_comments.php +++ b/tests/specs/blog_v2/migrations_mysql_db/m200000_000005_change_table_v2_comments.php @@ -27,7 +27,7 @@ public function down() $this->alterColumn('{{%v2_comments}}', 'message', 'json NOT NULL'); $this->addColumn('{{%v2_comments}}', 'author_id', $this->integer()->notNull()->after('post_id')); $this->dropColumn('{{%v2_comments}}', 'user_id'); - $this->addForeignKey('fk_v2_comments_author_id_v2_users_id', '{{%v2_comments}}', 'id', 'v2_users', 'author_id'); - $this->addForeignKey('fk_v2_comments_post_id_v2_posts_uid', '{{%v2_comments}}', 'uid', 'v2_posts', 'post_id'); + $this->addForeignKey('fk_v2_comments_author_id_v2_users_id', '{{%v2_comments}}', 'author_id', 'itt_v2_users', 'id'); + $this->addForeignKey('fk_v2_comments_post_id_v2_posts_uid', '{{%v2_comments}}', 'post_id', 'itt_v2_posts', 'uid'); } } diff --git a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000005_change_table_v2_comments.php b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000005_change_table_v2_comments.php index 99a896c6..efbb21be 100644 --- a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000005_change_table_v2_comments.php +++ b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000005_change_table_v2_comments.php @@ -33,7 +33,7 @@ public function safeDown() $this->alterColumn('{{%v2_comments}}', 'message', "SET DEFAULT '[]'"); $this->alterColumn('{{%v2_comments}}', 'meta_data', "SET NOT NULL"); $this->alterColumn('{{%v2_comments}}', 'meta_data', "SET DEFAULT '[]'"); - $this->addForeignKey('fk_v2_comments_post_id_v2_posts_uid', '{{%v2_comments}}', 'uid', 'v2_posts', 'post_id'); - $this->addForeignKey('fk_v2_comments_author_id_v2_users_id', '{{%v2_comments}}', 'id', 'v2_users', 'author_id'); + $this->addForeignKey('fk_v2_comments_post_id_v2_posts_uid', '{{%v2_comments}}', 'post_id', 'itt_v2_posts', 'uid'); + $this->addForeignKey('fk_v2_comments_author_id_v2_users_id', '{{%v2_comments}}', 'author_id', 'itt_v2_users', 'id'); } } diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.php new file mode 100644 index 00000000..7fe5327f --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.php @@ -0,0 +1,13 @@ + '@specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.yaml', + 'generateUrls' => false, + 'generateModels' => true, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => false, + 'generateMigrations' => true, + 'generateModelFaker' => false, +]; diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.yaml b/tests/specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.yaml new file mode 100644 index 00000000..74f46474 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.yaml @@ -0,0 +1,35 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: 132_create_migration_for_drop_table \#132 + +x-deleted-schemas: + - Pristine + - Fruit # Example: table name is evaluated to `itt_fruits`, if `itt_` is prefix set in DB config + - Mango: the_mango_table_name # custom table name; see `x-table` in README.md + - Animal: the_animal_table_name + - Upk + - Bigpk + - Ubigpk + +paths: + /: + get: + summary: List + operationId: list + responses: + '200': + description: The information + +components: + schemas: + Foo: # if you remove this entire schema and want to remove its table then you need to add its table name in `x-deleted-schemas` + type: object + description: 132_create_migration_for_drop_table + required: + - id + properties: + id: + type: integer + factor: + type: integer diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.php new file mode 100644 index 00000000..3987f0d2 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.php @@ -0,0 +1,13 @@ + '@specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.yaml', + 'generateUrls' => false, + 'generateModels' => true, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => false, + 'generateMigrations' => true, + 'generateModelFaker' => false, +]; diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.yaml b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.yaml new file mode 100644 index 00000000..7246c450 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.yaml @@ -0,0 +1,31 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: 132_create_migration_for_drop_table \#132 + +x-deleted-schemas: + - Upk + - Bigpk + - Ubigpk + +paths: + /: + get: + summary: List + operationId: list + responses: + '200': + description: The information + +components: + schemas: + Foo: # if you remove this entire schema and want to remove its table then you need to add its table name in `x-deleted-schemas` + type: object + description: 132_create_migration_for_drop_table + required: + - id + properties: + id: + type: integer + factor: + type: integer diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000000_delete_table_bigpks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000000_delete_table_bigpks.php new file mode 100644 index 00000000..9f129332 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000000_delete_table_bigpks.php @@ -0,0 +1,20 @@ +dropTable('{{%bigpks}}'); + } + + public function down() + { + $this->createTable('{{%bigpks}}', [ + 'id' => $this->bigPrimaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000001_create_table_foos.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000001_create_table_foos.php new file mode 100644 index 00000000..9f90d171 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000001_create_table_foos.php @@ -0,0 +1,20 @@ +createTable('{{%foos}}', [ + 'id' => $this->primaryKey(), + 'factor' => $this->integer()->null()->defaultValue(null), + ]); + } + + public function down() + { + $this->dropTable('{{%foos}}'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000002_delete_table_ubigpks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000002_delete_table_ubigpks.php new file mode 100644 index 00000000..b21388c7 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000002_delete_table_ubigpks.php @@ -0,0 +1,20 @@ +dropTable('{{%ubigpks}}'); + } + + public function down() + { + $this->createTable('{{%ubigpks}}', [ + 'id' => $this->bigPrimaryKey()->unsigned(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000003_delete_table_upks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000003_delete_table_upks.php new file mode 100644 index 00000000..e0261bf1 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/migrations_mysql_db/m200000_000003_delete_table_upks.php @@ -0,0 +1,20 @@ +dropTable('{{%upks}}'); + } + + public function down() + { + $this->createTable('{{%upks}}', [ + 'id' => $this->primaryKey()->unsigned(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/Bigpk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/Bigpk.php new file mode 100644 index 00000000..4f078c1b --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/Bigpk.php @@ -0,0 +1,10 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Foo.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Foo.php new file mode 100644 index 00000000..73f0bfba --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Foo.php @@ -0,0 +1,29 @@ + [['factor'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Ubigpk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Ubigpk.php new file mode 100644 index 00000000..c3520fd4 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Ubigpk.php @@ -0,0 +1,30 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Upk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Upk.php new file mode 100644 index 00000000..a8be1725 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql/models/base/Upk.php @@ -0,0 +1,30 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000000_create_table_foos.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000000_create_table_foos.php new file mode 100644 index 00000000..1e71fcd5 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000000_create_table_foos.php @@ -0,0 +1,20 @@ +createTable('{{%foos}}', [ + 'id' => $this->primaryKey(), + 'factor' => $this->integer()->null()->defaultValue(null), + ]); + } + + public function down() + { + $this->dropTable('{{%foos}}'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000001_delete_table_pristines.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000001_delete_table_pristines.php new file mode 100644 index 00000000..efc571a5 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000001_delete_table_pristines.php @@ -0,0 +1,23 @@ +dropForeignKey('name', '{{%pristines}}'); + $this->dropTable('{{%pristines}}'); + } + + public function down() + { + $this->createTable('{{%pristines}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(151)->null()->defaultValue(null), + 'fruit_id' => 'int NULL DEFAULT NULL', + ]); + $this->addForeignKey('name', '{{%pristines}}', 'fruit_id', 'itt_fruits', 'id'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000002_delete_table_fruits.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000002_delete_table_fruits.php new file mode 100644 index 00000000..4a7936ab --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000002_delete_table_fruits.php @@ -0,0 +1,23 @@ +dropForeignKey('name2', '{{%fruits}}'); + $this->dropTable('{{%fruits}}'); + } + + public function down() + { + $this->createTable('{{%fruits}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + 'food_of' => 'int NULL DEFAULT NULL', + ]); + $this->addForeignKey('name2', '{{%fruits}}', 'food_of', 'itt_the_animal_table_name', 'id'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000003_delete_table_the_mango_table_name.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000003_delete_table_the_mango_table_name.php new file mode 100644 index 00000000..033c95ed --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000003_delete_table_the_mango_table_name.php @@ -0,0 +1,23 @@ +dropForeignKey('animal_fruit_fk', '{{%the_mango_table_name}}'); + $this->dropTable('{{%the_mango_table_name}}'); + } + + public function down() + { + $this->createTable('{{%the_mango_table_name}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + 'food_of' => 'int NULL DEFAULT NULL', + ]); + $this->addForeignKey('animal_fruit_fk', '{{%the_mango_table_name}}', 'food_of', 'itt_the_animal_table_name', 'id'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000004_delete_table_the_animal_table_name.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000004_delete_table_the_animal_table_name.php new file mode 100644 index 00000000..c5d36223 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000004_delete_table_the_animal_table_name.php @@ -0,0 +1,20 @@ +dropTable('{{%the_animal_table_name}}'); + } + + public function down() + { + $this->createTable('{{%the_animal_table_name}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000005_delete_table_upks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000005_delete_table_upks.php new file mode 100644 index 00000000..c68dd4d8 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000005_delete_table_upks.php @@ -0,0 +1,20 @@ +dropTable('{{%upks}}'); + } + + public function down() + { + $this->createTable('{{%upks}}', [ + 'id' => $this->primaryKey()->unsigned(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000006_delete_table_bigpks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000006_delete_table_bigpks.php new file mode 100644 index 00000000..6f0e76c2 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000006_delete_table_bigpks.php @@ -0,0 +1,20 @@ +dropTable('{{%bigpks}}'); + } + + public function down() + { + $this->createTable('{{%bigpks}}', [ + 'id' => $this->bigPrimaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000007_delete_table_ubigpks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000007_delete_table_ubigpks.php new file mode 100644 index 00000000..57687175 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/migrations_mysql_db/m200000_000007_delete_table_ubigpks.php @@ -0,0 +1,26 @@ +dropTable('{{%ubigpks}}'); + } + + public function down() + { + $this->createTable('{{%ubigpks}}', [ + 'id' => $this->bigPrimaryKey()->unsigned(), + 'name' => $this->string(150)->null()->defaultValue(null), + 'size' => 'enum("x-small", "small", "medium", "large", "x-large") NOT NULL DEFAULT \'x-small\'', + 'd' => 'smallint(5) unsigned zerofill NULL DEFAULT NULL', + 'e' => 'mediumint(8) unsigned zerofill NULL DEFAULT NULL', + 'f' => 'decimal(12,4) NULL DEFAULT NULL', + 'dp' => $this->double()->null()->defaultValue(null), + 'dp2' => 'double(10,4) NULL DEFAULT NULL', + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/Animal.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/Animal.php new file mode 100644 index 00000000..92caf2f3 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/Animal.php @@ -0,0 +1,10 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Bigpk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Bigpk.php new file mode 100644 index 00000000..3c96ce51 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Bigpk.php @@ -0,0 +1,30 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Foo.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Foo.php new file mode 100644 index 00000000..73f0bfba --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Foo.php @@ -0,0 +1,29 @@ + [['factor'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Fruit.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Fruit.php new file mode 100644 index 00000000..4e52a2c6 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Fruit.php @@ -0,0 +1,32 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + 'food_of_integer' => [['food_of'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Mango.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Mango.php new file mode 100644 index 00000000..14637e36 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Mango.php @@ -0,0 +1,32 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + 'food_of_integer' => [['food_of'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Pristine.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Pristine.php new file mode 100644 index 00000000..4d6bee59 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Pristine.php @@ -0,0 +1,32 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 151], + 'fruit_id_integer' => [['fruit_id'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Ubigpk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Ubigpk.php new file mode 100644 index 00000000..5f8cbf5f --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Ubigpk.php @@ -0,0 +1,50 @@ + [['name', 'f'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + 'size_string' => [['size'], 'string'], + 'size_in' => [['size'], 'in', 'range' => [ + 'x-small', + 'small', + 'medium', + 'large', + 'x-large', + ]], + 'size_default' => [['size'], 'default', 'value' => 'x-small'], + 'd_integer' => [['d'], 'integer'], + 'e_integer' => [['e'], 'integer'], + 'f_string' => [['f'], 'string', 'max' => 12], + 'dp_double' => [['dp'], 'double'], + 'dp2_double' => [['dp2'], 'double'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Upk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Upk.php new file mode 100644 index 00000000..a8be1725 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/mysql/models/base/Upk.php @@ -0,0 +1,30 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000000_create_table_foos.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000000_create_table_foos.php new file mode 100644 index 00000000..268bd109 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000000_create_table_foos.php @@ -0,0 +1,20 @@ +createTable('{{%foos}}', [ + 'id' => $this->primaryKey(), + 'factor' => $this->integer()->null()->defaultValue(null), + ]); + } + + public function safeDown() + { + $this->dropTable('{{%foos}}'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000001_delete_table_pristines.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000001_delete_table_pristines.php new file mode 100644 index 00000000..54dd111e --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000001_delete_table_pristines.php @@ -0,0 +1,23 @@ +dropForeignKey('name', '{{%pristines}}'); + $this->dropTable('{{%pristines}}'); + } + + public function safeDown() + { + $this->createTable('{{%pristines}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(151)->null()->defaultValue(null), + 'fruit_id' => 'int4 NULL DEFAULT NULL', + ]); + $this->addForeignKey('name', '{{%pristines}}', 'fruit_id', 'itt_fruits', 'id'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000002_delete_table_fruits.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000002_delete_table_fruits.php new file mode 100644 index 00000000..7a6b2e8f --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000002_delete_table_fruits.php @@ -0,0 +1,23 @@ +dropForeignKey('name2', '{{%fruits}}'); + $this->dropTable('{{%fruits}}'); + } + + public function safeDown() + { + $this->createTable('{{%fruits}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + 'food_of' => 'int4 NULL DEFAULT NULL', + ]); + $this->addForeignKey('name2', '{{%fruits}}', 'food_of', 'itt_the_animal_table_name', 'id'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000003_delete_table_the_mango_table_name.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000003_delete_table_the_mango_table_name.php new file mode 100644 index 00000000..fd72c4b4 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000003_delete_table_the_mango_table_name.php @@ -0,0 +1,23 @@ +dropForeignKey('animal_fruit_fk', '{{%the_mango_table_name}}'); + $this->dropTable('{{%the_mango_table_name}}'); + } + + public function safeDown() + { + $this->createTable('{{%the_mango_table_name}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + 'food_of' => 'int4 NULL DEFAULT NULL', + ]); + $this->addForeignKey('animal_fruit_fk', '{{%the_mango_table_name}}', 'food_of', 'itt_the_animal_table_name', 'id'); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000004_delete_table_the_animal_table_name.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000004_delete_table_the_animal_table_name.php new file mode 100644 index 00000000..c3f3c88f --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000004_delete_table_the_animal_table_name.php @@ -0,0 +1,20 @@ +dropTable('{{%the_animal_table_name}}'); + } + + public function safeDown() + { + $this->createTable('{{%the_animal_table_name}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000005_delete_table_upks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000005_delete_table_upks.php new file mode 100644 index 00000000..9e9e49ac --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000005_delete_table_upks.php @@ -0,0 +1,22 @@ +dropTable('{{%upks}}'); + } + + public function safeDown() + { + $this->createTable('{{%upks}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + 'current_mood' => '"mood" NULL DEFAULT NULL', + 'e2' => '"enum_itt_upks_e2" NULL DEFAULT NULL', + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000006_delete_table_bigpks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000006_delete_table_bigpks.php new file mode 100644 index 00000000..2ba13f50 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000006_delete_table_bigpks.php @@ -0,0 +1,20 @@ +dropTable('{{%bigpks}}'); + } + + public function safeDown() + { + $this->createTable('{{%bigpks}}', [ + 'id' => $this->bigPrimaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000007_delete_table_ubigpks.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000007_delete_table_ubigpks.php new file mode 100644 index 00000000..197081f6 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/migrations_pgsql_db/m200000_000007_delete_table_ubigpks.php @@ -0,0 +1,25 @@ +dropTable('{{%ubigpks}}'); + } + + public function safeDown() + { + $this->createTable('{{%ubigpks}}', [ + 'id' => $this->bigPrimaryKey(), + 'name' => $this->string(150)->null()->defaultValue(null), + 'f' => 'numeric(12,4) NULL DEFAULT NULL', + 'g5' => 'text[] NULL DEFAULT NULL', + 'g6' => 'text[][] NULL DEFAULT NULL', + 'g7' => 'numeric(10,7) NULL DEFAULT NULL', + 'dp' => 'float8 NULL DEFAULT NULL', + ]); + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/Animal.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/Animal.php new file mode 100644 index 00000000..92caf2f3 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/Animal.php @@ -0,0 +1,10 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Bigpk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Bigpk.php new file mode 100644 index 00000000..3c96ce51 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Bigpk.php @@ -0,0 +1,30 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Foo.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Foo.php new file mode 100644 index 00000000..73f0bfba --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Foo.php @@ -0,0 +1,29 @@ + [['factor'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Fruit.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Fruit.php new file mode 100644 index 00000000..4e52a2c6 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Fruit.php @@ -0,0 +1,32 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + 'food_of_integer' => [['food_of'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Mango.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Mango.php new file mode 100644 index 00000000..14637e36 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Mango.php @@ -0,0 +1,32 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + 'food_of_integer' => [['food_of'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Pristine.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Pristine.php new file mode 100644 index 00000000..4d6bee59 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Pristine.php @@ -0,0 +1,32 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 151], + 'fruit_id_integer' => [['fruit_id'], 'integer'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Ubigpk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Ubigpk.php new file mode 100644 index 00000000..40750069 --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Ubigpk.php @@ -0,0 +1,40 @@ + [['name', 'f', 'g5', 'g6', 'g7'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + 'f_string' => [['f'], 'string'], + 'g5_string' => [['g5'], 'string'], + 'g6_string' => [['g6'], 'string'], + 'g7_string' => [['g7'], 'string'], + 'dp_double' => [['dp'], 'double'], + ]; + } +} diff --git a/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Upk.php b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Upk.php new file mode 100644 index 00000000..fb18da8f --- /dev/null +++ b/tests/specs/issue_fix/132_create_migration_for_drop_table/pgsql/models/base/Upk.php @@ -0,0 +1,44 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string', 'max' => 150], + 'current_mood_string' => [['current_mood'], 'string'], + 'current_mood_in' => [['current_mood'], 'in', 'range' => [ + 'sad', + 'ok', + 'happy', + ]], + 'e2_string' => [['e2'], 'string'], + 'e2_in' => [['e2'], 'in', 'range' => [ + 'sad2', + 'ok2', + 'happy2', + ]], + ]; + } +} diff --git a/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/Fruit.php b/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/Fruit.php index 2106e69d..ccdbe894 100644 --- a/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/Fruit.php +++ b/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/Fruit.php @@ -1,9 +1,13 @@ hasMany(\app\models\User::class, ['pet_id' => 'id']); + return $this->hasMany(\app\models\User::class, ['pet_id' => 'id'])->inverseOf('pet'); } public function getUserRefObjArr() { - return $this->hasMany(\app\models\User::class, ['pet_id' => 'id']); + return $this->hasMany(\app\models\User::class, ['pet_id' => 'id'])->inverseOf('pet'); } } diff --git a/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/User.php b/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/User.php index 08e59880..bce4e105 100644 --- a/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/User.php +++ b/tests/specs/issue_fix/20_consider_openapi_spec_examples_in_faker_code_generation/mysql/models/base/User.php @@ -1,9 +1,13 @@ [['name', 'paymentMethodName'], 'trim'], 'required' => [['name'], 'required'], 'user_id_integer' => [['user_id'], 'integer'], - 'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'User'], + 'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'user'], 'user2_id_integer' => [['user2_id'], 'integer'], - 'user2_id_exist' => [['user2_id'], 'exist', 'targetRelation' => 'User2'], + 'user2_id_exist' => [['user2_id'], 'exist', 'targetRelation' => 'user2'], 'user3_integer' => [['user3'], 'integer'], - 'user3_exist' => [['user3'], 'exist', 'targetRelation' => 'User3'], + 'user3_exist' => [['user3'], 'exist', 'targetRelation' => 'user3Rel'], 'name_string' => [['name'], 'string', 'max' => 128], 'paymentMethodName_string' => [['paymentMethodName'], 'string'], ]; @@ -49,7 +53,7 @@ public function getUser2() return $this->hasOne(\app\models\User::class, ['id' => 'user2_id']); } - public function getUser3() + public function getUser3Rel() { return $this->hasOne(\app\models\User::class, ['id' => 'user3']); } diff --git a/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/Menu.php b/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/Menu.php index ec3d0957..7f2eb9aa 100644 --- a/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/Menu.php +++ b/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/Menu.php @@ -1,9 +1,13 @@ [['name'], 'trim'], 'required' => [['name'], 'required'], 'parent_id_integer' => [['parent_id'], 'integer'], - 'parent_id_exist' => [['parent_id'], 'exist', 'targetRelation' => 'Parent'], + 'parent_id_exist' => [['parent_id'], 'exist', 'targetRelation' => 'parent'], 'name_string' => [['name'], 'string', 'min' => 3, 'max' => 100], ]; } diff --git a/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/User.php b/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/User.php index 5f70ce96..7e26bb25 100644 --- a/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/User.php +++ b/tests/specs/issue_fix/25_generate_inverse_relations/mysql/models/base/User.php @@ -1,9 +1,13 @@ [['name'], 'string'], ]; } + + public function getPost() + { + return $this->hasOne(\app\models\Post::class, ['user' => 'id'])->inverseOf('user'); + } } diff --git a/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/base/User.php b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/base/User.php index 87027cf9..eed2ea63 100644 --- a/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/base/User.php +++ b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/base/User.php @@ -1,9 +1,13 @@ [['name'], 'string'], ]; } + + public function getInvoice() + { + return $this->hasOne(\app\models\Invoice::class, ['animal_id' => 'id'])->inverseOf('animal'); + } } diff --git a/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Fruit.php b/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Fruit.php index ccdbe894..d56f106c 100644 --- a/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Fruit.php +++ b/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Fruit.php @@ -27,4 +27,9 @@ public function rules() 'name_string' => [['name'], 'string'], ]; } + + public function getInvoice() + { + return $this->hasOne(\app\models\Invoice::class, ['fruit_id' => 'id'])->inverseOf('fruit'); + } } diff --git a/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Invoice.php b/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Invoice.php index 1495d16b..73190e01 100644 --- a/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Invoice.php +++ b/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/Invoice.php @@ -35,17 +35,17 @@ public function rules() { return [ 'reference_invoice_id_integer' => [['reference_invoice_id'], 'integer'], - 'reference_invoice_id_exist' => [['reference_invoice_id'], 'exist', 'targetRelation' => 'ReferenceInvoice'], + 'reference_invoice_id_exist' => [['reference_invoice_id'], 'exist', 'targetRelation' => 'referenceInvoice'], 'reference_invoice_2_id_integer' => [['reference_invoice_2_id'], 'integer'], - 'reference_invoice_2_id_exist' => [['reference_invoice_2_id'], 'exist', 'targetRelation' => 'ReferenceInvoice2'], + 'reference_invoice_2_id_exist' => [['reference_invoice_2_id'], 'exist', 'targetRelation' => 'referenceInvoice2'], 'user_id_integer' => [['user_id'], 'integer'], - 'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'User'], + 'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'user'], 'user_2_id_integer' => [['user_2_id'], 'integer'], - 'user_2_id_exist' => [['user_2_id'], 'exist', 'targetRelation' => 'User2'], + 'user_2_id_exist' => [['user_2_id'], 'exist', 'targetRelation' => 'user2'], 'fruit_id_integer' => [['fruit_id'], 'integer'], - 'fruit_id_exist' => [['fruit_id'], 'exist', 'targetRelation' => 'Fruit'], + 'fruit_id_exist' => [['fruit_id'], 'exist', 'targetRelation' => 'fruit'], 'animal_id_integer' => [['animal_id'], 'integer'], - 'animal_id_exist' => [['animal_id'], 'exist', 'targetRelation' => 'Animal'], + 'animal_id_exist' => [['animal_id'], 'exist', 'targetRelation' => 'animal'], ]; } @@ -78,4 +78,14 @@ public function getAnimal() { return $this->hasOne(\app\models\Animal::class, ['id' => 'animal_id']); } + + public function getInvoice() + { + return $this->hasOne(\app\models\Invoice::class, ['reference_invoice_id' => 'id'])->inverseOf('reference_invoice'); + } + + public function getInvoice2() + { + return $this->hasOne(\app\models\Invoice::class, ['reference_invoice_2_id' => 'id'])->inverseOf('reference_invoice_2'); + } } diff --git a/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/User.php b/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/User.php index bce4e105..a6ce6e79 100644 --- a/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/User.php +++ b/tests/specs/issue_fix/52_bug_dependenton_allof_with_x_faker_false/mysql/models/base/User.php @@ -27,4 +27,14 @@ public function rules() 'name_string' => [['name'], 'string'], ]; } + + public function getInvoice() + { + return $this->hasOne(\app\models\Invoice::class, ['user_id' => 'id'])->inverseOf('user'); + } + + public function getInvoice2() + { + return $this->hasOne(\app\models\Invoice::class, ['user_2_id' => 'id'])->inverseOf('user_2'); + } } diff --git a/tests/unit/AttributeResolverTest.php b/tests/unit/AttributeResolverTest.php index 204a1e65..29710a46 100644 --- a/tests/unit/AttributeResolverTest.php +++ b/tests/unit/AttributeResolverTest.php @@ -12,8 +12,6 @@ use cebe\yii2openapi\lib\openapi\ComponentSchema; use tests\DbTestCase; use Yii; -use yii\helpers\VarDumper; -use const PHP_EOL; class AttributeResolverTest extends DbTestCase { @@ -50,11 +48,11 @@ public function testManyToManyResolve() /** * @dataProvider dataProvider - * @param string $schemaName - * @param \cebe\openapi\spec\Schema $openApiSchema - * @param \cebe\yii2openapi\lib\items\DbModel $expected + * @param string $schemaName + * @param Schema $openApiSchema + * @param DbModel $expected */ - public function testResolve(string $schemaName, Schema $openApiSchema, DbModel $expected):void + public function testResolve(string $schemaName, Schema $openApiSchema, DbModel $expected): void { $schema = new ComponentSchema($openApiSchema, $schemaName); $resolver = new AttributeResolver($schemaName, $schema, new JunctionSchemas([])); @@ -70,13 +68,15 @@ public function testResolve(string $schemaName, Schema $openApiSchema, DbModel $ self::assertTrue(isset($expected->relations[$name])); self::assertEquals($expected->relations[$name], $relation); } + foreach ($model->attributes as $name => $attribute) { + $attribute->tableName = null; # just skip `tableName` from testing as of now self::assertTrue(isset($expected->attributes[$name])); self::assertEquals($expected->attributes[$name], $attribute); } } - public function dataProvider():array + public function dataProvider(): array { $schemaFile = Yii::getAlias("@specs/blog.yaml"); $fixture = require Yii::getAlias('@fixtures/blog.php'); diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 5ea7591c..9739f3ec 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -157,41 +157,6 @@ private function createTableForQuoteInAlterColumn() ])->execute(); } - // Stub -> https://github.com/cebe/yii2-openapi/issues/132 - // public function testCreateTableInDownCode() - // { - // $testFile = Yii::getAlias("@specs/issue_fix/create_table_in_down_code/create_table_in_down_code.php"); - // $this->deleteTablesForCreateTableInDownCode(); - // $this->createTableForCreateTableInDownCode(); - // $this->runGenerator($testFile, 'mysql'); - // // $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ - // // 'recursive' => true, - // // ]); - // // $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/create_table_in_down_code/mysql/app"), [ - // // 'recursive' => true, - // // ]); - // // $this->checkFiles($actualFiles, $expectedFiles); - // // $this->runActualMigrations('mysql', 1); - // } - - // private function deleteTablesForCreateTableInDownCode() - // { - // Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%fruits}}')->execute(); - // Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%animals}}')->execute(); - // } - - // private function createTableForCreateTableInDownCode() - // { - // Yii::$app->db->createCommand()->createTable('{{%fruits}}', [ - // 'id' => 'pk', - // 'colourName' => 'varchar(255)', - // ])->execute(); - // Yii::$app->db->createCommand()->createTable('{{%animals}}', [ - // 'id' => 'pk', - // 'colourName' => 'varchar(255)', - // ])->execute(); - // } - // fix https://github.com/cebe/yii2-openapi/issues/143 // timestamp_143 public function testTimestampIssue143() @@ -274,6 +239,224 @@ public function testNullableFalseInRequired() $this->checkFiles($actualFiles, $expectedFiles); } + // https://github.com/php-openapi/yii2-openapi/pull/4#discussion_r1688225258 + public function testCreateMigrationForDropTable132IndependentTablesDropSort() + { + $testFile = Yii::getAlias("@specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/index.php"); + $dropTables = function () { + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%ubigpks}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%bigpks}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%upks}}')->execute(); + }; + + $dropTables(); + Yii::$app->db->createCommand()->createTable('{{%upks}}', [ + 'id' => 'upk', + 'name' => 'string(150)', + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%bigpks}}', [ + 'id' => 'bigpk', + 'name' => 'string(150)', + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%ubigpks}}', [ + 'id' => 'ubigpk', + 'name' => 'string(150)', + ])->execute(); + + $this->runGenerator($testFile); + $this->runActualMigrations('mysql', 4); + + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/132_create_migration_for_drop_table/case_independent_tables_drop_sort/mysql"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); + + $dropTables(); + } + + // Create migration for drop table if a entire schema is deleted from OpenAPI spec #132 + // https://github.com/cebe/yii2-openapi/issues/132 + public function testCreateMigrationForDropTable132() + { + $testFile = Yii::getAlias("@specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.php"); + $this->deleteTablesForCreateMigrationForDropTable132(); + $this->createTablesForCreateMigrationForDropTable132(); + $this->runGenerator($testFile); + $this->runActualMigrations('mysql', 8); + + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/132_create_migration_for_drop_table/mysql"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); + + $this->deleteTablesForCreateMigrationForDropTable132(); + } + + private function createTablesForCreateMigrationForDropTable132() + { + Yii::$app->db->createCommand()->createTable('{{%upks}}', [ + 'id' => 'upk', + 'name' => 'string(150)', + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%bigpks}}', [ + 'id' => 'bigpk', + 'name' => 'string(150)', + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%ubigpks}}', [ + 'id' => 'ubigpk', + 'name' => 'string(150)', + 'size' => "ENUM('x-small', 'small', 'medium', 'large', 'x-large') NOT NULL DEFAULT 'x-small'", + 'd SMALLINT UNSIGNED ZEROFILL', + 'e' => 'MEDIUMINT UNSIGNED ZEROFILL', + 'f' => 'decimal(12,4)', + 'dp' => 'double precision', + 'dp2' => 'double precision(10, 4)' + ])->execute(); + + // --- + Yii::$app->db->createCommand()->createTable('{{%fruits}}', [ + 'id' => 'pk', + 'name' => 'string(150)', + 'food_of' => 'int' + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%pristines}}', [ + 'id' => 'pk', + 'name' => 'string(151)', + 'fruit_id' => 'int', // FK + ])->execute(); + Yii::$app->db->createCommand()->addForeignKey('name', '{{%pristines}}', 'fruit_id', '{{%fruits}}', 'id')->execute(); + + // --- + Yii::$app->db->createCommand()->createTable('{{%the_animal_table_name}}', [ + 'id' => 'pk', + 'name' => 'string(150)', + ])->execute(); + Yii::$app->db->createCommand()->addForeignKey('name2', '{{%fruits}}', 'food_of', '{{%the_animal_table_name}}', 'id')->execute(); + Yii::$app->db->createCommand()->createTable('{{%the_mango_table_name}}', [ + 'id' => 'pk', + 'name' => 'string(150)', + 'food_of' => 'int' + ])->execute(); + Yii::$app->db->createCommand()->addForeignKey('animal_fruit_fk', '{{%the_mango_table_name}}', 'food_of', '{{%the_animal_table_name}}', 'id')->execute(); + } + + private function deleteTablesForCreateMigrationForDropTable132() + { + $this->dropFkIfExists('{{%pristines}}', 'name'); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%pristines}}')->execute(); + + $this->dropFkIfExists('{{%fruits}}', 'name2'); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%fruits}}')->execute(); + + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%upks}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%bigpks}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%ubigpks}}')->execute(); + + $this->dropFkIfExists('{{%the_mango_table_name}}', 'animal_fruit_fk'); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%the_mango_table_name}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%the_animal_table_name}}')->execute(); + } + + // Create migration for drop table if a entire schema is deleted from OpenAPI spec #132 + // https://github.com/cebe/yii2-openapi/issues/132 + // For PgSQL + public function testCreateMigrationForDropTable132ForPgsql() + { + $this->changeDbToPgsql(); + $testFile = Yii::getAlias("@specs/issue_fix/132_create_migration_for_drop_table/132_create_migration_for_drop_table.php"); + $this->deleteTablesForCreateMigrationForDropTable132ForPgsql(); + $this->createTablesForCreateMigrationForDropTable132ForPgsql(); + $this->runGenerator($testFile, 'pgsql'); + $this->runActualMigrations('pgsql', 8); + + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/132_create_migration_for_drop_table/pgsql"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); + + $this->deleteTablesForCreateMigrationForDropTable132ForPgsql(); + } + + private function createTablesForCreateMigrationForDropTable132ForPgsql() + { + Yii::$app->db->createCommand('CREATE TYPE mood AS ENUM (\'sad\', \'ok\', \'happy\')')->execute(); + Yii::$app->db->createCommand('CREATE TYPE enum_itt_upks_e2 AS ENUM (\'sad2\', \'ok2\', \'happy2\')')->execute(); + + Yii::$app->db->createCommand()->createTable('{{%upks}}', [ + 'id' => 'upk', + 'name' => 'string(150)', + 'current_mood' => 'mood', + 'e2' => 'enum_itt_upks_e2', + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%bigpks}}', [ + 'id' => 'bigpk', + 'name' => 'string(150)', + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%ubigpks}}', [ + 'id' => 'ubigpk', + 'name' => 'string(150)', + 'f' => 'decimal(12,4)', + 'g5' => 'text[]', + 'g6' => 'text[][]', + 'g7' => 'numeric(10,7)', + 'dp double precision', + ])->execute(); + + // --- + Yii::$app->db->createCommand()->createTable('{{%fruits}}', [ + 'id' => 'pk', + 'name' => 'string(150)', + 'food_of' => 'int' + ])->execute(); + Yii::$app->db->createCommand()->createTable('{{%pristines}}', [ + 'id' => 'pk', + 'name' => 'string(151)', + 'fruit_id' => 'int', // FK + ])->execute(); + Yii::$app->db->createCommand()->addForeignKey('name', '{{%pristines}}', 'fruit_id', '{{%fruits}}', 'id')->execute(); + + // --- + Yii::$app->db->createCommand()->createTable('{{%the_animal_table_name}}', [ + 'id' => 'pk', + 'name' => 'string(150)', + ])->execute(); + Yii::$app->db->createCommand()->addForeignKey('name2', '{{%fruits}}', 'food_of', '{{%the_animal_table_name}}', 'id')->execute(); + Yii::$app->db->createCommand()->createTable('{{%the_mango_table_name}}', [ + 'id' => 'pk', + 'name' => 'string(150)', + 'food_of' => 'int' + ])->execute(); + Yii::$app->db->createCommand()->addForeignKey('animal_fruit_fk', '{{%the_mango_table_name}}', 'food_of', '{{%the_animal_table_name}}', 'id')->execute(); + } + + private function deleteTablesForCreateMigrationForDropTable132ForPgsql() + { + $this->dropFkIfExists('{{%pristines}}', 'name'); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%pristines}}')->execute(); + + $this->dropFkIfExists('{{%fruits}}', 'name2'); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%fruits}}')->execute(); + + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%upks}}')->execute(); + Yii::$app->db->createCommand('DROP TYPE IF EXISTS mood')->execute(); + Yii::$app->db->createCommand('DROP TYPE IF EXISTS enum_itt_upks_e2')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%bigpks}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%ubigpks}}')->execute(); + + $this->dropFkIfExists('{{%the_mango_table_name}}', 'animal_fruit_fk'); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%the_mango_table_name}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%the_animal_table_name}}')->execute(); + } + public function test162BugDollarrefWithXFaker() { $testFile = Yii::getAlias("@specs/issue_fix/162_bug_dollarref_with_x_faker/162_bug_dollarref_with_x_faker.php"); @@ -366,13 +549,13 @@ public function test29ExtensionFkColumnNameCauseErrorInCaseOfColumnNameWithoutUn { $testFile = Yii::getAlias("@specs/issue_fix/29_extension_fk_column_name_cause_error_in_case_of_column_name_without_underscore/index.php"); $this->runGenerator($testFile); - $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ - 'recursive' => true, - ]); - $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/29_extension_fk_column_name_cause_error_in_case_of_column_name_without_underscore/mysql"), [ - 'recursive' => true, - ]); - $this->checkFiles($actualFiles, $expectedFiles); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/29_extension_fk_column_name_cause_error_in_case_of_column_name_without_underscore/mysql"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); } // https://github.com/php-openapi/yii2-openapi/issues/30