diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8fa87e34..728e0d95 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,38 +21,32 @@ jobs: fail-fast: true matrix: php-versions: ['7.1', '7.2', '7.3', '7.4'] + + # TODO use cache steps: - uses: actions/checkout@v2 - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php + # Run every tests inside Docker container + - name: Docker Compose Setup + uses: ndeloof/install-compose-action@v0.0.1 with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, intl, gd, zip, dom, pgsql - tools: php-cs-fixer - - - name: Get composer cache directory - id: composercache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" + # version: v3.5 # defaults to 'latest' + legacy: true # will also install in PATH as `docker-compose` - - name: Cache Composer packages - id: composer-cache - uses: actions/cache@v2 - with: - path: ${{ steps.composercache.outputs.dir }} - key: ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ hashFiles('**/composer.json') }} - restore-keys: | - ${{ runner.os }}-php-${{ matrix.php-versions }} + - name: Clean + run: make clean_all - - name: Install deps - run: composer install --prefer-dist --no-progress --no-suggest --optimize-autoloader + - name: docker-compose up + run: make up - - name: Prepare permissions - run: mkdir -p tests/tmp && chmod -R 0777 tests/tmp + - name: Install Docker and composer dependencies + run: make installdocker - - name: Unit tests - run: php vendor/bin/phpunit + - name: Migrate + run: make migrate - name: Check style - run: make check-style + run: make check-style-from-host + - name: Run tests + run: make testdocker diff --git a/Makefile b/Makefile index 0c6ab970..44086f91 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,9 @@ all: check-style: vendor/bin/php-cs-fixer fix --diff --dry-run +check-style-from-host: + docker-compose run --rm php sh -c 'vendor/bin/php-cs-fixer fix --diff --dry-run' + fix-style: vendor/bin/indent --tabs composer.json vendor/bin/indent --spaces .php_cs.dist @@ -28,20 +31,40 @@ clean: up: docker-compose up -d + echo "Waiting for mariadb to start up..." + docker-compose exec -T mysql timeout 60s sh -c "while ! (mysql -udbuser -pdbpass -h maria --execute 'SELECT 1;' > /dev/null 2>&1); do echo -n '.'; sleep 0.1 ; done; echo 'ok'" || (docker-compose ps; docker-compose logs; exit 1) cli: docker-compose exec php bash migrate: - mkdir -p "tests/tmp/app" - mkdir -p "tests/tmp/docker_app" + docker-compose run --rm php sh -c 'mkdir -p "tests/tmp/app"' + docker-compose run --rm php sh -c 'mkdir -p "tests/tmp/docker_app"' docker-compose run --rm php sh -c 'cd /app/tests && ./yii migrate --interactive=0' installdocker: docker-compose run --rm php composer install && chmod +x tests/yii testdocker: - docker-compose run --rm php sh -c 'vendor/bin/phpunit tests/unit' + docker-compose run --rm php sh -c 'vendor/bin/phpunit' .PHONY: all check-style fix-style install test clean clean_all up cli installdocker migrate testdocker + +# Docs: + +# outside docker +# clean_all +# clean (in both) +# up +# cli +# migrate +# installdocker +# testdocker + +# inside docker +# check-style +# fix-style +# install +# test +# clean (in both) diff --git a/README.md b/README.md index 597fbc33..94b53f46 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,8 @@ On console you can run the generator with `./yii gii/api --openApiPath=@app/open Run `./yii gii/api --help` for all options. +See [Petstore example](https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore.yaml) for example OpenAPI spec. + ## OpenAPI extensions @@ -114,9 +116,27 @@ Explicitly specify primary key name for table, if it is different from "id" ### `x-db-type` -Explicitly specify the database type for a column. (MUST contains only db type! (json, jsonb, uuid, varchar etc)) -If x-db-type sets as false, property will be processed as virtual; -It will be added in model as public property, but skipped for migrations generation +Explicitly specify the database type for a column. (MUST contains only real DB type! (`json`, `jsonb`, `uuid`, `varchar` etc.)). +If x-db-type sets as `false`, property will be processed as virtual; +It will be added in model as public property, but skipped for migrations generation. + +Example values of `x-db-type` are: + + - `false` (boolean false) + - as string and its value can be like: + - text + - text[] + - INTEGER PRIMARY KEY AUTO_INCREMENT + - decimal(12,4) + - json + - varchar + - VARCHAR + - SMALLINT UNSIGNED ZEROFILL + - MEDIUMINT(10) UNSIGNED ZEROFILL COMMENT "comment" (note the double quotes here) + +Such values are not allowed: + - `int null default null after low_price` (null and default will be handled by `nullable` and `default` keys respectively) + - MEDIUMINT(10) UNSIGNED ZEROFILL NULL DEFAULT '7' COMMENT 'comment' AFTER `seti`, ADD INDEX `t` (`w`) ### `x-indexes` Specify table indexes @@ -248,6 +268,97 @@ $this->update('{{%company}}', ['name' => 'No name']); $this->alterColumn('{{%company}}', 'name', $this->string(128)->notNull()); ``` +### Handling of `NOT NULL` constraints + +`NOT NULL` in DB migrations is determined by `nullable` and `required` properties of the OpenAPI schema. +e.g. attribute = 'my_property'. + +- If you define attribute neither "required" nor via "nullable", then it is by default `NULL`: + +```yaml + ExampleSchema: + properties: + my_property: + type: string +``` + +- If you define attribute in "required", then it is `NOT NULL` + +```yaml + ExampleSchema: + required: + - my_property + properties: + my_property: + type: string +``` + +- If you define attribute via "nullable", then it overrides "required", e.g. allow `NULL` in this case: + +```yaml + ExampleSchema: + required: + - my_property + properties: + my_property: + type: string + nullable: true +``` + +- If you define attribute via "nullable", then it overrides "required", e.g. `NOT NULL` in this case: + +```yaml + test_table: + required: + properties: + my_property: + type: string + nullable: false +``` + +### Handling of `enum` (#enum, #MariaDb) +It work on MariaDb. + + ```yaml + test_table: + properties: + my_property: + enum: + - one + - two + - three +``` + +### Handling of `numeric` (#numeric, #MariaDb) +precision-default = 10 +scale-default = 2 + +- You can define attribute like "numeric(precision,scale)": + ```yaml + test_table: + properties: + my_property: + x-db-type: decimal(12,4) +``` +DB-Result = decimal(12,4) + +- You can define attribute like "numeric(precision)" with default scale-default = 2: + ```yaml + test_table: + properties: + my_property: + x-db-type: decimal(12) +``` +DB-Result = decimal(12,2) + +- You can define attribute like "numeric" with precision-default = 10 and scale-default = 2: + ```yaml + test_table: + properties: + my_property: + x-db-type: decimal +``` +DB-Result = decimal(10,2) ## Screenshots @@ -259,6 +370,32 @@ Generated files:  +# Development + +There commands are available to develop and check the tests. It can be used inside the Docker container. To enter into bash of container run `make cli` . + +```bash +./yii migrate-mysql/up +./yii migrate-mysql/down 4 + +./yii migrate-maria/up +./yii migrate-maria/down 4 + +./yii migrate-pgsql/up +./yii migrate-pgsql/down 4 +``` + +To apply multiple migration with one command: + +```bash +./yii migrate-mysql/up --interactive=0 && \ +./yii migrate-mysql/down --interactive=0 4 && \ +./yii migrate-maria/up --interactive=0 && \ +./yii migrate-maria/down --interactive=0 4 && \ +./yii migrate-pgsql/up --interactive=0 && \ +./yii migrate-pgsql/down --interactive=0 4 +``` + # Support **Need help with your API project?** @@ -268,3 +405,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). + diff --git a/composer.json b/composer.json index b4d3034a..9c8a4da6 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "yiisoft/yii2-gii": "~2.0.0 | ~2.1.0 | ~2.2.0| ~2.3.0", "laminas/laminas-code": "^3.4", "insolita/yii2-fractal": "^1.0.0", - "fakerphp/faker": "^1.9" + "fakerphp/faker": "^1.9", + "sam-it/yii2-mariadb": "^2.0" }, "require-dev": { "cebe/indent": "*", diff --git a/docker-compose.yml b/docker-compose.yml index a4438459..2582e835 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,19 +33,21 @@ services: MYSQL_USER: dbuser MYSQL_PASSWORD: dbpass MYSQL_DATABASE: testdb + maria: - image: mariadb + image: mariadb:10.8 ports: - '23306:3306' volumes: - ./tests/tmp/maria:/var/lib/mysql:rw environment: - TZ: UTC - MYSQL_ALLOW_EMPTY_PASSWORD: 1 - MYSQL_USER: dbuser - MYSQL_PASSWORD: dbpass - MYSQL_DATABASE: testdb - MYSQL_INITDB_SKIP_TZINFO: 1 + # TZ: UTC + # MARIADB_ALLOW_EMPTY_PASSWORD: 1 + MARIADB_ROOT_PASSWORD: verysecret + MARIADB_USER: dbuser + MARIADB_PASSWORD: dbpass + MARIADB_DATABASE: testdb + # MYSQL_INITDB_SKIP_TZINFO: 1 postgres: image: postgres:12 ports: diff --git a/src/db/ColumnSchema.php b/src/db/ColumnSchema.php new file mode 100644 index 00000000..71127a24 --- /dev/null +++ b/src/db/ColumnSchema.php @@ -0,0 +1,28 @@ + and contributors + * @license https://github.com/cebe/yii2-openapi/blob/master/LICENSE + */ + +namespace cebe\yii2openapi\db; + +class ColumnSchema extends \yii\db\ColumnSchema +{ + /** + * @var string|null|false + * Custom DB type which contains real DB type + * Contains x-db-type string if present in OpenAPI YAML/json file + * @see \cebe\yii2openapi\lib\items\Attribute::$xDbType and `x-db-type` docs in README.md + * Used to detect what kind of migration code for column is to be generated + * e.g. `double_p double precision NULL DEFAULT NULL` + * instead of + * ```php + * $this->createTable('{{%alldbdatatypes}}', [ + * ... + * 'double_p' => 'double precision NULL DEFAULT NULL', + * ... + * ``` + */ + public $xDbType; +} diff --git a/src/generator/ApiGenerator.php b/src/generator/ApiGenerator.php index ef9f3d26..75d2b633 100644 --- a/src/generator/ApiGenerator.php +++ b/src/generator/ApiGenerator.php @@ -7,6 +7,9 @@ namespace cebe\yii2openapi\generator; +use yii\db\mysql\Schema as MySqlSchema; +use SamIT\Yii2\MariaDb\Schema as MariaDbSchema; +use yii\db\pgsql\Schema as PgSqlSchema; use cebe\openapi\Reader; use cebe\openapi\spec\OpenApi; use cebe\yii2openapi\lib\Config; @@ -502,4 +505,19 @@ protected function getOpenApiWithoutReferences():OpenApi } return $this->_openApiWithoutRef; } + + public static function isPostgres():bool + { + return Yii::$app->db->schema instanceof PgSqlSchema; + } + + public static function isMysql():bool + { + return (Yii::$app->db->schema instanceof MySqlSchema && !static::isMariaDb()); + } + + 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 1b2e6a9a..578de586 100644 --- a/src/lib/AttributeResolver.php +++ b/src/lib/AttributeResolver.php @@ -203,6 +203,8 @@ protected function resolveProperty(PropertySchema $property, bool $isRequired):v ->setDescription($property->getAttr('description', '')) ->setReadOnly($property->isReadonly()) ->setDefault($property->guessDefault()) + ->setXDbType($property->getAttr('x-db-type')) + ->setNullable($property->getProperty()->getSerializableData()->nullable ?? null) ->setIsPrimary($property->isPrimaryKey()); if ($property->isReference()) { if ($property->isVirtual()) { diff --git a/src/lib/ColumnToCode.php b/src/lib/ColumnToCode.php index 9f3b3973..7a0188e2 100644 --- a/src/lib/ColumnToCode.php +++ b/src/lib/ColumnToCode.php @@ -8,6 +8,7 @@ namespace cebe\yii2openapi\lib; use yii\db\ArrayExpression; +use cebe\yii2openapi\generator\ApiGenerator; use yii\db\ColumnSchema; use yii\db\ColumnSchemaBuilder; use yii\db\Expression; @@ -17,6 +18,7 @@ use yii\db\Schema; use yii\helpers\Json; use yii\helpers\StringHelper; +use yii\helpers\VarDumper; use function in_array; use function is_string; use function preg_replace; @@ -58,9 +60,18 @@ class ColumnToCode /** * @var bool + * Built In Type means the \cebe\yii2openapi\lib\items\Attribute::$type or \cebe\yii2openapi\lib\items\Attribute::$dbType is in list of Yii abstract data type list or not. And if is found we can use \yii\db\SchemaBuilderTrait methods to build migration instead of putting raw SQL */ private $isBuiltinType = false; + /** + * @var bool + * if set to `true`, `getCode()` method will return SQL migration in raw form instead of SchemaBuilderTrait methods + * Example: `string null default null` + * It won't return `$this->string()->null()->defaultValue(null)` + */ + private $raw = false; + /** * @var bool */ @@ -75,19 +86,45 @@ class ColumnToCode */ private $alter; + /** + * @var bool + * Q. How does it differ from `$alter` and why it is needed? + * A. Pgsql alter column data type does not support NULL, DEFAULT etc value. We just have to provide new data type. + * NULL will be handled SET NULL/SET NOT NULL + * DEFAULT will be handled by SET DEFAULT ... + * This property is only used in Pgsql DB and for alter column data type cases + */ + private $alterByXDbType; + /** * ColumnToCode constructor. * @param \yii\db\Schema $dbSchema * @param \yii\db\ColumnSchema $column * @param bool $fromDb (if from database we prefer column type for usage, from schema - dbType) * @param bool $alter (flag for resolve quotes that is different for create and alter) + * @param bool $raw see @property $raw above for docs + * @param bool $alterByXDbType see @alterByXDbType $raw above for docs */ - public function __construct(Schema $dbSchema, ColumnSchema $column, bool $fromDb = false, bool $alter = false) - { + public function __construct( + Schema $dbSchema, + ColumnSchema $column, + bool $fromDb = false, + bool $alter = false, + bool $raw = false, + bool $alterByXDbType = false + ) { $this->dbSchema = $dbSchema; $this->column = $column; $this->fromDb = $fromDb; $this->alter = $alter; + $this->raw = $raw; + $this->alterByXDbType = $alterByXDbType; + + // We use `property_exists()` because sometimes we can have instance of \yii\db\mysql\ColumnSchema (or of Maria/Pgsql) or \cebe\yii2openapi\db\ColumnSchema + if (property_exists($this->column, 'xDbType') && is_string($this->column->xDbType) && !empty($this->column->xDbType)) { + $this->raw = true; + } + $this->resolve(); } @@ -101,35 +138,42 @@ public function getCode(bool $quoted = false):string array_unshift($parts, '$this'); return implode('->', array_filter(array_map('trim', $parts), 'trim')); } - if (!$this->rawParts['default']) { + if ($this->rawParts['default'] === null) { $default = ''; - } elseif ($this->isPostgres() && $this->isEnum()) { + } elseif (ApiGenerator::isPostgres() && $this->isEnum()) { $default = - $this->rawParts['default'] ? ' DEFAULT ' . self::escapeQuotes(trim($this->rawParts['default'])) : ''; + $this->rawParts['default'] !== null ? ' DEFAULT ' . self::escapeQuotes(trim($this->rawParts['default'])) : ''; } else { - $default = $this->rawParts['default'] ? ' DEFAULT ' . trim($this->rawParts['default']) : ''; + $default = $this->rawParts['default'] !== null ? ' DEFAULT ' . trim($this->rawParts['default']) : ''; } $code = $this->rawParts['type'] . ' ' . $this->rawParts['nullable'] . $default; - if ($this->isMysql() && $this->isEnum()) { + if (ApiGenerator::isMysql() && $this->isEnum()) { return $quoted ? '"' . str_replace("\'", "'", $code) . '"' : $code; } + if (ApiGenerator::isPostgres() && $this->alterByXDbType) { + return $quoted ? "'" . $this->rawParts['type'] . "'" : $this->rawParts['type']; + } return $quoted ? "'" . $code . "'" : $code; } public function getAlterExpression(bool $addUsingExpression = false):string { - if ($this->isEnum() && $this->isPostgres()) { + if ($this->isEnum() && ApiGenerator::isPostgres()) { return "'" . sprintf('enum_%1$s USING %1$s::enum_%1$s', $this->column->name) . "'"; } if ($this->column->dbType === 'tsvector') { return "'" . $this->rawParts['type'] . "'"; } - if ($addUsingExpression && $this->isPostgres()) { + if ($addUsingExpression && ApiGenerator::isPostgres()) { return "'" . $this->rawParts['type'] . " ".$this->rawParts['nullable'] .' USING "'.$this->column->name.'"::'.$this->typeWithoutSize($this->rawParts['type'])."'"; } + if (ApiGenerator::isPostgres() && $this->alterByXDbType) { + return "'" . $this->rawParts['type'] . "'"; + } + return $this->isBuiltinType ? '$this->' . $this->fluentParts['type'].'->'.$this->fluentParts['nullable'] : "'" . $this->rawParts['type'] . " ".$this->rawParts['nullable']."'"; @@ -147,7 +191,57 @@ public function isJson():bool public function isEnum():bool { - return StringHelper::startsWith($this->column->dbType, 'enum'); + return !empty($this->column->enumValues); + } + + public function isDecimal() + { + return self::isDecimalByDbType($this->column->dbType); + } + + /** + * @param $dbType + * @return array|false + */ + public static function isDecimalByDbType($dbType) + { + $precision = null; + $scale = null; + + // https://runebook.dev/de/docs/mariadb/decimal/index + $precisionDefault = 10; + $scaleDefault = 2; + + preg_match_all('/(decimal\()+([0-9]+)+(,)+([0-9]+)+(\))/', $dbType, $matches); + if (!empty($matches[4][0])) { + $precision = $matches[2][0]; + $scale = $matches[4][0]; + } + + if (empty($precision)) { + preg_match_all('/(decimal\()+([0-9]+)+(\))/', $dbType, $matches); + if (!empty($matches[2][0])) { + $precision = $matches[2][0]; + $scale = $scaleDefault; + } + } + + if (empty($precision)) { + if (strtolower($dbType) === 'decimal') { + $precision = $precisionDefault; + $scale = $scaleDefault; + } + } + + if (empty($precision)) { + return false; + } + + return [ + 'precision' => (int)$precision, + 'scale' => (int)$scale, + 'dbType' => "decimal($precision,$scale)", + ]; } public static function escapeQuotes(string $str):string @@ -155,6 +249,11 @@ public static function escapeQuotes(string $str):string return str_replace(["'", '"', '$'], ["\\'", "\\'", '\$'], $str); } + public static function undoEscapeQuotes(string $str):string + { + return str_replace(["\\'", "\\'", '\$'], ["'", '"', '$'], $str); + } + public static function wrapQuotes(string $str, string $quotes = "'", bool $escape = true):string { if ($escape && strpos($str, $quotes) !== false) { @@ -208,11 +307,6 @@ private function resolve():void if ($dbType === 'varchar') { $type = $dbType = 'string'; } - if ($this->fromDb === true) { - $this->isBuiltinType = isset((new ColumnSchemaBuilder(''))->categoryMap[$type]); - } else { - $this->isBuiltinType = isset((new ColumnSchemaBuilder(''))->categoryMap[$dbType]); - } $fluentSize = $this->column->size ? '(' . $this->column->size . ')' : '()'; $rawSize = $this->column->size ? '(' . $this->column->size . ')' : ''; $this->rawParts['nullable'] = $this->column->allowNull ? 'NULL' : 'NOT NULL'; @@ -227,17 +321,48 @@ private function resolve():void $this->column->dbType . (strpos($this->column->dbType, '(') !== false ? '' : $rawSize); } elseif ($this->isEnum()) { $this->resolveEnumType(); + } elseif ($this->isDecimal()) { + $this->fluentParts['type'] = $this->column->dbType; + $this->rawParts['type'] = $this->column->dbType; } else { $this->fluentParts['type'] = $type . $fluentSize; $this->rawParts['type'] = $this->column->dbType . (strpos($this->column->dbType, '(') !== false ? '' : $rawSize); } + + $this->isBuiltinType = $this->raw ? false : $this->getIsBuiltinType($type, $dbType); + $this->resolveDefaultValue(); } + /** + * @param $type + * @param $dbType + * @return bool + */ + private function getIsBuiltinType($type, $dbType) + { + if (property_exists($this->column, 'xDbType') && is_string($this->column->xDbType) && !empty($this->column->xDbType)) { + return false; + } + + if ($this->isEnum() && ApiGenerator::isMariaDb()) { + return false; + } + if ($this->fromDb === true) { + return isset( + (new ColumnSchemaBuilder(''))->categoryMap[$type] + ); + } else { + return isset( + (new ColumnSchemaBuilder(''))->categoryMap[$dbType] + ); + } + } + private function resolveEnumType():void { - if ($this->isPostgres()) { + if (ApiGenerator::isPostgres()) { $this->rawParts['type'] = 'enum_' . $this->column->name; return; } @@ -251,8 +376,8 @@ private function resolveDefaultValue():void } $value = $this->column->defaultValue; if ($value === null || (is_string($value) && (stripos($value, 'null::') !== false))) { - $this->fluentParts['default'] = ($this->column->allowNull === true) ? 'defaultValue(null)' : ''; - $this->rawParts['default'] = ($this->column->allowNull === true) ? 'NULL' : ''; + $this->fluentParts['default'] = ($this->column->allowNull === true) ? 'defaultValue(null)' : $this->fluentParts['default']; + $this->rawParts['default'] = ($this->column->allowNull === true) ? 'NULL' : $this->rawParts['default']; return; } $expectInteger = is_numeric($value) && stripos($this->column->dbType, 'int') !== false; @@ -270,7 +395,7 @@ private function resolveDefaultValue():void break; case 'boolean': $this->fluentParts['default'] = (bool)$value === true ? 'defaultValue(true)' : 'defaultValue(false)'; - if ($this->isPostgres()) { + if (ApiGenerator::isPostgres()) { $this->rawParts['default'] = ((bool)$value === true ? "'t'" : "'f'"); } else { $this->rawParts['default'] = ((bool)$value === true ? '1' : '0'); @@ -305,7 +430,7 @@ private function resolveDefaultValue():void ? 'defaultValue(' . $value . ')' : 'defaultValue("' . self::escapeQuotes((string)$value) . '")'; } $this->rawParts['default'] = $expectInteger ? $value : self::wrapQuotes($value); - if ($this->isMysql() && $this->isEnum()) { + if (ApiGenerator::isMysql() && $this->isEnum()) { $this->rawParts['default'] = self::escapeQuotes($this->rawParts['default']); } } @@ -314,29 +439,27 @@ private function resolveDefaultValue():void private function isDefaultAllowed():bool { $type = strtolower($this->column->dbType); - if ($type === 'tsvector') { - return false; + switch ($type) { + case 'tsvector': + return false; + case 'blob': + case 'geometry': + case 'text': + case 'json': + if (ApiGenerator::isMysql()) { + // The BLOB, TEXT, GEOMETRY, and JSON data types cannot be assigned a literal default value. + // https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html + return false; + } + return true; + case 'enum': + default: + return true; } - return !($this->isMysql() && !$this->isMariaDb() && in_array($type, ['blob', 'geometry', 'text', 'json'])); } private function typeWithoutSize(string $type):string { return preg_replace('~(.*)(\(\d+\))~', '$1', $type); } - - private function isPostgres():bool - { - return $this->dbSchema instanceof PgSqlSchema; - } - - private function isMysql():bool - { - return $this->dbSchema instanceof MySqlSchema; - } - - private function isMariaDb():bool - { - return strpos($this->dbSchema->getServerVersion(), 'MariaDB') !== false; - } } diff --git a/src/lib/items/Attribute.php b/src/lib/items/Attribute.php index a71f02e6..f6c4b9ae 100644 --- a/src/lib/items/Attribute.php +++ b/src/lib/items/Attribute.php @@ -7,9 +7,19 @@ namespace cebe\yii2openapi\lib\items; +use yii\helpers\VarDumper; +use \Yii; +use cebe\yii2openapi\lib\openapi\PropertySchema; +use cebe\yii2openapi\generator\ApiGenerator; +use cebe\yii2openapi\lib\exceptions\InvalidDefinitionException; use yii\base\BaseObject; -use yii\db\ColumnSchema; +use cebe\yii2openapi\db\ColumnSchema; use yii\helpers\Inflector; +use yii\helpers\StringHelper; +use yii\db\mysql\Schema as MySqlSchema; +use SamIT\Yii2\MariaDb\Schema as MariaDbSchema; +use yii\db\pgsql\Schema as PgSqlSchema; +use yii\base\NotSupportedException; use function is_array; use function strtolower; @@ -46,6 +56,19 @@ class Attribute extends BaseObject */ public $dbType = 'string'; + /** + * Custom db type + * string | null | false + * if `false` then this attribute is virtual + */ + public $xDbType; + + /** + * nullable + * bool | null + */ + public $nullable; + /** * @var string */ @@ -117,6 +140,18 @@ public function setDbType(string $dbType):Attribute return $this; } + public function setXDbType($xDbType):Attribute + { + $this->xDbType = $xDbType; + return $this; + } + + public function setNullable($nullable):Attribute + { + $this->nullable = $nullable; + return $this; + } + public function setDescription(string $description):Attribute { $this->description = $description; @@ -244,11 +279,12 @@ public function toColumnSchema():ColumnSchema { $column = new ColumnSchema([ 'name' => $this->columnName, - 'phpType'=>$this->phpType, + 'phpType'=> $this->phpType, 'dbType' => strtolower($this->dbType), - 'type' => $this->dbTypeAbstract($this->dbType), - 'allowNull' => !$this->isRequired(), + 'type' => $this->yiiAbstractTypeForDbSpecificType($this->dbType), + 'allowNull' => $this->allowNull(), 'size' => $this->size > 0 ? $this->size : null, + 'xDbType' => $this->xDbType, ]); $column->isPrimaryKey = $this->primary; $column->autoIncrement = $this->primary && $this->phpType === 'int'; @@ -264,30 +300,58 @@ public function toColumnSchema():ColumnSchema if (is_array($this->enumValues)) { $column->enumValues = $this->enumValues; } + $this->handleDecimal($column); return $column; } - private function dbTypeAbstract(string $type):string + /** + * @throws \yii\base\InvalidConfigException + */ + private function yiiAbstractTypeForDbSpecificType(string $dbType): string { - if (stripos($type, 'int') === 0) { - return 'integer'; - } - if (stripos($type, 'string') === 0) { - return 'string'; + if (is_string($this->xDbType) && !empty($this->xDbType) && trim($this->xDbType)) { + list(, $yiiAbstractDataType, ) = PropertySchema::findMoreDetailOf($this->xDbType); + return $yiiAbstractDataType; + } else { + if (stripos($dbType, 'int') === 0) { + return 'integer'; + } + if (stripos($dbType, 'string') === 0) { + return 'string'; + } + if (stripos($dbType, 'varchar') === 0) { + return 'string'; + } + if (stripos($dbType, 'tsvector') === 0) { + return 'string'; + } + if (stripos($dbType, 'json') === 0) { + return 'json'; + } + // TODO? behaviour in Pgsql should remain same but timestamp/datetime bug which is only reproduced in Mysql and Mariadb should be fixed + if (stripos($dbType, 'datetime') === 0) { + return 'timestamp'; + } } - if (stripos($type, 'varchar') === 0) { - return 'string'; - } - if (stripos($type, 'tsvector') === 0) { - return 'string'; - } - if (stripos($type, 'json') === 0) { - return 'json'; + + return $dbType; + } + + private function allowNull() + { + if (is_bool($this->nullable)) { + return $this->nullable; } - if (stripos($type, 'datetime') === 0) { - return 'timestamp'; + return !$this->isRequired(); + } + + public function handleDecimal(ColumnSchema $columnSchema): void + { + if ($decimalAttributes = \cebe\yii2openapi\lib\ColumnToCode::isDecimalByDbType($columnSchema->dbType)) { + $columnSchema->precision = $decimalAttributes['precision']; + $columnSchema->scale = $decimalAttributes['scale']; + $columnSchema->dbType = $decimalAttributes['dbType']; } - return $type; } } diff --git a/src/lib/items/DbModel.php b/src/lib/items/DbModel.php index c306b877..dbfb09cc 100644 --- a/src/lib/items/DbModel.php +++ b/src/lib/items/DbModel.php @@ -139,8 +139,7 @@ public function getEnumAttributes():array return array_filter( $this->attributes, static function (Attribute $attribute) { - return !$attribute->isVirtual && StringHelper::startsWith($attribute->dbType, 'enum') - && !empty($attribute->enumValues); + return !$attribute->isVirtual && !empty($attribute->enumValues); } ); } diff --git a/src/lib/migrations/BaseMigrationBuilder.php b/src/lib/migrations/BaseMigrationBuilder.php index 781e7732..82becfb9 100644 --- a/src/lib/migrations/BaseMigrationBuilder.php +++ b/src/lib/migrations/BaseMigrationBuilder.php @@ -7,11 +7,13 @@ namespace cebe\yii2openapi\lib\migrations; +use cebe\yii2openapi\lib\ColumnToCode; use cebe\yii2openapi\lib\items\DbModel; use cebe\yii2openapi\lib\items\ManyToManyRelation; use cebe\yii2openapi\lib\items\MigrationModel; use Yii; use yii\db\ColumnSchema; +use yii\helpers\VarDumper; use yii\db\Connection; abstract class BaseMigrationBuilder @@ -205,6 +207,10 @@ function (string $unknownColumn) { $current->type = 'enum'; $current->dbType = 'enum'; } + if (!empty($desired->enumValues)) { + $desired->type = 'enum'; + $desired->dbType = 'enum'; + } $changedAttributes = $this->compareColumns($current, $desired); if (empty($changedAttributes)) { continue; @@ -261,6 +267,8 @@ abstract protected function createEnumMigrations():void; abstract protected function isDbDefaultSize(ColumnSchema $current):bool; + abstract public static function getColumnSchemaBuilderClass(): string; + /** * @return array|\cebe\yii2openapi\lib\items\DbIndex[] */ @@ -411,4 +419,31 @@ protected function isNeedUsingExpression(string $fromType, string $toType):bool $dates = ['date', 'timestamp']; return !(in_array($fromType, $dates) && in_array($toType, $dates)); } + + public function tmpSaveNewCol(\cebe\yii2openapi\db\ColumnSchema $columnSchema): \yii\db\ColumnSchema + { + $tableName = 'tmp_table_'; + + Yii::$app->db->createCommand('DROP TABLE IF EXISTS '.$tableName)->execute(); + + if (is_string($columnSchema->xDbType) && !empty($columnSchema->xDbType)) { + $column = [$columnSchema->name.' '.$this->newColStr($columnSchema)]; + } else { + $column = [$columnSchema->name => $this->newColStr($columnSchema)]; + } + + Yii::$app->db->createCommand()->createTable($tableName, $column)->execute(); + + $table = Yii::$app->db->getTableSchema($tableName); + + Yii::$app->db->createCommand()->dropTable($tableName)->execute(); + + return $table->columns[$columnSchema->name]; + } + + public function newColStr(\cebe\yii2openapi\db\ColumnSchema $columnSchema): string + { + $ctc = new ColumnToCode(\Yii::$app->db->schema, $columnSchema, false, false, true); + return ColumnToCode::undoEscapeQuotes($ctc->getCode()); + } } diff --git a/src/lib/migrations/MigrationRecordBuilder.php b/src/lib/migrations/MigrationRecordBuilder.php index cf0a4370..d15ee070 100644 --- a/src/lib/migrations/MigrationRecordBuilder.php +++ b/src/lib/migrations/MigrationRecordBuilder.php @@ -7,6 +7,7 @@ namespace cebe\yii2openapi\lib\migrations; +use cebe\yii2openapi\generator\ApiGenerator; use cebe\yii2openapi\lib\ColumnToCode; use Yii; use yii\db\ColumnSchema; @@ -32,8 +33,14 @@ final class MigrationRecordBuilder public const ADD_FK = MigrationRecordBuilder::INDENT . "\$this->addForeignKey('%s', '%s', '%s', '%s', '%s');"; public const ADD_PK = MigrationRecordBuilder::INDENT . "\$this->addPrimaryKey('%s', '%s', '%s');"; public const ADD_COLUMN = MigrationRecordBuilder::INDENT . "\$this->addColumn('%s', '%s', %s);"; + + public const ADD_COLUMN_RAW = MigrationRecordBuilder::INDENT . "\$this->db->createCommand('ALTER TABLE %s ADD COLUMN %s %s')->execute();"; + public const ALTER_COLUMN = MigrationRecordBuilder::INDENT . "\$this->alterColumn('%s', '%s', %s);"; + public const ALTER_COLUMN_RAW = MigrationRecordBuilder::INDENT . "\$this->db->createCommand('ALTER TABLE %s MODIFY %s %s')->execute();"; + public const ALTER_COLUMN_RAW_PGSQL = MigrationRecordBuilder::INDENT . "\$this->db->createCommand('ALTER TABLE %s ALTER COLUMN %s SET DATA TYPE %s')->execute();"; + /** * @var \yii\db\Schema */ @@ -52,9 +59,15 @@ public function __construct(Schema $dbSchema) */ public function createTable(string $tableAlias, array $columns):string { - $codeColumns = array_map(function (ColumnSchema $column) { - return $this->columnToCode($column, false)->getCode(); - }, $columns); + $codeColumns = []; + foreach ($columns as $columnName => $cebeDbColumnSchema) { + if (is_string($cebeDbColumnSchema->xDbType) && !empty($cebeDbColumnSchema->xDbType)) { + $codeColumns[] = $columnName.' '.$this->columnToCode($cebeDbColumnSchema, false)->getCode(); + } else { + $codeColumns[$columnName] = $this->columnToCode($cebeDbColumnSchema, false)->getCode(); + } + } + $codeColumns = str_replace([PHP_EOL, "\\\'"], [PHP_EOL . self::INDENT, "'"], VarDumper::export($codeColumns)); return sprintf(self::ADD_TABLE, $tableAlias, $codeColumns); } @@ -64,6 +77,11 @@ public function createTable(string $tableAlias, array $columns):string */ public function addColumn(string $tableAlias, ColumnSchema $column):string { + if (is_string($column->xDbType) && !empty($column->xDbType)) { + $converter = $this->columnToCode($column, false); + return sprintf(self::ADD_COLUMN_RAW, $tableAlias, $column->name, $converter->getCode()); + } + $converter = $this->columnToCode($column, false); return sprintf(self::ADD_COLUMN, $tableAlias, $column->name, $converter->getCode(true)); } @@ -73,6 +91,10 @@ public function addColumn(string $tableAlias, ColumnSchema $column):string */ public function addDbColumn(string $tableAlias, ColumnSchema $column):string { + if (property_exists($column, 'xDbType') && is_string($column->xDbType) && !empty($column->xDbType)) { + $converter = $this->columnToCode($column, true); + return sprintf(self::ADD_COLUMN_RAW, $tableAlias, $column->name, $converter->getCode()); + } $converter = $this->columnToCode($column, true); return sprintf(self::ADD_COLUMN, $tableAlias, $column->name, $converter->getCode(true)); } @@ -82,6 +104,15 @@ public function addDbColumn(string $tableAlias, ColumnSchema $column):string */ public function alterColumn(string $tableAlias, ColumnSchema $column):string { + if (property_exists($column, 'xDbType') && is_string($column->xDbType) && !empty($column->xDbType)) { + $converter = $this->columnToCode($column, true, false, true, true); + return sprintf( + ApiGenerator::isPostgres() ? self::ALTER_COLUMN_RAW_PGSQL : self::ALTER_COLUMN_RAW, + $tableAlias, + $column->name, + $converter->getCode() + ); + } $converter = $this->columnToCode($column, true); return sprintf(self::ALTER_COLUMN, $tableAlias, $column->name, $converter->getCode(true)); } @@ -91,6 +122,15 @@ public function alterColumn(string $tableAlias, ColumnSchema $column):string */ public function alterColumnType(string $tableAlias, ColumnSchema $column, bool $addUsing = false):string { + if (property_exists($column, 'xDbType') && is_string($column->xDbType) && !empty($column->xDbType)) { + $converter = $this->columnToCode($column, false, false, true, true); + return sprintf( + ApiGenerator::isPostgres() ? self::ALTER_COLUMN_RAW_PGSQL : self::ALTER_COLUMN_RAW, + $tableAlias, + $column->name, + rtrim(ltrim($converter->getAlterExpression($addUsing), "'"), "'") + ); + } $converter = $this->columnToCode($column, false); return sprintf(self::ALTER_COLUMN, $tableAlias, $column->name, $converter->getAlterExpression($addUsing)); } @@ -100,6 +140,15 @@ public function alterColumnType(string $tableAlias, ColumnSchema $column, bool $ */ public function alterColumnTypeFromDb(string $tableAlias, ColumnSchema $column, bool $addUsing = false) :string { + if (property_exists($column, 'xDbType') && is_string($column->xDbType) && !empty($column->xDbType)) { + $converter = $this->columnToCode($column, true, false, true, true); + return sprintf( + ApiGenerator::isPostgres() ? self::ALTER_COLUMN_RAW_PGSQL : self::ALTER_COLUMN_RAW, + $tableAlias, + $column->name, + rtrim(ltrim($converter->getAlterExpression($addUsing), "'"), "'") + ); + } $converter = $this->columnToCode($column, true); return sprintf(self::ALTER_COLUMN, $tableAlias, $column->name, $converter->getAlterExpression($addUsing)); } @@ -204,8 +253,20 @@ public function dropIndex(string $tableAlias, string $indexName):string /** * @throws \yii\base\InvalidConfigException */ - private function columnToCode(ColumnSchema $column, bool $fromDb = false, bool $alter = false): ColumnToCode - { - return Yii::createObject(ColumnToCode::class, [$this->dbSchema, $column, $fromDb, $alter]); + private function columnToCode( + ColumnSchema $column, + bool $fromDb = false, + bool $alter = false, + bool $raw = false, + bool $alterByXDbType = false + ): ColumnToCode { + return Yii::createObject(ColumnToCode::class, [ + $this->dbSchema, + $column, + $fromDb, + $alter, + $raw, + $alterByXDbType + ]); } } diff --git a/src/lib/migrations/MysqlMigrationBuilder.php b/src/lib/migrations/MysqlMigrationBuilder.php index 65029fcd..9cb17c79 100644 --- a/src/lib/migrations/MysqlMigrationBuilder.php +++ b/src/lib/migrations/MysqlMigrationBuilder.php @@ -7,12 +7,16 @@ namespace cebe\yii2openapi\lib\migrations; +use cebe\yii2openapi\generator\ApiGenerator; +use cebe\yii2openapi\lib\ColumnToCode; use cebe\yii2openapi\lib\items\DbIndex; use yii\base\NotSupportedException; use yii\db\ColumnSchema; use yii\db\IndexConstraint; use yii\db\Schema; +use \Yii; use yii\helpers\ArrayHelper; +use yii\helpers\VarDumper; final class MysqlMigrationBuilder extends BaseMigrationBuilder { @@ -35,29 +39,21 @@ protected function buildColumnChanges(ColumnSchema $current, ColumnSchema $desir protected function compareColumns(ColumnSchema $current, ColumnSchema $desired):array { $changedAttributes = []; - if ($current->dbType === 'tinyint(1)' && $desired->type === 'boolean') { - if (is_bool($desired->defaultValue) || is_string($desired->defaultValue)) { - $desired->defaultValue = (int)$desired->defaultValue; - } - if ($current->defaultValue !== $desired->defaultValue) { - $changedAttributes[] = 'defaultValue'; - } - if ($current->allowNull !== $desired->allowNull) { - $changedAttributes[] = 'allowNull'; - } - return $changedAttributes; - } - if ($current->phpType === 'integer' && $current->defaultValue !== null) { - $current->defaultValue = (int)$current->defaultValue; - } - if ($desired->phpType === 'int' && $desired->defaultValue !== null) { - $desired->defaultValue = (int)$desired->defaultValue; - } - if ($current->type === $desired->type && !$desired->size && $this->isDbDefaultSize($current)) { - $desired->size = $current->size; - } - foreach (['type', 'size', 'allowNull', 'defaultValue', 'enumValues'] as $attr) { - if ($current->$attr !== $desired->$attr) { + + $this->modifyCurrent($current); + $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 + $desiredFromDb = $this->tmpSaveNewCol($desired); + $this->modifyDesired($desiredFromDb); + $this->modifyDesiredInContextOfCurrent($current, $desiredFromDb); + + foreach (['type', 'size', 'allowNull', 'defaultValue', 'enumValues' + , 'dbType', 'phpType' + , 'precision', 'scale', 'unsigned' + ] as $attr) { + if ($current->$attr !== $desiredFromDb->$attr) { $changedAttributes[] = $attr; } } @@ -66,7 +62,7 @@ protected function compareColumns(ColumnSchema $current, ColumnSchema $desired): protected function createEnumMigrations():void { - // Postgres only case + // execute via default } protected function isDbDefaultSize(ColumnSchema $current):bool @@ -107,4 +103,49 @@ protected function findTableIndexes():array return []; } } + + public static function getColumnSchemaBuilderClass(): string + { + if (ApiGenerator::isMysql()) { + return \yii\db\mysql\ColumnSchemaBuilder::class; + } elseif (ApiGenerator::isMariaDb()) { + return \SamIT\Yii2\MariaDb\ColumnSchemaBuilder::class; + } + } + + public function modifyCurrent(ColumnSchema $current): void + { + /** @var $current \yii\db\mysql\ColumnSchema */ + if ($current->phpType === 'integer' && $current->defaultValue !== null) { + $current->defaultValue = (int)$current->defaultValue; + } + } + + public function modifyDesired(ColumnSchema $desired): void + { + /** @var $desired cebe\yii2openapi\db\ColumnSchema|\yii\db\mysql\ColumnSchema */ + if ($desired->phpType === 'int' && $desired->defaultValue !== null) { + $desired->defaultValue = (int)$desired->defaultValue; + } + + if ($decimalAttributes = ColumnToCode::isDecimalByDbType($desired->dbType)) { + $desired->precision = $decimalAttributes['precision']; + $desired->scale = $decimalAttributes['scale']; + } + } + + public function modifyDesiredInContextOfCurrent(ColumnSchema $current, ColumnSchema $desired): void + { + /** @var $current \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; + } + } + + if ($current->type === $desired->type && !$desired->size && $this->isDbDefaultSize($current)) { + $desired->size = $current->size; + } + } } diff --git a/src/lib/migrations/PostgresMigrationBuilder.php b/src/lib/migrations/PostgresMigrationBuilder.php index 70e304af..edd9ec4d 100644 --- a/src/lib/migrations/PostgresMigrationBuilder.php +++ b/src/lib/migrations/PostgresMigrationBuilder.php @@ -9,11 +9,11 @@ use cebe\yii2openapi\lib\items\DbIndex; use yii\db\ColumnSchema; +use yii\helpers\VarDumper; use yii\helpers\ArrayHelper; final class PostgresMigrationBuilder extends BaseMigrationBuilder { - /** * @param array|ColumnSchema[] $columns * @throws \yii\base\InvalidConfigException @@ -105,18 +105,21 @@ protected function buildColumnChanges(ColumnSchema $current, ColumnSchema $desir protected function compareColumns(ColumnSchema $current, ColumnSchema $desired):array { $changedAttributes = []; - if ($current->phpType === 'integer' && $current->defaultValue !== null) { - $current->defaultValue = (int)$current->defaultValue; - } - if ($desired->phpType === 'int' && $desired->defaultValue !== null) { - $desired->defaultValue = (int)$desired->defaultValue; - } - if ($current->type === $desired->type && !$desired->size && $this->isDbDefaultSize($current)) { - $desired->size = $current->size; - } - foreach (['type', 'size', 'allowNull', 'defaultValue', 'enumValues'] as $attr) { - if ($current->$attr !== $desired->$attr) { + $this->modifyCurrent($current); + $this->modifyDesired($desired); + $this->modifyDesiredInContextOfCurrent($current, $desired); + + // for docs, please see MysqlMigrationBuilder file + $desiredFromDb = $this->tmpSaveNewCol($desired); + $this->modifyDesired($desiredFromDb); + $this->modifyDesiredInContextOfCurrent($current, $desiredFromDb); + + foreach (['type', 'size', 'allowNull', 'defaultValue', 'enumValues' + , 'dbType', 'phpType' + , 'precision', 'scale', 'unsigned' + ] as $attr) { + if ($current->$attr !== $desiredFromDb->$attr) { $changedAttributes[] = $attr; } } @@ -190,4 +193,38 @@ protected function findTableIndexes():array } return $dbIndexes; } + + public static function getColumnSchemaBuilderClass(): string + { + return \yii\db\ColumnSchemaBuilder::class; + } + + public function modifyCurrent(ColumnSchema $current): void + { + /** @var $current \yii\db\pgsql\ColumnSchema */ + if ($current->phpType === 'integer' && $current->defaultValue !== null) { + $current->defaultValue = (int)$current->defaultValue; + } + } + + public function modifyDesired(ColumnSchema $desired): void + { + /** @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; + } + if ($decimalAttributes = \cebe\yii2openapi\lib\ColumnToCode::isDecimalByDbType($desired->dbType)) { + $desired->precision = $decimalAttributes['precision']; + $desired->scale = $decimalAttributes['scale']; + } + } + + public function modifyDesiredInContextOfCurrent(ColumnSchema $current, ColumnSchema $desired): void + { + /** @var $current \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/PropertySchema.php b/src/lib/openapi/PropertySchema.php index 4f87e5e9..4137f99a 100644 --- a/src/lib/openapi/PropertySchema.php +++ b/src/lib/openapi/PropertySchema.php @@ -7,6 +7,13 @@ namespace cebe\yii2openapi\lib\openapi; +use yii\db\ColumnSchema; +use cebe\yii2openapi\generator\ApiGenerator; +use yii\db\mysql\Schema as MySqlSchema; +use SamIT\Yii2\MariaDb\Schema as MariaDbSchema; +use yii\db\pgsql\Schema as PgSqlSchema; +use cebe\yii2openapi\lib\items\Attribute; +use yii\base\NotSupportedException; use BadMethodCallException; use cebe\openapi\ReferenceContext; use cebe\openapi\spec\Reference; @@ -19,6 +26,7 @@ use yii\helpers\Inflector; use yii\helpers\Json; use yii\helpers\StringHelper; +use yii\helpers\VarDumper; use function is_int; use function strpos; @@ -315,6 +323,11 @@ public function guessPhpType():string return 'array'; } + if ($customDbType) { + list(, , $phpType) = static::findMoreDetailOf($customDbType); + return $phpType; + } + switch ($this->getAttr('type')) { case 'integer': return 'int'; @@ -343,9 +356,9 @@ public function guessDbType($forReference = false):string } if ($this->hasAttr(CustomSpecAttr::DB_TYPE) && $this->getAttr(CustomSpecAttr::DB_TYPE) !== false) { $customDbType = strtolower($this->getAttr(CustomSpecAttr::DB_TYPE)); - if ($customDbType === 'varchar') { - return YiiDbSchema::TYPE_STRING; - } + // if ($customDbType === 'varchar') { + // return YiiDbSchema::TYPE_STRING; + // } if ($customDbType !== null) { return $customDbType; } @@ -425,4 +438,127 @@ public function guessDefault() return $default; } + + public static function findMoreDetailOf(string $xDbType): array + { + // We can have various values in `x-db-type`. Few examples are: + // double precision(10,2) + // double + // text + // text[] + // decimal(12,2) + // decimal + // pg_lsn + // pg_snapshot + // integer primary key + // time with time zone + // time(3) with time zone + // smallint unsigned zerofill + // mediumint(10) unsigned zerofill comment "comment" + + // We only consider first word of DB type that has more than one word e.g. : + // SQL Standard + // 'double precision', + + // // PgSQL + // 'bit varying', + // 'character varying', + // 'time with time zone', + // 'time(3) with time zone', + // 'time without time zone', + // 'timestamp with time zone', + // 'timestamp(6) with time zone', + // 'timestamp without time zone', + + // Because abstract data type (e.g. yii\db\pgsql\Schema::$typeMap) is same for: + // `double` and `double precision` + // `time` and `time with time zone` + // `time` and `time without time zone` + // `timestamp` and `timestamp without time zone` etc + + + preg_match('/\w+/', $xDbType, $matches); + if (!isset($matches[0])) { + throw new \yii\base\InvalidConfigException('Abnormal x-db-type: "'.$xDbType.'" detected'); + } + $firstWordOfRealJustDbType = strtolower($matches[0]); + + if (ApiGenerator::isMysql()) { + $mysqlSchema = new MySqlSchema; + + if (!array_key_exists($firstWordOfRealJustDbType, $mysqlSchema->typeMap)) { + throw new InvalidDefinitionException('"x-db-type: '.$firstWordOfRealJustDbType.'" is incorrect. "'.$firstWordOfRealJustDbType.'" is not a real data type in MySQL or not implemented in Yii MySQL. See allowed data types list in `\yii\db\mysql\Schema::$typeMap`'); + } + + $yiiAbstractDataType = $mysqlSchema->typeMap[$firstWordOfRealJustDbType]; + } elseif (ApiGenerator::isMariaDb()) { + $mariadbSchema = new MariaDbSchema; + + if (!array_key_exists($firstWordOfRealJustDbType, $mariadbSchema->typeMap)) { + throw new InvalidDefinitionException('"x-db-type: '.$firstWordOfRealJustDbType.'" is incorrect. "'.$firstWordOfRealJustDbType.'" is not a real data type in MariaDb or not implemented in Yii MariaDB. See allowed data types list in `\SamIT\Yii2\MariaDb\Schema::$typeMap`'); + } + $yiiAbstractDataType = $mariadbSchema->typeMap[$firstWordOfRealJustDbType]; + } elseif (ApiGenerator::isPostgres()) { + $pgsqlSchema = new PgSqlSchema; + if (!array_key_exists($firstWordOfRealJustDbType, $pgsqlSchema->typeMap)) { + preg_match('/\w+\ \w+/', $xDbType, $doublePrecisionDataType); + if (!isset($doublePrecisionDataType[0])) { + throw new InvalidDefinitionException('"x-db-type: '.$firstWordOfRealJustDbType.'" is incorrect. "'.$firstWordOfRealJustDbType.'" is not a real data type in PostgreSQL or not implemented in Yii PostgreSQL. See allowed data types list in `\yii\db\pgsql\Schema::$typeMap`'); + } + $doublePrecisionDataType[0] = strtolower($doublePrecisionDataType[0]); + if (!array_key_exists($doublePrecisionDataType[0], $pgsqlSchema->typeMap)) { + throw new InvalidDefinitionException('"x-db-type: '.$doublePrecisionDataType[0].'" is incorrect. "'.$doublePrecisionDataType[0].'" is not a real data type in PostgreSQL or not implemented in Yii PostgreSQL. See allowed data types list in `\yii\db\pgsql\Schema::$typeMap`'); + } + $yiiAbstractDataType = $pgsqlSchema->typeMap[$doublePrecisionDataType[0]]; + } else { + $yiiAbstractDataType = $pgsqlSchema->typeMap[$firstWordOfRealJustDbType]; + } + } else { + throw new NotSupportedException('"x-db-type" for database '.get_class(Yii::$app->db->schema).' is not implemented. It is only implemented for PostgreSQL, MySQL and MariaDB.'); + } + + $phpType = static::getColumnPhpType(new ColumnSchema(['type' => $yiiAbstractDataType])); + if (StringHelper::endsWith($xDbType, '[]')) { + $phpType = 'array'; + } + + return [ + $firstWordOfRealJustDbType, + $yiiAbstractDataType, + $phpType, + ]; + } + + /** + * This method is copied from protected method `getColumnPhpType()` of \yii\db\Schema class + * Extracts the PHP type from abstract DB type. + * @param \yii\db\ColumnSchema $column the column schema information + * @return string PHP type name + */ + public static function getColumnPhpType(ColumnSchema $column): string + { + static $typeMap = [ + // abstract type => php type + YiiDbSchema::TYPE_TINYINT => 'integer', + YiiDbSchema::TYPE_SMALLINT => 'integer', + YiiDbSchema::TYPE_INTEGER => 'integer', + YiiDbSchema::TYPE_BIGINT => 'integer', + YiiDbSchema::TYPE_BOOLEAN => 'boolean', + YiiDbSchema::TYPE_FLOAT => 'double', + YiiDbSchema::TYPE_DOUBLE => 'double', + YiiDbSchema::TYPE_BINARY => 'resource', + YiiDbSchema::TYPE_JSON => 'array', + ]; + if (isset($typeMap[$column->type])) { + if ($column->type === 'bigint') { + return PHP_INT_SIZE === 8 && !$column->unsigned ? 'integer' : 'string'; + } elseif ($column->type === 'integer') { + return PHP_INT_SIZE === 4 && $column->unsigned ? 'string' : 'integer'; + } + + return $typeMap[$column->type]; + } + + return 'string'; + } } diff --git a/tests/DbTestCase.php b/tests/DbTestCase.php index 4d6ec518..8e59422a 100644 --- a/tests/DbTestCase.php +++ b/tests/DbTestCase.php @@ -2,14 +2,17 @@ namespace tests; +use cebe\yii2openapi\generator\ApiGenerator; use Yii; use yii\di\Container; +use yii\db\mysql\Schema as MySqlSchema; +use yii\db\pgsql\Schema as PgSqlSchema; +use \SamIT\Yii2\MariaDb\Schema as MariaDbSchema; use yii\helpers\ArrayHelper; use yii\helpers\FileHelper; class DbTestCase extends \PHPUnit\Framework\TestCase { - protected function prepareTempDir() { FileHelper::removeDirectory(__DIR__ . '/tmp/docker_app'); @@ -31,4 +34,59 @@ protected function destroyApplication() Yii::$app = null; Yii::$container = new Container(); } -} \ No newline at end of file + + protected function setUp() + { + if (getenv('IN_DOCKER') !== 'docker') { + $this->markTestSkipped('For docker env only'); + } + $this->prepareTempDir(); + $this->mockApplication(); + parent::setUp(); + } + + protected function tearDown() + { + parent::tearDown(); + if (getenv('IN_DOCKER') === 'docker') { + $this->destroyApplication(); + } + } + + protected function runGenerator($configFile, string $dbName) + { + $config = require $configFile; + $config['migrationPath'] = "@app/migrations_{$dbName}_db/"; + $generator = new ApiGenerator($config); + self::assertTrue($generator->validate(), print_r($generator->getErrors(), true)); + $codeFiles = $generator->generate(); + foreach ($codeFiles as $file) { + $file->save(); + } + } + + protected function changeDbToMysql() + { + Yii::$app->set('db', Yii::$app->mysql); + self::assertInstanceOf(MySqlSchema::class, Yii::$app->db->schema); + self::assertNotInstanceOf(MariaDbSchema::class, Yii::$app->db->schema); + self::assertNotInstanceOf(PgSqlSchema::class, Yii::$app->db->schema); + self::assertTrue(strpos(Yii::$app->db->schema->getServerVersion(), 'MariaDB') === false); + } + + protected function changeDbToMariadb() + { + Yii::$app->set('db', Yii::$app->maria); + self::assertInstanceOf(MariaDbSchema::class, Yii::$app->db->schema); + self::assertNotInstanceOf(PgSqlSchema::class, Yii::$app->db->schema); + self::assertTrue(strpos(Yii::$app->db->schema->getServerVersion(), 'MariaDB') !== false); + } + + protected function changeDbToPgsql() + { + Yii::$app->set('db', Yii::$app->pgsql); + self::assertNotInstanceOf(MariaDbSchema::class, Yii::$app->db->schema); + self::assertNotInstanceOf(MySqlSchema::class, Yii::$app->db->schema); + self::assertInstanceOf(PgSqlSchema::class, Yii::$app->db->schema); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 4ba19919..8aa54d81 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -7,3 +7,20 @@ Yii::setAlias('@specs', __DIR__ . '/specs'); Yii::setAlias('@fixtures', __DIR__ . '/fixtures'); Yii::setAlias('@tests', __DIR__); + +if (YII_DEBUG) { + function p($var = '', $vardump = false) + { + echo PHP_EOL."
".PHP_EOL; + !$vardump ? print_r($var) : var_dump($var); + echo PHP_EOL."".PHP_EOL; + } + + function pd($var = '', $vardump = false) + { + echo PHP_EOL."
".PHP_EOL; + !$vardump ? print_r($var) : var_dump($var); + echo PHP_EOL."".PHP_EOL; + die; + } +} diff --git a/tests/config/console.php b/tests/config/console.php index 2881f765..a562c131 100644 --- a/tests/config/console.php +++ b/tests/config/console.php @@ -1,8 +1,9 @@ 'cebe/yii2-openapi', 'timeZone' => 'UTC', 'basePath' => dirname(__DIR__) . '/tmp/docker_app', @@ -15,7 +16,32 @@ 'controllerMap' => [ 'migrate' => [ 'class' => \yii\console\controllers\MigrateController::class, - 'migrationPath' => dirname(__DIR__).'/migrations', + 'migrationPath' => [ + dirname(__DIR__).'/migrations', + ], + ], + // see usage instructions at https://www.yiiframework.com/doc/guide/2.0/en/db-migrations#separated-migrations + 'migrate-mysql' => [ // just for development of tests + 'class' => \yii\console\controllers\MigrateController::class, + 'migrationPath' => [ + dirname(__DIR__).'/migrations', + dirname(__DIR__).'/tmp/docker_app/migrations', + dirname(__DIR__).'/tmp/docker_app/migrations_mysql_db', + ], + ], + 'migrate-maria' => [ // just for development of tests + 'class' => \yii\console\controllers\MigrateController::class, + 'db' => 'maria', + 'migrationPath' => [ + dirname(__DIR__).'/tmp/docker_app/migrations_maria_db', + ], + ], + 'migrate-pgsql' => [ // just for development of tests + 'class' => \yii\console\controllers\MigrateController::class, + 'db' => 'pgsql', + 'migrationPath' => [ + dirname(__DIR__).'/tmp/docker_app/migrations_pgsql_db', + ], ], ], 'components' => [ @@ -42,6 +68,9 @@ 'password' => 'dbpass', 'charset' => 'utf8', 'tablePrefix'=>'itt_', + 'schemaMap' => [ + 'mysql' => \SamIT\Yii2\MariaDb\Schema::class + ] ], 'db'=>[ 'class' => \yii\db\Connection::class, @@ -53,3 +82,5 @@ ], ], ]; + +return $config; diff --git a/tests/fixtures/blog.php b/tests/fixtures/blog.php index b842707f..c9737bb9 100644 --- a/tests/fixtures/blog.php +++ b/tests/fixtures/blog.php @@ -19,10 +19,6 @@ ->setSize(200)->setRequired()->setFakerStub('substr($faker->safeEmail, 0, 200)'), 'password' => (new Attribute('password', ['phpType' => 'string', 'dbType' => 'string'])) ->setRequired()->setFakerStub('$faker->password'), - 'role' => (new Attribute('role', ['phpType' => 'string', 'dbType' => 'string'])) - ->setSize(20) - ->setDefault('reader') - ->setFakerStub('$faker->randomElement([\'admin\', \'editor\', \'reader\'])'), 'flags' => (new Attribute('flags', ['phpType'=>'int', 'dbType'=>'integer']))->setDefault(0)->setFakerStub ('$faker->numberBetween(0, 1000000)'), 'created_at' => (new Attribute('created_at', ['phpType' => 'string', 'dbType' => 'datetime'])) @@ -32,7 +28,7 @@ 'indexes' => [ 'users_email_key' => DbIndex::make('users', ['email'], null, true), 'users_username_key' => DbIndex::make('users', ['username'], null, true), - 'users_role_flags_index' => DbIndex::make('users', ['role', 'flags']) + 'users_flags_index' => DbIndex::make('users', ['flags']) ] ]), 'category' => new DbModel([ @@ -60,7 +56,7 @@ 'tableName' => 'blog_posts', 'description' => 'A blog post (uid used as pk for test purposes)', 'attributes' => [ - 'uid' => (new Attribute('uid', ['phpType' => 'string', 'dbType' => 'string'])) + 'uid' => (new Attribute('uid', ['phpType' => 'string', 'dbType' => 'varchar', 'xDbType' => 'varchar'])) ->setReadOnly()->setRequired()->setIsPrimary()->setSize(128) ->setFakerStub('substr($uniqueFaker->sha256, 0, 128)'), 'title' => (new Attribute('title', ['phpType' => 'string', 'dbType' => 'string'])) @@ -116,9 +112,9 @@ ->asReference('User') ->setDescription('The User') ->setFakerStub('$uniqueFaker->numberBetween(0, 1000000)'), - 'message' => (new Attribute('message', ['phpType' => 'array', 'dbType' => 'json'])) + 'message' => (new Attribute('message', ['phpType' => 'array', 'dbType' => 'json', 'xDbType' => 'json'])) ->setRequired()->setDefault([])->setFakerStub('[]'), - 'meta_data' => (new Attribute('meta_data', ['phpType' => 'array', 'dbType' => 'json'])) + 'meta_data' => (new Attribute('meta_data', ['phpType' => 'array', 'dbType' => 'json', 'xDbType' => 'json'])) ->setDefault([])->setFakerStub('[]'), 'created_at' => (new Attribute('created_at',['phpType' => 'int', 'dbType' => 'integer'])) ->setRequired()->setFakerStub('$faker->unixTime'), diff --git a/tests/migrations/m100000_000000_maria.php b/tests/migrations/m100000_000000_maria.php index 936f7c83..53dc91df 100644 --- a/tests/migrations/m100000_000000_maria.php +++ b/tests/migrations/m100000_000000_maria.php @@ -34,7 +34,6 @@ public function up() 'username' => $this->string(200)->notNull()->unique(), 'email' => $this->string(200)->notNull()->unique(), 'password' => $this->string()->notNull(), - 'role' => $this->string(20)->null()->defaultValue('reader'), 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP"), ]); diff --git a/tests/migrations/m100000_000000_mysql.php b/tests/migrations/m100000_000000_mysql.php index 5b249c06..d1d0c19a 100644 --- a/tests/migrations/m100000_000000_mysql.php +++ b/tests/migrations/m100000_000000_mysql.php @@ -33,7 +33,6 @@ public function up() 'username' => $this->string(200)->notNull()->unique(), 'email' => $this->string(200)->notNull()->unique(), 'password' => $this->string()->notNull(), - 'role' => $this->string(20)->null()->defaultValue('reader'), 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP"), ]); diff --git a/tests/migrations/m100000_000000_pgsql.php b/tests/migrations/m100000_000000_pgsql.php index 9efd59d3..0780107d 100644 --- a/tests/migrations/m100000_000000_pgsql.php +++ b/tests/migrations/m100000_000000_pgsql.php @@ -29,7 +29,6 @@ public function safeUp() 'username' => $this->string(200)->notNull()->unique(), 'email' => $this->string(200)->notNull()->unique(), 'password' => $this->string()->notNull(), - 'role' => $this->string(20)->null()->defaultValue('reader'), 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP"), ]); @@ -84,7 +83,6 @@ public function safeUp() 'int_minmax' => $this->integer()->null()->defaultValue(null), 'int_created_at' => $this->integer()->null()->defaultValue(null), 'int_simple' => $this->integer()->null()->defaultValue(null), - 'uuid' => 'uuid NULL DEFAULT NULL', 'str_text' => $this->text()->null()->defaultValue(null), 'str_varchar' => $this->string(100)->null()->defaultValue(null), 'str_date' => $this->date()->null()->defaultValue(null), @@ -92,7 +90,6 @@ public function safeUp() 'str_country' => $this->text()->null()->defaultValue(null), ]); - $this->execute('CREATE TYPE status_enum AS ENUM(\'active\', \'draft\')'); $this->createTable('{{%v3_pgcustom}}', [ 'id' => $this->bigPrimaryKey(), @@ -101,7 +98,6 @@ public function safeUp() 'json2' => $this->json()->null()->defaultValue(null), 'json3' => $this->json()->defaultValue(Json::encode(['foo' => 'bar', 'bar' => 'baz'])), 'json4' => "json DEFAULT '" . new Expression(Json::encode(['ffo' => 'bar'])) . "'", - 'status' => 'status_enum', 'search' => 'tsvector' ]); $columns = [ @@ -139,7 +135,6 @@ public function safeDown() $this->dropTable('{{%v2_users}}'); $this->dropTable('{{%v2_categories}}'); $this->dropTable('{{%v3_pgcustom}}'); - $this->execute('DROP TYPE status_enum'); $this->dropTable('{{%default_sizes}}'); } } diff --git a/tests/specs/blog.yaml b/tests/specs/blog.yaml index 7cbb1bfb..cd03139d 100644 --- a/tests/specs/blog.yaml +++ b/tests/specs/blog.yaml @@ -51,7 +51,7 @@ components: x-indexes: - unique:username - unique:email - - role,flags + - flags properties: id: type: integer @@ -66,12 +66,6 @@ components: password: type: string format: password - x-db-type: string - role: - type: string - maxLength: 20 - x-faker: "$faker->randomElement(['admin', 'editor', 'reader'])" - default: reader flags: type: integer default: 0 @@ -225,10 +219,10 @@ components: type: integer int_simple: type: integer - uuid: - type: string - x-db-type: UUID - x-faker: '$faker->uuid' + # uuid: + # type: string + # x-db-type: UUID # uuid is supported in only PgSQL + # x-faker: '$faker->uuid' str_text: type: string str_varchar: 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 f8cd744a..7afd35d4 100644 --- a/tests/specs/blog/migrations/m200000_000001_create_table_users.php +++ b/tests/specs/blog/migrations/m200000_000001_create_table_users.php @@ -12,18 +12,17 @@ public function up() 'username' => $this->string(200)->notNull(), 'email' => $this->string(200)->notNull(), 'password' => $this->string()->notNull(), - 'role' => $this->string(20)->null()->defaultValue("reader"), 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP"), ]); $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_flags_index', '{{%users}}', 'flags', false); } public function down() { - $this->dropIndex('users_role_flags_index', '{{%users}}'); + $this->dropIndex('users_flags_index', '{{%users}}'); $this->dropIndex('users_email_key', '{{%users}}'); $this->dropIndex('users_username_key', '{{%users}}'); $this->dropTable('{{%users}}'); 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 e9241403..64cce2eb 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 @@ -8,7 +8,7 @@ class m200000_000002_create_table_blog_posts extends \yii\db\Migration public function up() { $this->createTable('{{%blog_posts}}', [ - 'uid' => $this->string(128)->notNull(), + 0 => 'uid varchar(128) NOT NULL', 'title' => $this->string(255)->notNull(), 'slug' => $this->string(200)->null()->defaultValue(null), 'category_id' => $this->integer()->notNull(), diff --git a/tests/specs/blog/migrations/m200000_000003_create_table_fakerable.php b/tests/specs/blog/migrations/m200000_000003_create_table_fakerable.php index b86b5181..0f3eebad 100644 --- a/tests/specs/blog/migrations/m200000_000003_create_table_fakerable.php +++ b/tests/specs/blog/migrations/m200000_000003_create_table_fakerable.php @@ -18,12 +18,11 @@ public function up() 'int_minmax' => $this->integer()->null()->defaultValue(null), 'int_created_at' => $this->integer()->null()->defaultValue(null), 'int_simple' => $this->integer()->null()->defaultValue(null), - 'uuid' => 'uuid NULL DEFAULT NULL', - 'str_text' => $this->text()->null()->defaultValue(null), + 'str_text' => $this->text()->null(), 'str_varchar' => $this->string(100)->null()->defaultValue(null), 'str_date' => $this->date()->null()->defaultValue(null), 'str_datetime' => $this->timestamp()->null()->defaultValue(null), - 'str_country' => $this->text()->null()->defaultValue(null), + 'str_country' => $this->text()->null(), ]); } diff --git a/tests/specs/blog/migrations/m200000_000004_create_table_post_comments.php b/tests/specs/blog/migrations/m200000_000004_create_table_post_comments.php index c3e08fcd..c16766da 100644 --- a/tests/specs/blog/migrations/m200000_000004_create_table_post_comments.php +++ b/tests/specs/blog/migrations/m200000_000004_create_table_post_comments.php @@ -11,8 +11,8 @@ public function up() 'id' => $this->bigPrimaryKey(), 'post_id' => $this->string(128)->notNull(), 'author_id' => $this->integer()->notNull(), - 'message' => 'json NOT NULL DEFAULT \'[]\'', - 'meta_data' => 'json NOT NULL DEFAULT \'[]\'', + 0 => 'message json NOT NULL', + 1 => 'meta_data json NOT NULL', 'created_at' => $this->integer()->notNull(), ]); $this->addForeignKey('fk_post_comments_post_id_blog_posts_uid', '{{%post_comments}}', 'post_id', '{{%blog_posts}}', 'uid'); 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 f8cd744a..7afd35d4 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 @@ -12,18 +12,17 @@ public function up() 'username' => $this->string(200)->notNull(), 'email' => $this->string(200)->notNull(), 'password' => $this->string()->notNull(), - 'role' => $this->string(20)->null()->defaultValue("reader"), 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP"), ]); $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_flags_index', '{{%users}}', 'flags', false); } public function down() { - $this->dropIndex('users_role_flags_index', '{{%users}}'); + $this->dropIndex('users_flags_index', '{{%users}}'); $this->dropIndex('users_email_key', '{{%users}}'); $this->dropIndex('users_username_key', '{{%users}}'); $this->dropTable('{{%users}}'); 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 e9241403..64cce2eb 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 @@ -8,7 +8,7 @@ class m200000_000002_create_table_blog_posts extends \yii\db\Migration public function up() { $this->createTable('{{%blog_posts}}', [ - 'uid' => $this->string(128)->notNull(), + 0 => 'uid varchar(128) NOT NULL', 'title' => $this->string(255)->notNull(), 'slug' => $this->string(200)->null()->defaultValue(null), 'category_id' => $this->integer()->notNull(), diff --git a/tests/specs/blog/migrations_maria_db/m200000_000003_create_table_fakerable.php b/tests/specs/blog/migrations_maria_db/m200000_000003_create_table_fakerable.php index b86b5181..84f6247c 100644 --- a/tests/specs/blog/migrations_maria_db/m200000_000003_create_table_fakerable.php +++ b/tests/specs/blog/migrations_maria_db/m200000_000003_create_table_fakerable.php @@ -18,7 +18,6 @@ public function up() 'int_minmax' => $this->integer()->null()->defaultValue(null), 'int_created_at' => $this->integer()->null()->defaultValue(null), 'int_simple' => $this->integer()->null()->defaultValue(null), - 'uuid' => 'uuid NULL DEFAULT NULL', 'str_text' => $this->text()->null()->defaultValue(null), 'str_varchar' => $this->string(100)->null()->defaultValue(null), 'str_date' => $this->date()->null()->defaultValue(null), diff --git a/tests/specs/blog/migrations_maria_db/m200000_000004_create_table_post_comments.php b/tests/specs/blog/migrations_maria_db/m200000_000004_create_table_post_comments.php index c3e08fcd..d4971f43 100644 --- a/tests/specs/blog/migrations_maria_db/m200000_000004_create_table_post_comments.php +++ b/tests/specs/blog/migrations_maria_db/m200000_000004_create_table_post_comments.php @@ -11,8 +11,8 @@ public function up() 'id' => $this->bigPrimaryKey(), 'post_id' => $this->string(128)->notNull(), 'author_id' => $this->integer()->notNull(), - 'message' => 'json NOT NULL DEFAULT \'[]\'', - 'meta_data' => 'json NOT NULL DEFAULT \'[]\'', + 0 => 'message json NOT NULL DEFAULT \'[]\'', + 1 => 'meta_data json NOT NULL DEFAULT \'[]\'', 'created_at' => $this->integer()->notNull(), ]); $this->addForeignKey('fk_post_comments_post_id_blog_posts_uid', '{{%post_comments}}', 'post_id', '{{%blog_posts}}', 'uid'); 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 f8cd744a..7afd35d4 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 @@ -12,18 +12,17 @@ public function up() 'username' => $this->string(200)->notNull(), 'email' => $this->string(200)->notNull(), 'password' => $this->string()->notNull(), - 'role' => $this->string(20)->null()->defaultValue("reader"), 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP"), ]); $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_flags_index', '{{%users}}', 'flags', false); } public function down() { - $this->dropIndex('users_role_flags_index', '{{%users}}'); + $this->dropIndex('users_flags_index', '{{%users}}'); $this->dropIndex('users_email_key', '{{%users}}'); $this->dropIndex('users_username_key', '{{%users}}'); $this->dropTable('{{%users}}'); 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 e9241403..64cce2eb 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 @@ -8,7 +8,7 @@ class m200000_000002_create_table_blog_posts extends \yii\db\Migration public function up() { $this->createTable('{{%blog_posts}}', [ - 'uid' => $this->string(128)->notNull(), + 0 => 'uid varchar(128) NOT NULL', 'title' => $this->string(255)->notNull(), 'slug' => $this->string(200)->null()->defaultValue(null), 'category_id' => $this->integer()->notNull(), diff --git a/tests/specs/blog/migrations_mysql_db/m200000_000003_create_table_fakerable.php b/tests/specs/blog/migrations_mysql_db/m200000_000003_create_table_fakerable.php index 31485c92..0f3eebad 100644 --- a/tests/specs/blog/migrations_mysql_db/m200000_000003_create_table_fakerable.php +++ b/tests/specs/blog/migrations_mysql_db/m200000_000003_create_table_fakerable.php @@ -18,7 +18,6 @@ public function up() 'int_minmax' => $this->integer()->null()->defaultValue(null), 'int_created_at' => $this->integer()->null()->defaultValue(null), 'int_simple' => $this->integer()->null()->defaultValue(null), - 'uuid' => 'uuid NULL DEFAULT NULL', 'str_text' => $this->text()->null(), 'str_varchar' => $this->string(100)->null()->defaultValue(null), 'str_date' => $this->date()->null()->defaultValue(null), diff --git a/tests/specs/blog/migrations_mysql_db/m200000_000004_create_table_post_comments.php b/tests/specs/blog/migrations_mysql_db/m200000_000004_create_table_post_comments.php index f0e445e7..c16766da 100644 --- a/tests/specs/blog/migrations_mysql_db/m200000_000004_create_table_post_comments.php +++ b/tests/specs/blog/migrations_mysql_db/m200000_000004_create_table_post_comments.php @@ -11,8 +11,8 @@ public function up() 'id' => $this->bigPrimaryKey(), 'post_id' => $this->string(128)->notNull(), 'author_id' => $this->integer()->notNull(), - 'message' => 'json NOT NULL', - 'meta_data' => 'json NOT NULL', + 0 => 'message json NOT NULL', + 1 => 'meta_data json NOT NULL', 'created_at' => $this->integer()->notNull(), ]); $this->addForeignKey('fk_post_comments_post_id_blog_posts_uid', '{{%post_comments}}', 'post_id', '{{%blog_posts}}', 'uid'); 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 23fadf71..ceeb4494 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 @@ -12,18 +12,17 @@ public function safeUp() 'username' => $this->string(200)->notNull(), 'email' => $this->string(200)->notNull(), 'password' => $this->string()->notNull(), - 'role' => $this->string(20)->null()->defaultValue("reader"), 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP"), ]); $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_flags_index', '{{%users}}', 'flags', false); } public function safeDown() { - $this->dropIndex('users_role_flags_index', '{{%users}}'); + $this->dropIndex('users_flags_index', '{{%users}}'); $this->dropIndex('users_email_key', '{{%users}}'); $this->dropIndex('users_username_key', '{{%users}}'); $this->dropTable('{{%users}}'); 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 0b391456..780ed900 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 @@ -8,7 +8,7 @@ class m200000_000002_create_table_blog_posts extends \yii\db\Migration public function safeUp() { $this->createTable('{{%blog_posts}}', [ - 'uid' => $this->string(128)->notNull(), + 0 => 'uid varchar(128) NOT NULL', 'title' => $this->string(255)->notNull(), 'slug' => $this->string(200)->null()->defaultValue(null), 'category_id' => $this->integer()->notNull(), diff --git a/tests/specs/blog/migrations_pgsql_db/m200000_000003_create_table_fakerable.php b/tests/specs/blog/migrations_pgsql_db/m200000_000003_create_table_fakerable.php index 650fd2c5..a42b8954 100644 --- a/tests/specs/blog/migrations_pgsql_db/m200000_000003_create_table_fakerable.php +++ b/tests/specs/blog/migrations_pgsql_db/m200000_000003_create_table_fakerable.php @@ -18,7 +18,6 @@ public function safeUp() 'int_minmax' => $this->integer()->null()->defaultValue(null), 'int_created_at' => $this->integer()->null()->defaultValue(null), 'int_simple' => $this->integer()->null()->defaultValue(null), - 'uuid' => 'uuid NULL DEFAULT NULL', 'str_text' => $this->text()->null()->defaultValue(null), 'str_varchar' => $this->string(100)->null()->defaultValue(null), 'str_date' => $this->date()->null()->defaultValue(null), diff --git a/tests/specs/blog/migrations_pgsql_db/m200000_000004_create_table_post_comments.php b/tests/specs/blog/migrations_pgsql_db/m200000_000004_create_table_post_comments.php index 90b4e4c9..731ec10e 100644 --- a/tests/specs/blog/migrations_pgsql_db/m200000_000004_create_table_post_comments.php +++ b/tests/specs/blog/migrations_pgsql_db/m200000_000004_create_table_post_comments.php @@ -11,8 +11,8 @@ public function safeUp() 'id' => $this->bigPrimaryKey(), 'post_id' => $this->string(128)->notNull(), 'author_id' => $this->integer()->notNull(), - 'message' => 'json NOT NULL DEFAULT \'[]\'', - 'meta_data' => 'json NOT NULL DEFAULT \'[]\'', + 0 => 'message json NOT NULL DEFAULT \'[]\'', + 1 => 'meta_data json NOT NULL DEFAULT \'[]\'', 'created_at' => $this->integer()->notNull(), ]); $this->addForeignKey('fk_post_comments_post_id_blog_posts_uid', '{{%post_comments}}', 'post_id', '{{%blog_posts}}', 'uid'); diff --git a/tests/specs/blog/models/FakerableFaker.php b/tests/specs/blog/models/FakerableFaker.php index ddf88f6c..3e8a14bf 100644 --- a/tests/specs/blog/models/FakerableFaker.php +++ b/tests/specs/blog/models/FakerableFaker.php @@ -39,7 +39,6 @@ public function generateModel($attributes = []) $model->int_minmax = $faker->numberBetween(5, 25); $model->int_created_at = $faker->unixTime; $model->int_simple = $faker->numberBetween(0, 1000000); - $model->uuid = $faker->uuid; $model->str_text = $faker->sentence; $model->str_varchar = substr($faker->text(100), 0, 100); $model->str_date = $faker->dateTimeThisCentury->format('Y-m-d'); diff --git a/tests/specs/blog/models/UserFaker.php b/tests/specs/blog/models/UserFaker.php index d42fb940..943eea86 100644 --- a/tests/specs/blog/models/UserFaker.php +++ b/tests/specs/blog/models/UserFaker.php @@ -33,7 +33,6 @@ public function generateModel($attributes = []) $model->username = substr($faker->userName, 0, 200); $model->email = substr($faker->safeEmail, 0, 200); $model->password = $faker->password; - $model->role = $faker->randomElement(['admin', 'editor', 'reader']); $model->flags = $faker->numberBetween(0, 1000000); $model->created_at = $faker->dateTimeThisYear('now', 'UTC')->format(DATE_ATOM); if (!is_callable($attributes)) { diff --git a/tests/specs/blog/models/base/Fakerable.php b/tests/specs/blog/models/base/Fakerable.php index 7fd6eaa4..bfe5dd23 100644 --- a/tests/specs/blog/models/base/Fakerable.php +++ b/tests/specs/blog/models/base/Fakerable.php @@ -15,7 +15,6 @@ * @property int $int_minmax * @property int $int_created_at * @property int $int_simple - * @property string $uuid * @property string $str_text * @property string $str_varchar * @property string $str_date @@ -33,7 +32,7 @@ public static function tableName() public function rules() { return [ - 'trim' => [['uuid', 'str_text', 'str_varchar', 'str_date', 'str_datetime', 'str_country'], 'trim'], + 'trim' => [['str_text', 'str_varchar', 'str_date', 'str_datetime', 'str_country'], 'trim'], 'active_boolean' => [['active'], 'boolean'], 'floatval_double' => [['floatval'], 'double'], 'floatval_lim_double' => [['floatval_lim'], 'double', 'min' => 0, 'max' => 1], @@ -43,7 +42,6 @@ public function rules() 'int_minmax_integer' => [['int_minmax'], 'integer', 'min' => 5, 'max' => 25], 'int_created_at_integer' => [['int_created_at'], 'integer'], 'int_simple_integer' => [['int_simple'], 'integer'], - 'uuid_string' => [['uuid'], 'string'], 'str_text_string' => [['str_text'], 'string'], 'str_varchar_string' => [['str_varchar'], 'string', 'max' => 100], 'str_date_date' => [['str_date'], 'date'], diff --git a/tests/specs/blog/models/base/User.php b/tests/specs/blog/models/base/User.php index 614718da..bc2f5493 100644 --- a/tests/specs/blog/models/base/User.php +++ b/tests/specs/blog/models/base/User.php @@ -9,7 +9,6 @@ * @property string $username * @property string $email * @property string $password - * @property string $role * @property int $flags * @property string $created_at * @@ -24,7 +23,7 @@ public static function tableName() public function rules() { return [ - 'trim' => [['username', 'email', 'password', 'role', 'created_at'], 'trim'], + 'trim' => [['username', 'email', 'password', 'created_at'], 'trim'], 'required' => [['username', 'email', 'password'], 'required'], 'username_unique' => [['username'], 'unique'], 'email_unique' => [['email'], 'unique'], @@ -32,7 +31,6 @@ public function rules() 'email_string' => [['email'], 'string', 'max' => 200], 'email_email' => [['email'], 'email'], 'password_string' => [['password'], 'string'], - 'role_string' => [['role'], 'string', 'max' => 20], 'flags_integer' => [['flags'], 'integer'], 'created_at_datetime' => [['created_at'], 'datetime'], ]; diff --git a/tests/specs/blog_v2.yaml b/tests/specs/blog_v2.yaml index 1c1014b2..81076078 100644 --- a/tests/specs/blog_v2.yaml +++ b/tests/specs/blog_v2.yaml @@ -241,7 +241,7 @@ components: x-indexes: - unique:login - unique:email - - hash:role,flags + - hash:flags required: - id - login @@ -256,20 +256,14 @@ components: type: string email: type: string + x-db-type: varchar + maxLength: 255 password: type: string format: password - role: - type: string - x-db-type: enum - enum: - - admin - - editor - - reader - x-faker: "$faker->randomElement(['admin', 'editor', 'reader'])" flags: type: integer - default: "0" + default: 0 created_at: type: string format: date-time @@ -331,13 +325,12 @@ components: type: string minLength: 1 maxLength: 200 - lang: - type: string - x-db-type: enum - enum: - - ru - - eng - default: ru + # lang: + # type: string + # enum: + # - ru + # - eng + # default: ru category: $ref: "#/components/schemas/Category" active: @@ -379,7 +372,7 @@ components: type: string meta_data: type: string - example: "type=='ticket' && status=='closed'" + example: "type=='ticket'" minLength: 1 maxLength: 300 default: '' @@ -397,7 +390,7 @@ components: required: - id - name - - lang + # - lang properties: id: type: integer @@ -407,12 +400,11 @@ components: type: string x-db-type: VARCHAR maxLength: 100 - lang: - type: string - x-db-type: enum - enum: - - ru - - eng + # lang: + # type: string + # enum: + # - ru + # - eng posts: type: array items: diff --git a/tests/specs/blog_v2/migrations/m200000_000001_create_table_v2_users.php b/tests/specs/blog_v2/migrations/m200000_000001_create_table_v2_users.php index 5dbcb200..fd61f856 100644 --- a/tests/specs/blog_v2/migrations/m200000_000001_create_table_v2_users.php +++ b/tests/specs/blog_v2/migrations/m200000_000001_create_table_v2_users.php @@ -12,18 +12,17 @@ public function up() 'login' => $this->text()->notNull(), 'email' => $this->text()->notNull(), 'password' => $this->string()->notNull(), - 'role' => 'enum(\'admin\', \'editor\', \'reader\') NULL DEFAULT NULL', 'flags' => $this->integer()->null()->defaultValue(0), 'created_at' => $this->timestamp()->null()->defaultValue(null), ]); $this->createIndex('v2_users_login_key', '{{%v2_users}}', 'login', true); $this->createIndex('v2_users_email_key', '{{%v2_users}}', 'email', true); - $this->createIndex('v2_users_role_flags_hash_index', '{{%v2_users}}', 'role,flags', 'hash'); + $this->createIndex('v2_users_flags_hash_index', '{{%v2_users}}', 'flags', 'hash'); } public function down() { - $this->dropIndex('v2_users_role_flags_hash_index', '{{%v2_users}}'); + $this->dropIndex('v2_users_flags_hash_index', '{{%v2_users}}'); $this->dropIndex('v2_users_email_key', '{{%v2_users}}'); $this->dropIndex('v2_users_login_key', '{{%v2_users}}'); $this->dropTable('{{%v2_users}}'); diff --git a/tests/specs/blog_v2/migrations/m200000_000002_create_table_v2_posts.php b/tests/specs/blog_v2/migrations/m200000_000002_create_table_v2_posts.php index ba307de6..cf3ca27a 100644 --- a/tests/specs/blog_v2/migrations/m200000_000002_create_table_v2_posts.php +++ b/tests/specs/blog_v2/migrations/m200000_000002_create_table_v2_posts.php @@ -11,7 +11,6 @@ public function up() 'id' => $this->bigPrimaryKey(), 'title' => $this->string(255)->notNull(), 'slug' => $this->string(200)->null()->defaultValue(null), - 'lang' => 'enum(\'ru\', \'eng\') NULL DEFAULT \'ru\'', 'category_id' => $this->bigInteger()->notNull(), 'active' => $this->boolean()->notNull(), 'created_at' => $this->date()->null()->defaultValue(null), diff --git a/tests/specs/blog_v2/migrations/m200000_000003_create_table_v2_tags.php b/tests/specs/blog_v2/migrations/m200000_000003_create_table_v2_tags.php index 32aefd34..f27f11fe 100644 --- a/tests/specs/blog_v2/migrations/m200000_000003_create_table_v2_tags.php +++ b/tests/specs/blog_v2/migrations/m200000_000003_create_table_v2_tags.php @@ -10,7 +10,6 @@ public function up() $this->createTable('{{%v2_tags}}', [ 'id' => $this->bigPrimaryKey(), 'name' => $this->string(100)->notNull(), - 'lang' => 'enum(\'ru\', \'eng\') NOT NULL', ]); $this->createIndex('v2_tags_name_key', '{{%v2_tags}}', 'name', true); } diff --git a/tests/specs/blog_v2/migrations_maria_db/m200000_000000_change_table_v2_posts.php b/tests/specs/blog_v2/migrations_maria_db/m200000_000000_change_table_v2_posts.php index fcd1d212..c7f6a2a3 100644 --- a/tests/specs/blog_v2/migrations_maria_db/m200000_000000_change_table_v2_posts.php +++ b/tests/specs/blog_v2/migrations_maria_db/m200000_000000_change_table_v2_posts.php @@ -8,7 +8,6 @@ class m200000_000000_change_table_v2_posts extends \yii\db\Migration public function up() { $this->addColumn('{{%v2_posts}}', 'id', $this->bigPrimaryKey()); - $this->addColumn('{{%v2_posts}}', 'lang', "enum('ru', 'eng') NULL DEFAULT 'ru'"); $this->dropColumn('{{%v2_posts}}', 'uid'); $this->alterColumn('{{%v2_posts}}', 'active', $this->tinyInteger(1)->notNull()); $this->alterColumn('{{%v2_posts}}', 'category_id', $this->bigInteger()->notNull()); @@ -23,7 +22,6 @@ public function down() $this->alterColumn('{{%v2_posts}}', 'category_id', $this->integer(11)->notNull()); $this->alterColumn('{{%v2_posts}}', 'active', $this->tinyInteger(1)->notNull()->defaultValue(0)); $this->addColumn('{{%v2_posts}}', 'uid', $this->bigInteger(20)->notNull()); - $this->dropColumn('{{%v2_posts}}', 'lang'); $this->dropColumn('{{%v2_posts}}', 'id'); } } diff --git a/tests/specs/blog_v2/migrations_maria_db/m200000_000001_create_table_v2_tags.php b/tests/specs/blog_v2/migrations_maria_db/m200000_000001_create_table_v2_tags.php index b1f185d5..50ffc28d 100644 --- a/tests/specs/blog_v2/migrations_maria_db/m200000_000001_create_table_v2_tags.php +++ b/tests/specs/blog_v2/migrations_maria_db/m200000_000001_create_table_v2_tags.php @@ -9,8 +9,7 @@ public function up() { $this->createTable('{{%v2_tags}}', [ 'id' => $this->bigPrimaryKey(), - 'name' => $this->string(100)->notNull(), - 'lang' => 'enum(\'ru\', \'eng\') NOT NULL', + 0 => 'name varchar(100) NOT NULL', ]); $this->createIndex('v2_tags_name_key', '{{%v2_tags}}', 'name', true); } 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 6805ef31..59003105 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 @@ -10,21 +10,19 @@ public function up() $this->addColumn('{{%v2_users}}', 'login', $this->text()->notNull()); $this->dropColumn('{{%v2_users}}', 'username'); $this->alterColumn('{{%v2_users}}', 'created_at', $this->timestamp()->null()->defaultValue(null)); - $this->alterColumn('{{%v2_users}}', 'email', $this->string()->notNull()); - $this->alterColumn('{{%v2_users}}', 'role', "enum('admin', 'editor', 'reader') NULL DEFAULT NULL"); + $this->alterColumn('{{%v2_users}}', 'email', $this->string(255)->notNull()); $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_flags_hash_index', '{{%v2_users}}', 'flags', 'hash'); } public function down() { - $this->dropIndex('v2_users_role_flags_hash_index', '{{%v2_users}}'); + $this->dropIndex('v2_users_flags_hash_index', '{{%v2_users}}'); $this->dropIndex('v2_users_login_key', '{{%v2_users}}'); $this->createIndex('v2_users_username_key', '{{%v2_users}}', 'username', true); - $this->alterColumn('{{%v2_users}}', 'role', $this->string(20)->null()->defaultValue("reader")); $this->alterColumn('{{%v2_users}}', 'email', $this->string(200)->notNull()); - $this->alterColumn('{{%v2_users}}', 'created_at', $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP")); + $this->alterColumn('{{%v2_users}}', 'created_at', $this->timestamp()->null()->defaultExpression("current_timestamp()")); $this->addColumn('{{%v2_users}}', 'username', $this->string(200)->notNull()); $this->dropColumn('{{%v2_users}}', 'login'); } 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 ff8fbf4f..3f7fd1b3 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 @@ -22,8 +22,8 @@ public function down() { $this->dropForeignKey('fk_v2_comments_user_id_v2_users_id', '{{%v2_comments}}'); $this->dropForeignKey('fk_v2_comments_post_id_v2_posts_id', '{{%v2_comments}}'); - $this->alterColumn('{{%v2_comments}}', 'meta_data', $this->text()->notNull()->defaultValue("\'[]\'")); - $this->alterColumn('{{%v2_comments}}', 'message', $this->text()->notNull()->defaultValue("\'{}\'")); + $this->alterColumn('{{%v2_comments}}', 'meta_data', 'json NOT NULL DEFAULT \'[]\''); + $this->alterColumn('{{%v2_comments}}', 'message', 'json NOT NULL DEFAULT \'[]\''); $this->alterColumn('{{%v2_comments}}', 'created_at', $this->integer(11)->notNull()); $this->addColumn('{{%v2_comments}}', 'author_id', $this->integer(11)->notNull()); $this->dropColumn('{{%v2_comments}}', 'user_id'); diff --git a/tests/specs/blog_v2/migrations_mysql_db/m200000_000000_change_table_v2_posts.php b/tests/specs/blog_v2/migrations_mysql_db/m200000_000000_change_table_v2_posts.php index fcd1d212..c7f6a2a3 100644 --- a/tests/specs/blog_v2/migrations_mysql_db/m200000_000000_change_table_v2_posts.php +++ b/tests/specs/blog_v2/migrations_mysql_db/m200000_000000_change_table_v2_posts.php @@ -8,7 +8,6 @@ class m200000_000000_change_table_v2_posts extends \yii\db\Migration public function up() { $this->addColumn('{{%v2_posts}}', 'id', $this->bigPrimaryKey()); - $this->addColumn('{{%v2_posts}}', 'lang', "enum('ru', 'eng') NULL DEFAULT 'ru'"); $this->dropColumn('{{%v2_posts}}', 'uid'); $this->alterColumn('{{%v2_posts}}', 'active', $this->tinyInteger(1)->notNull()); $this->alterColumn('{{%v2_posts}}', 'category_id', $this->bigInteger()->notNull()); @@ -23,7 +22,6 @@ public function down() $this->alterColumn('{{%v2_posts}}', 'category_id', $this->integer(11)->notNull()); $this->alterColumn('{{%v2_posts}}', 'active', $this->tinyInteger(1)->notNull()->defaultValue(0)); $this->addColumn('{{%v2_posts}}', 'uid', $this->bigInteger(20)->notNull()); - $this->dropColumn('{{%v2_posts}}', 'lang'); $this->dropColumn('{{%v2_posts}}', 'id'); } } diff --git a/tests/specs/blog_v2/migrations_mysql_db/m200000_000001_create_table_v2_tags.php b/tests/specs/blog_v2/migrations_mysql_db/m200000_000001_create_table_v2_tags.php index b1f185d5..50ffc28d 100644 --- a/tests/specs/blog_v2/migrations_mysql_db/m200000_000001_create_table_v2_tags.php +++ b/tests/specs/blog_v2/migrations_mysql_db/m200000_000001_create_table_v2_tags.php @@ -9,8 +9,7 @@ public function up() { $this->createTable('{{%v2_tags}}', [ 'id' => $this->bigPrimaryKey(), - 'name' => $this->string(100)->notNull(), - 'lang' => 'enum(\'ru\', \'eng\') NOT NULL', + 0 => 'name varchar(100) NOT NULL', ]); $this->createIndex('v2_tags_name_key', '{{%v2_tags}}', 'name', true); } 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 6805ef31..db190e42 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 @@ -10,19 +10,17 @@ public function up() $this->addColumn('{{%v2_users}}', 'login', $this->text()->notNull()); $this->dropColumn('{{%v2_users}}', 'username'); $this->alterColumn('{{%v2_users}}', 'created_at', $this->timestamp()->null()->defaultValue(null)); - $this->alterColumn('{{%v2_users}}', 'email', $this->string()->notNull()); - $this->alterColumn('{{%v2_users}}', 'role', "enum('admin', 'editor', 'reader') NULL DEFAULT NULL"); + $this->alterColumn('{{%v2_users}}', 'email', $this->string(255)->notNull()); $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_flags_hash_index', '{{%v2_users}}', 'flags', 'hash'); } public function down() { - $this->dropIndex('v2_users_role_flags_hash_index', '{{%v2_users}}'); + $this->dropIndex('v2_users_flags_hash_index', '{{%v2_users}}'); $this->dropIndex('v2_users_login_key', '{{%v2_users}}'); $this->createIndex('v2_users_username_key', '{{%v2_users}}', 'username', true); - $this->alterColumn('{{%v2_users}}', 'role', $this->string(20)->null()->defaultValue("reader")); $this->alterColumn('{{%v2_users}}', 'email', $this->string(200)->notNull()); $this->alterColumn('{{%v2_users}}', 'created_at', $this->timestamp()->null()->defaultExpression("CURRENT_TIMESTAMP")); $this->addColumn('{{%v2_users}}', 'username', $this->string(200)->notNull()); 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 7168e063..a629bcab 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 @@ -13,7 +13,7 @@ public function up() $this->dropColumn('{{%v2_comments}}', 'author_id'); $this->alterColumn('{{%v2_comments}}', 'created_at', $this->timestamp()->notNull()); $this->alterColumn('{{%v2_comments}}', 'message', $this->text()->notNull()); - $this->alterColumn('{{%v2_comments}}', 'meta_data', $this->string(300)->null()); + $this->alterColumn('{{%v2_comments}}', 'meta_data', $this->string(300)->null()->defaultValue("")); $this->addForeignKey('fk_v2_comments_post_id_v2_posts_id', '{{%v2_comments}}', 'post_id', '{{%v2_posts}}', 'id'); $this->addForeignKey('fk_v2_comments_user_id_v2_users_id', '{{%v2_comments}}', 'user_id', '{{%v2_users}}', 'id'); } diff --git a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000000_change_table_v2_posts.php b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000000_change_table_v2_posts.php index 00a497b9..a03de14a 100644 --- a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000000_change_table_v2_posts.php +++ b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000000_change_table_v2_posts.php @@ -8,8 +8,6 @@ class m200000_000000_change_table_v2_posts extends \yii\db\Migration public function safeUp() { $this->addColumn('{{%v2_posts}}', 'id', $this->bigPrimaryKey()); - $this->execute('CREATE TYPE enum_lang AS ENUM(\'ru\', \'eng\')'); - $this->addColumn('{{%v2_posts}}', 'lang', 'enum_lang NULL DEFAULT \'ru\''); $this->dropColumn('{{%v2_posts}}', 'uid'); $this->alterColumn('{{%v2_posts}}', 'active', "DROP DEFAULT"); $this->alterColumn('{{%v2_posts}}', 'category_id', $this->bigInteger()->notNull()); @@ -23,8 +21,6 @@ public function safeDown() $this->alterColumn('{{%v2_posts}}', 'created_by_id', $this->integer()->null()); $this->alterColumn('{{%v2_posts}}', 'category_id', $this->integer()->notNull()); $this->addColumn('{{%v2_posts}}', 'uid', $this->bigInteger()->notNull()); - $this->dropColumn('{{%v2_posts}}', 'lang'); - $this->execute('DROP TYPE enum_lang'); $this->dropColumn('{{%v2_posts}}', 'id'); $this->alterColumn('{{%v2_posts}}', 'active', "SET DEFAULT 'f'"); } diff --git a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000001_create_table_v2_tags.php b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000001_create_table_v2_tags.php index cd0ff091..a8d8a98c 100644 --- a/tests/specs/blog_v2/migrations_pgsql_db/m200000_000001_create_table_v2_tags.php +++ b/tests/specs/blog_v2/migrations_pgsql_db/m200000_000001_create_table_v2_tags.php @@ -7,11 +7,9 @@ class m200000_000001_create_table_v2_tags extends \yii\db\Migration { public function safeUp() { - $this->execute('CREATE TYPE enum_lang AS ENUM(\'ru\', \'eng\')'); $this->createTable('{{%v2_tags}}', [ 'id' => $this->bigPrimaryKey(), - 'name' => $this->string(100)->notNull(), - 'lang' => 'enum_lang NOT NULL', + 0 => 'name varchar(100) NOT NULL', ]); $this->createIndex('v2_tags_name_key', '{{%v2_tags}}', 'name', true); } @@ -19,7 +17,6 @@ public function safeUp() public function safeDown() { $this->dropIndex('v2_tags_name_key', '{{%v2_tags}}'); - $this->execute('DROP TYPE enum_lang'); $this->dropTable('{{%v2_tags}}'); } } 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 9f1b9769..8dbf692d 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 @@ -7,29 +7,23 @@ class m200000_000004_change_table_v2_users extends \yii\db\Migration { public function safeUp() { - $this->execute('CREATE TYPE enum_role AS ENUM(\'admin\', \'editor\', \'reader\')'); $this->addColumn('{{%v2_users}}', 'login', $this->text()->notNull()); $this->dropColumn('{{%v2_users}}', 'username'); $this->alterColumn('{{%v2_users}}', 'created_at', "DROP DEFAULT"); - $this->alterColumn('{{%v2_users}}', 'email', $this->text()->notNull()); - $this->alterColumn('{{%v2_users}}', 'role', 'enum_role USING role::enum_role'); - $this->alterColumn('{{%v2_users}}', 'role', "DROP DEFAULT"); + $this->db->createCommand('ALTER TABLE {{%v2_users}} ALTER COLUMN email SET DATA TYPE varchar(255)')->execute(); $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_flags_hash_index', '{{%v2_users}}', 'flags', 'hash'); } public function safeDown() { - $this->dropIndex('v2_users_role_flags_hash_index', '{{%v2_users}}'); + $this->dropIndex('v2_users_flags_hash_index', '{{%v2_users}}'); $this->dropIndex('v2_users_login_key', '{{%v2_users}}'); $this->createIndex('v2_users_username_key', '{{%v2_users}}', 'username', true); - $this->alterColumn('{{%v2_users}}', 'role', 'varchar(20) NULL USING "role"::varchar'); $this->alterColumn('{{%v2_users}}', 'email', $this->string(200)->notNull()); $this->addColumn('{{%v2_users}}', 'username', $this->string(200)->notNull()); $this->dropColumn('{{%v2_users}}', 'login'); $this->alterColumn('{{%v2_users}}', 'created_at', "SET DEFAULT CURRENT_TIMESTAMP"); - $this->alterColumn('{{%v2_users}}', 'role', "SET DEFAULT 'reader'"); - $this->execute('DROP TYPE enum_role'); } } diff --git a/tests/specs/blog_v2/models/PostFaker.php b/tests/specs/blog_v2/models/PostFaker.php index a1e8eb81..6fc36c0e 100644 --- a/tests/specs/blog_v2/models/PostFaker.php +++ b/tests/specs/blog_v2/models/PostFaker.php @@ -32,7 +32,6 @@ public function generateModel($attributes = []) //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->title = substr($faker->sentence, 0, 255); $model->slug = substr($uniqueFaker->slug, 0, 200); - $model->lang = $faker->randomElement(['ru','eng']); $model->active = $faker->boolean; $model->created_at = $faker->dateTimeThisCentury->format('Y-m-d'); if (!is_callable($attributes)) { diff --git a/tests/specs/blog_v2/models/TagFaker.php b/tests/specs/blog_v2/models/TagFaker.php index 8e0af887..6308fa68 100644 --- a/tests/specs/blog_v2/models/TagFaker.php +++ b/tests/specs/blog_v2/models/TagFaker.php @@ -31,7 +31,6 @@ public function generateModel($attributes = []) $model = new Tag(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = substr($faker->text(100), 0, 100); - $model->lang = $faker->randomElement(['ru','eng']); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { diff --git a/tests/specs/blog_v2/models/UserFaker.php b/tests/specs/blog_v2/models/UserFaker.php index 423ca4f0..9810c37a 100644 --- a/tests/specs/blog_v2/models/UserFaker.php +++ b/tests/specs/blog_v2/models/UserFaker.php @@ -31,9 +31,8 @@ public function generateModel($attributes = []) $model = new User(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->login = $faker->userName; - $model->email = $faker->safeEmail; + $model->email = substr($faker->safeEmail, 0, 255); $model->password = $faker->password; - $model->role = $faker->randomElement(['admin', 'editor', 'reader']); $model->flags = $faker->numberBetween(0, 1000000); $model->created_at = $faker->dateTimeThisYear('now', 'UTC')->format(DATE_ATOM); if (!is_callable($attributes)) { diff --git a/tests/specs/blog_v2/models/base/Post.php b/tests/specs/blog_v2/models/base/Post.php index aec86342..3599eb90 100644 --- a/tests/specs/blog_v2/models/base/Post.php +++ b/tests/specs/blog_v2/models/base/Post.php @@ -8,7 +8,6 @@ * @property int $id * @property string $title * @property string $slug - * @property string $lang * @property int $category_id Category of posts * @property bool $active * @property string $created_at @@ -29,7 +28,7 @@ public static function tableName() public function rules() { return [ - 'trim' => [['title', 'slug', 'lang', 'created_at'], 'trim'], + 'trim' => [['title', 'slug', 'created_at'], 'trim'], 'required' => [['title', 'category_id', 'active'], 'required'], 'category_id_integer' => [['category_id'], 'integer'], 'category_id_exist' => [['category_id'], 'exist', 'targetRelation' => 'Category'], @@ -38,8 +37,6 @@ public function rules() 'title_unique' => [['title'], 'unique'], 'title_string' => [['title'], 'string', 'max' => 255], 'slug_string' => [['slug'], 'string', 'min' => 1, 'max' => 200], - 'lang_string' => [['lang'], 'string'], - 'lang_in' => [['lang'], 'in', 'range' => ['ru', 'eng']], 'active_boolean' => [['active'], 'boolean'], 'created_at_date' => [['created_at'], 'date'], ]; diff --git a/tests/specs/blog_v2/models/base/Tag.php b/tests/specs/blog_v2/models/base/Tag.php index 2d0e7d6c..761507a8 100644 --- a/tests/specs/blog_v2/models/base/Tag.php +++ b/tests/specs/blog_v2/models/base/Tag.php @@ -7,7 +7,6 @@ * * @property int $id * @property string $name - * @property string $lang * * @property array|\app\models\Post[] $posts */ @@ -21,12 +20,10 @@ public static function tableName() public function rules() { return [ - 'trim' => [['name', 'lang'], 'trim'], - 'required' => [['name', 'lang'], 'required'], + 'trim' => [['name'], 'trim'], + 'required' => [['name'], 'required'], 'name_unique' => [['name'], 'unique'], 'name_string' => [['name'], 'string', 'max' => 100], - 'lang_string' => [['lang'], 'string'], - 'lang_in' => [['lang'], 'in', 'range' => ['ru', 'eng']], ]; } diff --git a/tests/specs/blog_v2/models/base/User.php b/tests/specs/blog_v2/models/base/User.php index 747808d1..3470798f 100644 --- a/tests/specs/blog_v2/models/base/User.php +++ b/tests/specs/blog_v2/models/base/User.php @@ -9,7 +9,6 @@ * @property string $login * @property string $email * @property string $password - * @property string $role * @property int $flags * @property string $created_at * @@ -24,16 +23,14 @@ public static function tableName() public function rules() { return [ - 'trim' => [['login', 'email', 'password', 'role', 'created_at'], 'trim'], + 'trim' => [['login', 'email', 'password', 'created_at'], 'trim'], 'required' => [['login', 'email', 'password'], 'required'], 'login_unique' => [['login'], 'unique'], 'email_unique' => [['email'], 'unique'], 'login_string' => [['login'], 'string'], - 'email_string' => [['email'], 'string'], + 'email_string' => [['email'], 'string', 'max' => 255], 'email_email' => [['email'], 'email'], 'password_string' => [['password'], 'string'], - 'role_string' => [['role'], 'string'], - 'role_in' => [['role'], 'in', 'range' => ['admin', 'editor', 'reader']], 'flags_integer' => [['flags'], 'integer'], 'created_at_datetime' => [['created_at'], 'datetime'], ]; diff --git a/tests/specs/many2many/migrations/m200000_000006_create_table_posts_gallery.php b/tests/specs/many2many/migrations/m200000_000006_create_table_posts_gallery.php index 4fb773ce..aeb6c64f 100644 --- a/tests/specs/many2many/migrations/m200000_000006_create_table_posts_gallery.php +++ b/tests/specs/many2many/migrations/m200000_000006_create_table_posts_gallery.php @@ -10,7 +10,7 @@ public function up() $this->createTable('{{%posts_gallery}}', [ 'image_id' => $this->bigInteger()->null()->defaultValue(null), 'article_id' => $this->bigInteger()->null()->defaultValue(null), - 'is_cover' => $this->text()->null()->defaultValue(null), + 'is_cover' => $this->text()->null(), ]); $this->addPrimaryKey('pk_image_id_article_id', '{{%posts_gallery}}', 'image_id,article_id'); $this->addForeignKey('fk_posts_gallery_image_id_photo_id', '{{%posts_gallery}}', 'image_id', '{{%photo}}', 'id'); diff --git a/tests/specs/menu/migrations/m200000_000000_create_table_menus.php b/tests/specs/menu/migrations/m200000_000000_create_table_menus.php index 66d43585..03cde247 100644 --- a/tests/specs/menu/migrations/m200000_000000_create_table_menus.php +++ b/tests/specs/menu/migrations/m200000_000000_create_table_menus.php @@ -5,19 +5,19 @@ */ class m200000_000000_create_table_menus extends \yii\db\Migration { - public function up() + public function safeUp() { $this->createTable('{{%menus}}', [ 'id' => $this->bigPrimaryKey(), 'name' => $this->string(100)->notNull(), 'parent_id' => $this->bigInteger()->null()->defaultValue(null), - 'args' => 'text[] NULL DEFAULT \'{"foo","bar","baz"}\'', - 'kwargs' => 'json NOT NULL DEFAULT \'[{"foo":"bar"},{"buzz":"fizz"}]\'', + 0 => 'args text[] NULL DEFAULT \'{"foo","bar","baz"}\'', + 1 => 'kwargs json NOT NULL DEFAULT \'[{"foo":"bar"},{"buzz":"fizz"}]\'', ]); $this->addForeignKey('fk_menus_parent_id_menus_id', '{{%menus}}', 'parent_id', '{{%menus}}', 'id'); } - public function down() + public function safeDown() { $this->dropForeignKey('fk_menus_parent_id_menus_id', '{{%menus}}'); $this->dropTable('{{%menus}}'); diff --git a/tests/specs/petstore_jsonapi/migrations/m200000_000000_create_table_pets.php b/tests/specs/petstore_jsonapi/migrations/m200000_000000_create_table_pets.php index f712c5ba..4d4c3bff 100644 --- a/tests/specs/petstore_jsonapi/migrations/m200000_000000_create_table_pets.php +++ b/tests/specs/petstore_jsonapi/migrations/m200000_000000_create_table_pets.php @@ -10,7 +10,7 @@ public function up() $this->createTable('{{%pets}}', [ 'id' => $this->bigPrimaryKey(), 'name' => $this->text()->notNull(), - 'tag' => $this->text()->null()->defaultValue(null), + 'tag' => $this->text()->null(), ]); } diff --git a/tests/specs/petstore_xtable/migrations/m200000_000000_create_table_pets.php b/tests/specs/petstore_xtable/migrations/m200000_000000_create_table_pets.php index f712c5ba..4d4c3bff 100644 --- a/tests/specs/petstore_xtable/migrations/m200000_000000_create_table_pets.php +++ b/tests/specs/petstore_xtable/migrations/m200000_000000_create_table_pets.php @@ -10,7 +10,7 @@ public function up() $this->createTable('{{%pets}}', [ 'id' => $this->bigPrimaryKey(), 'name' => $this->text()->notNull(), - 'tag' => $this->text()->null()->defaultValue(null), + 'tag' => $this->text()->null(), ]); } diff --git a/tests/specs/postgres_custom.yaml b/tests/specs/postgres_custom.yaml index 27ab3a4d..fce6664c 100644 --- a/tests/specs/postgres_custom.yaml +++ b/tests/specs/postgres_custom.yaml @@ -35,7 +35,7 @@ components: Custom: x-table: v3_pgcustom x-indexes: - - "gin(to_tsvector('english', status)):search" + - "gin(to_tsvector('english')):search" required: - id properties: @@ -64,13 +64,12 @@ components: type: array x-db-type: json default: '{"foo": "bar", "bar": "baz"}' - status: - type: string - x-db-type: enum - default: draft - enum: - - active - - draft + # status: + # type: string + # default: draft + # enum: + # - active + # - draft search: type: string x-db-type: tsvector diff --git a/tests/specs/postgres_custom/migrations/m200000_000000_create_table_v3_pgcustom.php b/tests/specs/postgres_custom/migrations/m200000_000000_create_table_v3_pgcustom.php index fbf76227..6855df2a 100644 --- a/tests/specs/postgres_custom/migrations/m200000_000000_create_table_v3_pgcustom.php +++ b/tests/specs/postgres_custom/migrations/m200000_000000_create_table_v3_pgcustom.php @@ -14,10 +14,9 @@ public function up() 'json2' => 'json NOT NULL DEFAULT \'[]\'', 'json3' => 'json NOT NULL DEFAULT \'[{"foo":"foobar"},{"xxx":"yyy"}]\'', 'json4' => 'json NOT NULL DEFAULT \'{"foo":"bar","bar":"baz"}\'', - 'status' => 'enum(\'active\', \'draft\') NULL DEFAULT \'draft\'', 'search' => 'tsvector NULL', ]); - $this->createIndex('v3_pgcustom_search_gin_index', '{{%v3_pgcustom}}', 'search', 'gin(to_tsvector(\'english\', status))'); + $this->createIndex('v3_pgcustom_search_gin_index', '{{%v3_pgcustom}}', 'search', 'gin(to_tsvector(\'english\'))'); } public function down() diff --git a/tests/specs/postgres_custom/migrations_pgsql_db/m200000_000000_change_table_v3_pgcustom.php b/tests/specs/postgres_custom/migrations_pgsql_db/m200000_000000_change_table_v3_pgcustom.php index 6635ca3d..f0608474 100644 --- a/tests/specs/postgres_custom/migrations_pgsql_db/m200000_000000_change_table_v3_pgcustom.php +++ b/tests/specs/postgres_custom/migrations_pgsql_db/m200000_000000_change_table_v3_pgcustom.php @@ -15,7 +15,7 @@ public function safeUp() $this->alterColumn('{{%v3_pgcustom}}', 'json3', "SET DEFAULT '[{\"foo\":\"foobar\"},{\"xxx\":\"yyy\"}]'"); $this->alterColumn('{{%v3_pgcustom}}', 'json4', "SET NOT NULL"); $this->alterColumn('{{%v3_pgcustom}}', 'json4', "SET DEFAULT '{\"foo\":\"bar\",\"bar\":\"baz\"}'"); - $this->createIndex('v3_pgcustom_search_gin_index', '{{%v3_pgcustom}}', 'search', 'gin(to_tsvector(\'english\', status))'); + $this->createIndex('v3_pgcustom_search_gin_index', '{{%v3_pgcustom}}', 'search', 'gin(to_tsvector(\'english\'))'); } public function safeDown() diff --git a/tests/specs/postgres_custom/models/CustomFaker.php b/tests/specs/postgres_custom/models/CustomFaker.php index 6c7de598..373217df 100644 --- a/tests/specs/postgres_custom/models/CustomFaker.php +++ b/tests/specs/postgres_custom/models/CustomFaker.php @@ -35,7 +35,6 @@ public function generateModel($attributes = []) $model->json2 = []; $model->json3 = []; $model->json4 = []; - $model->status = $faker->randomElement(['active','draft']); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { diff --git a/tests/specs/postgres_custom/models/base/Custom.php b/tests/specs/postgres_custom/models/base/Custom.php index e19f3700..9190b60a 100644 --- a/tests/specs/postgres_custom/models/base/Custom.php +++ b/tests/specs/postgres_custom/models/base/Custom.php @@ -11,7 +11,6 @@ * @property array $json2 * @property array $json3 * @property array $json4 - * @property string $status * @property string $search * */ @@ -25,10 +24,7 @@ public static function tableName() public function rules() { return [ - 'trim' => [['status'], 'trim'], 'num_integer' => [['num'], 'integer'], - 'status_string' => [['status'], 'string'], - 'status_in' => [['status'], 'in', 'range' => ['active', 'draft']], 'safe' => [['json1', 'json2', 'json3', 'json4'], 'safe'], ]; } diff --git a/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..9c002bea --- /dev/null +++ b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,62 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar(255) NULL DEFAULT NULL', + 1 => 'varchar_col varchar(132) NULL DEFAULT NULL', + 2 => 'text_col text NULL DEFAULT NULL', + 3 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 4 => 'char_4_col char(4) NULL DEFAULT NULL', + 5 => 'char_5_col char NULL DEFAULT NULL', + 6 => 'char_6_col char NOT NULL', + 7 => 'char_7_col char(6) NOT NULL', + 8 => 'char_8_col char NULL DEFAULT \'d\'', + 9 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 10 => 'varbinary_col varbinary(5) NULL DEFAULT NULL', + 11 => 'blob_col blob NULL DEFAULT NULL', + 12 => 'bit_col bit NULL DEFAULT NULL', + 13 => 'bit_2 bit(1) NULL DEFAULT NULL', + 14 => 'bit_3 bit(64) NULL DEFAULT NULL', + 15 => 'ti tinyint NULL DEFAULT NULL', + 16 => 'ti_2 tinyint(1) NULL DEFAULT NULL', + 17 => 'ti_3 tinyint(2) NULL DEFAULT NULL', + 18 => 'si_col smallint NULL DEFAULT NULL', + 19 => 'si_col_2 smallint unsigned zerofill NULL DEFAULT NULL', + 20 => 'mi mediumint(10) unsigned zerofill comment "comment" NULL DEFAULT 7', + 21 => 'bi bigint NULL DEFAULT NULL', + 22 => 'int_col int NULL DEFAULT NULL', + 23 => 'int_col_2 integer NULL DEFAULT NULL', + 24 => 'numeric_col numeric NULL DEFAULT NULL', + 25 => 'float_col float NULL DEFAULT NULL', + 26 => 'float_2 float(10, 2) NULL DEFAULT NULL', + 27 => 'float_3 float(8) NULL DEFAULT NULL', + 28 => 'double_col double NULL DEFAULT NULL', + 29 => 'double_p double precision(10,2) NULL DEFAULT NULL', + 30 => 'double_p_2 double precision NULL DEFAULT NULL', + 31 => 'real_col real NULL DEFAULT NULL', + 32 => 'date_col date NULL DEFAULT NULL', + 33 => 'time_col time NULL DEFAULT NULL', + 34 => 'datetime_col datetime NULL DEFAULT NULL', + 35 => 'timestamp_col timestamp NULL DEFAULT NULL', + 36 => 'year_col year NULL DEFAULT NULL', + 37 => 'json_col json NOT NULL', + 38 => 'json_col_def json NOT NULL DEFAULT \'[]\'', + 39 => 'json_col_def_2 json NOT NULL DEFAULT \'[]\'', + 40 => 'blob_def blob NULL DEFAULT \'the blob\'', + 41 => 'text_def text NULL DEFAULT \'the text\'', + 42 => 'json_def json NOT NULL DEFAULT \'{"a":"b"}\'', + ]); + } + + public function down() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000001_change_table_editcolumns.php b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000001_change_table_editcolumns.php new file mode 100644 index 00000000..3670ecc6 --- /dev/null +++ b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000001_change_table_editcolumns.php @@ -0,0 +1,35 @@ +db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN first_name varchar(255) NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN json_col_def_n json NOT NULL DEFAULT \'[]\'')->execute(); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN json_col_def_n_2 json NOT NULL DEFAULT \'[]\'')->execute(); + $this->alterColumn('{{%editcolumns}}', 'dec_col', $this->decimal(12,2)->null()->defaultValue("3.14")); + $this->alterColumn('{{%editcolumns}}', 'json_col', $this->text()->notNull()->defaultValue("fox jumps over dog")); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', 'json NOT NULL DEFAULT \'[]\''); + $this->alterColumn('{{%editcolumns}}', 'name', $this->string(255)->notNull()->defaultValue("Horse-2")); + $this->alterColumn('{{%editcolumns}}', 'numeric_col', $this->double()->null()->defaultValue(null)); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', $this->string(255)->notNull()); + $this->alterColumn('{{%editcolumns}}', 'string_col', $this->text()->null()->defaultValue(null)); + } + + public function down() + { + $this->alterColumn('{{%editcolumns}}', 'string_col', $this->string(255)->notNull()); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', $this->string(255)->null()->defaultValue("hi there")); + $this->alterColumn('{{%editcolumns}}', 'numeric_col', $this->integer(11)->null()->defaultValue(null)); + $this->alterColumn('{{%editcolumns}}', 'name', $this->string(255)->notNull()->defaultValue("Horse")); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', 'json NULL DEFAULT NULL'); + $this->alterColumn('{{%editcolumns}}', 'json_col', 'json NULL DEFAULT NULL'); + $this->alterColumn('{{%editcolumns}}', 'dec_col', $this->decimal(12,4)->null()->defaultValue(null)); + $this->dropColumn('{{%editcolumns}}', 'json_col_def_n_2'); + $this->dropColumn('{{%editcolumns}}', 'json_col_def_n'); + $this->dropColumn('{{%editcolumns}}', 'first_name'); + } +} diff --git a/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000002_create_table_newcolumns.php b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000002_create_table_newcolumns.php new file mode 100644 index 00000000..a53b1995 --- /dev/null +++ b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000002_create_table_newcolumns.php @@ -0,0 +1,26 @@ +createTable('{{%newcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL', + 'last_name' => $this->text()->null()->defaultValue(null), + 1 => 'dec_col decimal(12,4) NULL DEFAULT NULL', + 2 => 'json_col json NOT NULL', + 3 => 'varchar_col varchar(5) NULL DEFAULT NULL', + 4 => 'numeric_col double precision NULL DEFAULT NULL', + 5 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + ]); + } + + public function down() + { + $this->dropTable('{{%newcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..4d1b1590 --- /dev/null +++ b/tests/specs/x_db_type/edit_column/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col integer primary key auto_increment NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null()->defaultValue("4 leg"), + 2 => 'new_col varchar(17) NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar(9) NULL DEFAULT NULL', + 8 => 'col_10 varchar(10) NULL DEFAULT NULL', + 9 => 'col_11 text NULL DEFAULT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..2cda660f --- /dev/null +++ b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,62 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar(255) NULL DEFAULT NULL', + 1 => 'varchar_col varchar(132) NULL DEFAULT NULL', + 2 => 'text_col text NULL', + 3 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 4 => 'char_4_col char(4) NULL DEFAULT NULL', + 5 => 'char_5_col char NULL DEFAULT NULL', + 6 => 'char_6_col char NOT NULL', + 7 => 'char_7_col char(6) NOT NULL', + 8 => 'char_8_col char NULL DEFAULT \'d\'', + 9 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 10 => 'varbinary_col varbinary(5) NULL DEFAULT NULL', + 11 => 'blob_col blob NULL', + 12 => 'bit_col bit NULL DEFAULT NULL', + 13 => 'bit_2 bit(1) NULL DEFAULT NULL', + 14 => 'bit_3 bit(64) NULL DEFAULT NULL', + 15 => 'ti tinyint NULL DEFAULT NULL', + 16 => 'ti_2 tinyint(1) NULL DEFAULT NULL', + 17 => 'ti_3 tinyint(2) NULL DEFAULT NULL', + 18 => 'si_col smallint NULL DEFAULT NULL', + 19 => 'si_col_2 smallint unsigned zerofill NULL DEFAULT NULL', + 20 => 'mi mediumint(10) unsigned zerofill comment "comment" NULL DEFAULT 7', + 21 => 'bi bigint NULL DEFAULT NULL', + 22 => 'int_col int NULL DEFAULT NULL', + 23 => 'int_col_2 integer NULL DEFAULT NULL', + 24 => 'numeric_col numeric NULL DEFAULT NULL', + 25 => 'float_col float NULL DEFAULT NULL', + 26 => 'float_2 float(10, 2) NULL DEFAULT NULL', + 27 => 'float_3 float(8) NULL DEFAULT NULL', + 28 => 'double_col double NULL DEFAULT NULL', + 29 => 'double_p double precision(10,2) NULL DEFAULT NULL', + 30 => 'double_p_2 double precision NULL DEFAULT NULL', + 31 => 'real_col real NULL DEFAULT NULL', + 32 => 'date_col date NULL DEFAULT NULL', + 33 => 'time_col time NULL DEFAULT NULL', + 34 => 'datetime_col datetime NULL DEFAULT NULL', + 35 => 'timestamp_col timestamp NULL DEFAULT NULL', + 36 => 'year_col year NULL DEFAULT NULL', + 37 => 'json_col json NOT NULL', + 38 => 'json_col_def json NOT NULL', + 39 => 'json_col_def_2 json NOT NULL', + 40 => 'blob_def blob NULL', + 41 => 'text_def text NULL', + 42 => 'json_def json NOT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000001_change_table_editcolumns.php b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000001_change_table_editcolumns.php new file mode 100644 index 00000000..d116027d --- /dev/null +++ b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000001_change_table_editcolumns.php @@ -0,0 +1,35 @@ +db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN first_name varchar(255) NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN json_col_def_n json NOT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN json_col_def_n_2 json NOT NULL')->execute(); + $this->alterColumn('{{%editcolumns}}', 'dec_col', $this->decimal(12,2)->null()->defaultValue("3.14")); + $this->alterColumn('{{%editcolumns}}', 'json_col', $this->text()->notNull()); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', 'json NOT NULL'); + $this->alterColumn('{{%editcolumns}}', 'name', $this->string(255)->notNull()->defaultValue("Horse-2")); + $this->alterColumn('{{%editcolumns}}', 'numeric_col', $this->double()->null()->defaultValue(null)); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', $this->string(255)->notNull()); + $this->alterColumn('{{%editcolumns}}', 'string_col', $this->text()->null()); + } + + public function down() + { + $this->alterColumn('{{%editcolumns}}', 'string_col', $this->string(255)->notNull()); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', $this->string(255)->null()->defaultValue("hi there")); + $this->alterColumn('{{%editcolumns}}', 'numeric_col', $this->integer(11)->null()->defaultValue(null)); + $this->alterColumn('{{%editcolumns}}', 'name', $this->string(255)->notNull()->defaultValue("Horse")); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', 'json NULL'); + $this->alterColumn('{{%editcolumns}}', 'json_col', 'json NULL'); + $this->alterColumn('{{%editcolumns}}', 'dec_col', $this->decimal(12,4)->null()->defaultValue(null)); + $this->dropColumn('{{%editcolumns}}', 'json_col_def_n_2'); + $this->dropColumn('{{%editcolumns}}', 'json_col_def_n'); + $this->dropColumn('{{%editcolumns}}', 'first_name'); + } +} diff --git a/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000002_create_table_newcolumns.php b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000002_create_table_newcolumns.php new file mode 100644 index 00000000..aacd206c --- /dev/null +++ b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000002_create_table_newcolumns.php @@ -0,0 +1,26 @@ +createTable('{{%newcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL', + 'last_name' => $this->text()->null(), + 1 => 'dec_col decimal(12,4) NULL DEFAULT NULL', + 2 => 'json_col json NOT NULL', + 3 => 'varchar_col varchar(5) NULL DEFAULT NULL', + 4 => 'numeric_col double precision NULL DEFAULT NULL', + 5 => 'json_col_def_n json NOT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%newcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..aeed5fe1 --- /dev/null +++ b/tests/specs/x_db_type/edit_column/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col integer primary key auto_increment NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null(), + 2 => 'new_col varchar(17) NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar(9) NULL DEFAULT NULL', + 8 => 'col_10 varchar(10) NULL DEFAULT NULL', + 9 => 'col_11 text NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..53498798 --- /dev/null +++ b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,112 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar NULL DEFAULT NULL', + 1 => 'varchar_col varchar NULL DEFAULT NULL', + 2 => 'text_col text NULL DEFAULT NULL', + 3 => 'text_col_array text[] NULL DEFAULT NULL', + 4 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 5 => 'varchar_5_col varchar(5) NULL DEFAULT NULL', + 6 => 'char_4_col char(4) NULL DEFAULT NULL', + 7 => 'char_5_col char NULL DEFAULT NULL', + 8 => 'char_6_col char NOT NULL', + 9 => 'char_7_col char(6) NOT NULL', + 10 => 'char_8_col char NULL DEFAULT \'d\'', + 11 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 12 => 'bytea_col_2 bytea NULL DEFAULT NULL', + 13 => 'bit_col bit NULL DEFAULT NULL', + 14 => 'bit_2 bit(1) NULL DEFAULT NULL', + 15 => 'bit_3 bit(64) NULL DEFAULT NULL', + 16 => 'ti smallint NULL DEFAULT NULL', + 17 => 'int2_col int2 NULL DEFAULT NULL', + 18 => 'smallserial_col smallserial NOT NULL', + 19 => 'serial2_col serial2 NOT NULL', + 20 => 'si_col smallint NULL DEFAULT NULL', + 21 => 'si_col_2 smallint NULL DEFAULT NULL', + 22 => 'bi bigint NULL DEFAULT NULL', + 23 => 'bi2 int8 NULL DEFAULT NULL', + 24 => 'int4_col int4 NULL DEFAULT NULL', + 25 => 'bigserial_col bigserial NOT NULL', + 26 => 'bigserial_col_2 serial8 NOT NULL', + 27 => 'int_col int NULL DEFAULT NULL', + 28 => 'int_col_2 integer NULL DEFAULT NULL', + 29 => 'numeric_col numeric NULL DEFAULT NULL', + 30 => 'numeric_col_2 numeric(10) NULL DEFAULT NULL', + 31 => 'numeric_col_3 numeric(10,2) NULL DEFAULT NULL', + 32 => 'double_p_2 double precision NULL DEFAULT NULL', + 33 => 'double_p_3 double precision NULL DEFAULT NULL', + 34 => 'real_col real NULL DEFAULT NULL', + 35 => 'float4_col float4 NULL DEFAULT NULL', + 36 => 'date_col date NULL DEFAULT NULL', + 37 => 'time_col time NULL DEFAULT NULL', + 38 => 'time_col_2 time with time zone NULL DEFAULT NULL', + 39 => 'time_col_3 time without time zone NULL DEFAULT NULL', + 40 => 'time_col_4 time(3) without time zone NULL DEFAULT NULL', + 41 => 'timetz_col timetz NULL DEFAULT NULL', + 42 => 'timetz_col_2 timetz(3) NULL DEFAULT NULL', + 43 => 'timestamp_col timestamp NULL DEFAULT NULL', + 44 => 'timestamp_col_2 timestamp with time zone NULL DEFAULT NULL', + 45 => 'timestamp_col_3 timestamp without time zone NULL DEFAULT NULL', + 46 => 'timestamp_col_4 timestamp(3) without time zone NULL DEFAULT NULL', + 47 => 'timestamptz_col timestamptz NULL DEFAULT NULL', + 48 => 'timestamptz_col_2 timestamptz(3) NULL DEFAULT NULL', + 49 => 'date2 date NULL DEFAULT NULL', + 50 => 'timestamp_col_z timestamp NULL DEFAULT NULL', + 51 => 'bit_varying bit varying NULL DEFAULT NULL', + 52 => 'bit_varying_n bit varying(8) NULL DEFAULT NULL', + 53 => 'bit_varying_n_2 varbit NULL DEFAULT NULL', + 54 => 'bit_varying_n_3 varbit(3) NULL DEFAULT NULL', + 55 => 'bool_col boolean NULL DEFAULT NULL', + 56 => 'bool_col_2 bool NULL DEFAULT NULL', + 57 => 'box_col box NULL DEFAULT NULL', + 58 => 'character_col character NULL DEFAULT NULL', + 59 => 'character_n character(12) NULL DEFAULT NULL', + 60 => 'character_varying character varying NULL DEFAULT NULL', + 61 => 'character_varying_n character varying(12) NULL DEFAULT NULL', + 62 => 'json_col json NOT NULL', + 63 => 'jsonb_col jsonb NOT NULL', + 64 => 'json_col_def json NOT NULL DEFAULT \'[]\'', + 65 => 'json_col_def_2 json NOT NULL DEFAULT \'[]\'', + 66 => 'bytea_def bytea NULL DEFAULT \'the bytea blob default\'', + 67 => 'text_def text NULL DEFAULT \'the text\'', + 68 => 'json_def json NOT NULL DEFAULT \'{"a":"b"}\'', + 69 => 'jsonb_def jsonb NOT NULL DEFAULT \'{"ba":"bb"}\'', + 70 => 'cidr_col cidr NULL DEFAULT NULL', + 71 => 'circle_col circle NULL DEFAULT NULL', + 72 => 'date_col_z date NULL DEFAULT NULL', + 73 => 'float8_col float8 NULL DEFAULT NULL', + 74 => 'inet_col inet NULL DEFAULT NULL', + 75 => 'interval_col interval NULL DEFAULT NULL', + 76 => 'interval_col_2 interval year NULL DEFAULT NULL', + 77 => 'interval_col_3 interval day to second(3) NULL DEFAULT NULL', + 78 => 'line_col line NULL DEFAULT NULL', + 79 => 'lseg_col lseg NULL DEFAULT NULL', + 80 => 'macaddr_col macaddr NULL DEFAULT NULL', + 81 => 'money_col money NULL DEFAULT NULL', + 82 => 'path_col path NULL DEFAULT NULL', + 83 => 'pg_lsn_col pg_lsn NULL DEFAULT NULL', + 84 => 'point_col point NULL DEFAULT NULL', + 85 => 'polygon_col polygon NULL DEFAULT NULL', + 86 => 'serial_col serial NOT NULL', + 87 => 'serial4_col serial4 NOT NULL', + 88 => 'tsquery_col tsquery NULL DEFAULT NULL', + 89 => 'tsvector_col tsvector NULL', + 90 => 'txid_snapshot_col txid_snapshot NULL DEFAULT NULL', + 91 => 'uuid_col uuid NULL DEFAULT NULL', + 92 => 'xml_col xml NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000001_change_table_editcolumns.php b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000001_change_table_editcolumns.php new file mode 100644 index 00000000..d412271c --- /dev/null +++ b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000001_change_table_editcolumns.php @@ -0,0 +1,49 @@ +db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN first_name varchar NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN json_col_def_n json NOT NULL DEFAULT \'[]\'')->execute(); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN json_col_def_n_2 json NOT NULL DEFAULT \'[]\'')->execute(); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ADD COLUMN text_col_array text[] NULL DEFAULT NULL')->execute(); + $this->alterColumn('{{%editcolumns}}', 'dec_col', "SET DEFAULT 3.14"); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ALTER COLUMN json_col SET DATA TYPE text')->execute(); + $this->alterColumn('{{%editcolumns}}', 'json_col', "SET NOT NULL"); + $this->alterColumn('{{%editcolumns}}', 'json_col', "SET DEFAULT 'fox jumps over dog'"); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', "SET NOT NULL"); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', "SET DEFAULT '[]'"); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ALTER COLUMN name SET DATA TYPE varchar(254)')->execute(); + $this->alterColumn('{{%editcolumns}}', 'name', "SET DEFAULT 'Horse-2'"); + $this->db->createCommand('ALTER TABLE {{%editcolumns}} ALTER COLUMN numeric_col SET DATA TYPE double precision')->execute(); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', "SET NOT NULL"); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', "DROP DEFAULT"); + $this->alterColumn('{{%editcolumns}}', 'string_col', $this->text()->null()); + $this->alterColumn('{{%editcolumns}}', 'string_col', "DROP NOT NULL"); + } + + public function safeDown() + { + $this->alterColumn('{{%editcolumns}}', 'string_col', $this->string(255)->notNull()); + $this->alterColumn('{{%editcolumns}}', 'numeric_col', 'int4 NULL USING "numeric_col"::int4'); + $this->alterColumn('{{%editcolumns}}', 'name', $this->string(255)->notNull()); + $this->alterColumn('{{%editcolumns}}', 'json_col', 'jsonb NULL USING "json_col"::jsonb'); + $this->dropColumn('{{%editcolumns}}', 'text_col_array'); + $this->dropColumn('{{%editcolumns}}', 'json_col_def_n_2'); + $this->dropColumn('{{%editcolumns}}', 'json_col_def_n'); + $this->dropColumn('{{%editcolumns}}', 'first_name'); + $this->alterColumn('{{%editcolumns}}', 'dec_col', "DROP DEFAULT"); + $this->alterColumn('{{%editcolumns}}', 'json_col', "DROP NOT NULL"); + $this->alterColumn('{{%editcolumns}}', 'json_col', "DROP DEFAULT"); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', "DROP NOT NULL"); + $this->alterColumn('{{%editcolumns}}', 'json_col_2', "DROP DEFAULT"); + $this->alterColumn('{{%editcolumns}}', 'name', "SET DEFAULT 'Horse'"); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', "DROP NOT NULL"); + $this->alterColumn('{{%editcolumns}}', 'str_col_def', "SET DEFAULT 'hi there'"); + $this->alterColumn('{{%editcolumns}}', 'string_col', "SET NOT NULL"); + } +} diff --git a/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000002_create_table_newcolumns.php b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000002_create_table_newcolumns.php new file mode 100644 index 00000000..3604dce0 --- /dev/null +++ b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000002_create_table_newcolumns.php @@ -0,0 +1,29 @@ +createTable('{{%newcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar NOT NULL', + 1 => 'first_name varchar NULL DEFAULT NULL', + 'last_name' => $this->text()->null()->defaultValue(null), + 2 => 'dec_col decimal(12,4) NULL DEFAULT NULL', + 3 => 'json_col json NOT NULL', + 4 => 'varchar_col varchar NULL DEFAULT NULL', + 5 => 'numeric_col double precision NULL DEFAULT NULL', + 6 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + 7 => 'json_col_def_n_2 json NOT NULL DEFAULT \'[]\'', + 8 => 'text_col_array text[] NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%newcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..e4090b6d --- /dev/null +++ b/tests/specs/x_db_type/edit_column/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col serial primary key NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null()->defaultValue("4 leg"), + 2 => 'new_col varchar NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar NULL DEFAULT NULL', + 8 => 'col_10 varchar NULL DEFAULT NULL', + 9 => 'col_11 text NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..9c002bea --- /dev/null +++ b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,62 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar(255) NULL DEFAULT NULL', + 1 => 'varchar_col varchar(132) NULL DEFAULT NULL', + 2 => 'text_col text NULL DEFAULT NULL', + 3 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 4 => 'char_4_col char(4) NULL DEFAULT NULL', + 5 => 'char_5_col char NULL DEFAULT NULL', + 6 => 'char_6_col char NOT NULL', + 7 => 'char_7_col char(6) NOT NULL', + 8 => 'char_8_col char NULL DEFAULT \'d\'', + 9 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 10 => 'varbinary_col varbinary(5) NULL DEFAULT NULL', + 11 => 'blob_col blob NULL DEFAULT NULL', + 12 => 'bit_col bit NULL DEFAULT NULL', + 13 => 'bit_2 bit(1) NULL DEFAULT NULL', + 14 => 'bit_3 bit(64) NULL DEFAULT NULL', + 15 => 'ti tinyint NULL DEFAULT NULL', + 16 => 'ti_2 tinyint(1) NULL DEFAULT NULL', + 17 => 'ti_3 tinyint(2) NULL DEFAULT NULL', + 18 => 'si_col smallint NULL DEFAULT NULL', + 19 => 'si_col_2 smallint unsigned zerofill NULL DEFAULT NULL', + 20 => 'mi mediumint(10) unsigned zerofill comment "comment" NULL DEFAULT 7', + 21 => 'bi bigint NULL DEFAULT NULL', + 22 => 'int_col int NULL DEFAULT NULL', + 23 => 'int_col_2 integer NULL DEFAULT NULL', + 24 => 'numeric_col numeric NULL DEFAULT NULL', + 25 => 'float_col float NULL DEFAULT NULL', + 26 => 'float_2 float(10, 2) NULL DEFAULT NULL', + 27 => 'float_3 float(8) NULL DEFAULT NULL', + 28 => 'double_col double NULL DEFAULT NULL', + 29 => 'double_p double precision(10,2) NULL DEFAULT NULL', + 30 => 'double_p_2 double precision NULL DEFAULT NULL', + 31 => 'real_col real NULL DEFAULT NULL', + 32 => 'date_col date NULL DEFAULT NULL', + 33 => 'time_col time NULL DEFAULT NULL', + 34 => 'datetime_col datetime NULL DEFAULT NULL', + 35 => 'timestamp_col timestamp NULL DEFAULT NULL', + 36 => 'year_col year NULL DEFAULT NULL', + 37 => 'json_col json NOT NULL', + 38 => 'json_col_def json NOT NULL DEFAULT \'[]\'', + 39 => 'json_col_def_2 json NOT NULL DEFAULT \'[]\'', + 40 => 'blob_def blob NULL DEFAULT \'the blob\'', + 41 => 'text_def text NULL DEFAULT \'the text\'', + 42 => 'json_def json NOT NULL DEFAULT \'{"a":"b"}\'', + ]); + } + + public function down() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000001_create_table_editcolumns.php b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000001_create_table_editcolumns.php new file mode 100644 index 00000000..1de3d8d5 --- /dev/null +++ b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000001_create_table_editcolumns.php @@ -0,0 +1,30 @@ +createTable('{{%editcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL DEFAULT \'Horse-2\'', + 'tag' => $this->text()->null()->defaultValue(null), + 1 => 'first_name varchar(255) NULL DEFAULT NULL', + 'string_col' => $this->text()->null()->defaultValue(null), + 2 => 'dec_col decimal(12,2) NULL DEFAULT 3.14', + 3 => 'str_col_def varchar(3) NOT NULL', + 4 => 'json_col text NOT NULL DEFAULT \'fox jumps over dog\'', + 5 => 'json_col_2 json NOT NULL DEFAULT \'[]\'', + 6 => 'numeric_col double precision NULL DEFAULT NULL', + 7 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + 8 => 'json_col_def_n_2 json NOT NULL DEFAULT \'[]\'', + ]); + } + + public function down() + { + $this->dropTable('{{%editcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000002_create_table_newcolumns.php b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000002_create_table_newcolumns.php new file mode 100644 index 00000000..a53b1995 --- /dev/null +++ b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000002_create_table_newcolumns.php @@ -0,0 +1,26 @@ +createTable('{{%newcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL', + 'last_name' => $this->text()->null()->defaultValue(null), + 1 => 'dec_col decimal(12,4) NULL DEFAULT NULL', + 2 => 'json_col json NOT NULL', + 3 => 'varchar_col varchar(5) NULL DEFAULT NULL', + 4 => 'numeric_col double precision NULL DEFAULT NULL', + 5 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + ]); + } + + public function down() + { + $this->dropTable('{{%newcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..4d1b1590 --- /dev/null +++ b/tests/specs/x_db_type/fresh/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col integer primary key auto_increment NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null()->defaultValue("4 leg"), + 2 => 'new_col varchar(17) NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar(9) NULL DEFAULT NULL', + 8 => 'col_10 varchar(10) NULL DEFAULT NULL', + 9 => 'col_11 text NULL DEFAULT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..2cda660f --- /dev/null +++ b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,62 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar(255) NULL DEFAULT NULL', + 1 => 'varchar_col varchar(132) NULL DEFAULT NULL', + 2 => 'text_col text NULL', + 3 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 4 => 'char_4_col char(4) NULL DEFAULT NULL', + 5 => 'char_5_col char NULL DEFAULT NULL', + 6 => 'char_6_col char NOT NULL', + 7 => 'char_7_col char(6) NOT NULL', + 8 => 'char_8_col char NULL DEFAULT \'d\'', + 9 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 10 => 'varbinary_col varbinary(5) NULL DEFAULT NULL', + 11 => 'blob_col blob NULL', + 12 => 'bit_col bit NULL DEFAULT NULL', + 13 => 'bit_2 bit(1) NULL DEFAULT NULL', + 14 => 'bit_3 bit(64) NULL DEFAULT NULL', + 15 => 'ti tinyint NULL DEFAULT NULL', + 16 => 'ti_2 tinyint(1) NULL DEFAULT NULL', + 17 => 'ti_3 tinyint(2) NULL DEFAULT NULL', + 18 => 'si_col smallint NULL DEFAULT NULL', + 19 => 'si_col_2 smallint unsigned zerofill NULL DEFAULT NULL', + 20 => 'mi mediumint(10) unsigned zerofill comment "comment" NULL DEFAULT 7', + 21 => 'bi bigint NULL DEFAULT NULL', + 22 => 'int_col int NULL DEFAULT NULL', + 23 => 'int_col_2 integer NULL DEFAULT NULL', + 24 => 'numeric_col numeric NULL DEFAULT NULL', + 25 => 'float_col float NULL DEFAULT NULL', + 26 => 'float_2 float(10, 2) NULL DEFAULT NULL', + 27 => 'float_3 float(8) NULL DEFAULT NULL', + 28 => 'double_col double NULL DEFAULT NULL', + 29 => 'double_p double precision(10,2) NULL DEFAULT NULL', + 30 => 'double_p_2 double precision NULL DEFAULT NULL', + 31 => 'real_col real NULL DEFAULT NULL', + 32 => 'date_col date NULL DEFAULT NULL', + 33 => 'time_col time NULL DEFAULT NULL', + 34 => 'datetime_col datetime NULL DEFAULT NULL', + 35 => 'timestamp_col timestamp NULL DEFAULT NULL', + 36 => 'year_col year NULL DEFAULT NULL', + 37 => 'json_col json NOT NULL', + 38 => 'json_col_def json NOT NULL', + 39 => 'json_col_def_2 json NOT NULL', + 40 => 'blob_def blob NULL', + 41 => 'text_def text NULL', + 42 => 'json_def json NOT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000001_create_table_editcolumns.php b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000001_create_table_editcolumns.php new file mode 100644 index 00000000..8c84e731 --- /dev/null +++ b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000001_create_table_editcolumns.php @@ -0,0 +1,30 @@ +createTable('{{%editcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL DEFAULT \'Horse-2\'', + 'tag' => $this->text()->null(), + 1 => 'first_name varchar(255) NULL DEFAULT NULL', + 'string_col' => $this->text()->null(), + 2 => 'dec_col decimal(12,2) NULL DEFAULT 3.14', + 3 => 'str_col_def varchar(3) NOT NULL', + 4 => 'json_col text NOT NULL', + 5 => 'json_col_2 json NOT NULL', + 6 => 'numeric_col double precision NULL DEFAULT NULL', + 7 => 'json_col_def_n json NOT NULL', + 8 => 'json_col_def_n_2 json NOT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%editcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000002_create_table_newcolumns.php b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000002_create_table_newcolumns.php new file mode 100644 index 00000000..aacd206c --- /dev/null +++ b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000002_create_table_newcolumns.php @@ -0,0 +1,26 @@ +createTable('{{%newcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL', + 'last_name' => $this->text()->null(), + 1 => 'dec_col decimal(12,4) NULL DEFAULT NULL', + 2 => 'json_col json NOT NULL', + 3 => 'varchar_col varchar(5) NULL DEFAULT NULL', + 4 => 'numeric_col double precision NULL DEFAULT NULL', + 5 => 'json_col_def_n json NOT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%newcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..aeed5fe1 --- /dev/null +++ b/tests/specs/x_db_type/fresh/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col integer primary key auto_increment NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null(), + 2 => 'new_col varchar(17) NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar(9) NULL DEFAULT NULL', + 8 => 'col_10 varchar(10) NULL DEFAULT NULL', + 9 => 'col_11 text NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/mysql/x_db_type_mysql.php b/tests/specs/x_db_type/fresh/mysql/x_db_type_mysql.php new file mode 100644 index 00000000..1d647481 --- /dev/null +++ b/tests/specs/x_db_type/fresh/mysql/x_db_type_mysql.php @@ -0,0 +1,13 @@ + '@specs/x_db_type/fresh/mysql/x_db_type_mysql.yaml', + 'generateUrls' => false, + 'generateModels' => false, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => false, + 'generateMigrations' => true, + 'generateModelFaker' => false, +]; diff --git a/tests/specs/x_db_type/fresh/mysql/x_db_type_mysql.yaml b/tests/specs/x_db_type/fresh/mysql/x_db_type_mysql.yaml new file mode 100644 index 00000000..a055caad --- /dev/null +++ b/tests/specs/x_db_type/fresh/mysql/x_db_type_mysql.yaml @@ -0,0 +1,336 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Column edit by x-db-type test +paths: + /: + get: + summary: List + operationId: list + responses: + '200': + description: The information + +components: + schemas: + Pristine: + type: object + description: New Fresh table with new columns for migration code generation + required: + - custom_id_col + - name + properties: + custom_id_col: + type: integer + format: int64 + x-db-type: INTEGER PRIMARY KEY AUTO_INCREMENT + name: + type: integer + x-db-type: text + tag: + type: string + default: 4 leg + new_col: + type: string + x-db-type: varchar(17) + col_5: + type: string + x-db-type: decimal(12,4) + col_6: + type: string + x-db-type: decimal(11) + col_7: + type: string + x-db-type: decimal + col_8: + type: string + x-db-type: json + col_9: + type: string + x-db-type: varchar(9) + col_10: + type: string + x-db-type: VARCHAR(10) + col_11: + type: string + x-db-type: TEXT + + + Alldbdatatype: # All DB data type + type: object + description: All DB data type + required: + - id + - char_6_col + properties: + id: + type: integer + format: int64 + string_col: + type: string + x-db-type: varchar(255) + varchar_col: + type: string + x-db-type: varchar(132) + text_col: + type: string + x-db-type: text + varchar_4_col: + type: string + x-db-type: VARCHAR(4) # (4) has no effect, use maxLength instead + char_4_col: + type: string + x-db-type: CHAR(4) # (4) has no effect, use maxLength instead + char_5_col: + type: string + x-db-type: CHAR + char_6_col: + type: string + x-db-type: char + char_7_col: + type: string + x-db-type: char + maxLength: 6 + nullable: false + char_8_col: + type: string + x-db-type: char + default: d + decimal_col: + type: float + x-db-type: decimal(12,3) + + # binary_col: + # type: string + # x-db-type: binary # binary is not in $typeMap list in \yii\db\mysql\Schema::class https://github.com/yiisoft/yii2/issues/19705 + + varbinary_col: + type: string + x-db-type: varbinary + # nullable: false + maxLength: 5 # length is required in varbinary and binary + blob_col: + type: string + x-db-type: blob + # set: + # type: string + # x-db-type: SET('a', 'b', 'c', 'd') # set is not in $typeMap list in \yii\db\mysql\Schema::class https://github.com/yiisoft/yii2/issues/19705 + bit_col: + type: string + x-db-type: bit + bit_2: + type: string + x-db-type: bit(1) + bit_3: + type: string + x-db-type: bit(64) + + ti: + type: string + x-db-type: tinyint + ti_2: + type: string + x-db-type: tinyint(1) + ti_3: + type: string + x-db-type: tinyint(2) + + si_col: + type: string + x-db-type: smallint + si_col_2: + type: string + x-db-type: SMALLINT UNSIGNED ZEROFILL + + mi: + type: string + x-db-type: MEDIUMINT(10) UNSIGNED ZEROFILL COMMENT "comment" # note the double quotes here + default: 7 + bi: + type: string + x-db-type: bigint + int_col: + type: string + x-db-type: int + int_col_2: + type: string + x-db-type: integer + + # dec: + # type: string + # x-db-type: dec # not supported + + # fixed: + # type: string + # x-db-type: fixed # not supported + + numeric_col: + type: string + x-db-type: numeric + float_col: + type: string + x-db-type: float + float_2: + type: string + x-db-type: float(10, 2) + float_3: + type: string + x-db-type: float(8) + + double_col: + type: string + x-db-type: double + double_p: + type: string + x-db-type: double precision(10,2) + double_p_2: + type: string + x-db-type: double precision + real_col: + type: string + x-db-type: real + + date_col: + type: string + x-db-type: date + time_col: + type: string + x-db-type: time + datetime_col: + type: string + x-db-type: datetime + timestamp_col: + type: string + x-db-type: timestamp + year_col: + type: string + x-db-type: year + + # geometry: + # type: string + # x-db-type: geometry + # below are not implemented in Yii + # GEOMETRY + # point + # LINESTRING + # POLYGON + # MULTIPOINT + # MULTILINESTRING + # MULTIPOLYGON + # GEOMETRYCOLLECTION + + json_col: + type: string + x-db-type: json + json_col_def: + type: string + x-db-type: json + default: [] + json_col_def_2: + type: string + x-db-type: json + default: '[]' + + # literal default not supportted for blob, text, json and geometry + # below default will have no effect + blob_def: + type: string + x-db-type: blob + default: the blob + text_def: + type: string + x-db-type: text + default: the text + json_def: + type: string + x-db-type: json + default: '{"a":"b"}' + + + Newcolumn: + type: object + description: New Fresh table with new columns for migration code generation + required: + - id + - name + properties: + id: + type: integer + name: + type: string + x-db-type: varchar(255) + nullable: false + # first_name: + # type: string + # x-db-type: string # This should lead to error as string is not real DB type in MySQL but (bug in Yii?) it is present in \yii\db\mysql\Schema + last_name: + type: string + dec_col: + type: string + x-db-type: decimal(12,4) + json_col: + type: string + x-db-type: json + varchar_col: + type: string + x-db-type: varchar(5) + numeric_col: + type: string + x-db-type: double precision + json_col_def_n: + type: string + x-db-type: json + default: [] + + Editcolumn: + type: object + description: Table with edit columns for migration code generation + required: + - id + - name + properties: + id: + type: integer + name: + type: string + x-db-type: varchar(255) + maxLength: 254 + nullable: false + default: Horse-2 + tag: + type: string + first_name: + type: string + x-db-type: varchar(255) + string_col: + type: string # text in DB + nullable: true + dec_col: + type: string + x-db-type: decimal(12,2) + default: 3.14 + str_col_def: + type: string + x-db-type: varchar(3) + nullable: false + json_col: + type: string + x-db-type: text + nullable: false + default: fox jumps over dog + json_col_2: + type: string + x-db-type: json + nullable: false + default: [] + numeric_col: + type: string + x-db-type: double precision + json_col_def_n: + type: string + x-db-type: json + default: [] + json_col_def_n_2: + type: string + x-db-type: json + default: '[]' diff --git a/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..53498798 --- /dev/null +++ b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,112 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar NULL DEFAULT NULL', + 1 => 'varchar_col varchar NULL DEFAULT NULL', + 2 => 'text_col text NULL DEFAULT NULL', + 3 => 'text_col_array text[] NULL DEFAULT NULL', + 4 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 5 => 'varchar_5_col varchar(5) NULL DEFAULT NULL', + 6 => 'char_4_col char(4) NULL DEFAULT NULL', + 7 => 'char_5_col char NULL DEFAULT NULL', + 8 => 'char_6_col char NOT NULL', + 9 => 'char_7_col char(6) NOT NULL', + 10 => 'char_8_col char NULL DEFAULT \'d\'', + 11 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 12 => 'bytea_col_2 bytea NULL DEFAULT NULL', + 13 => 'bit_col bit NULL DEFAULT NULL', + 14 => 'bit_2 bit(1) NULL DEFAULT NULL', + 15 => 'bit_3 bit(64) NULL DEFAULT NULL', + 16 => 'ti smallint NULL DEFAULT NULL', + 17 => 'int2_col int2 NULL DEFAULT NULL', + 18 => 'smallserial_col smallserial NOT NULL', + 19 => 'serial2_col serial2 NOT NULL', + 20 => 'si_col smallint NULL DEFAULT NULL', + 21 => 'si_col_2 smallint NULL DEFAULT NULL', + 22 => 'bi bigint NULL DEFAULT NULL', + 23 => 'bi2 int8 NULL DEFAULT NULL', + 24 => 'int4_col int4 NULL DEFAULT NULL', + 25 => 'bigserial_col bigserial NOT NULL', + 26 => 'bigserial_col_2 serial8 NOT NULL', + 27 => 'int_col int NULL DEFAULT NULL', + 28 => 'int_col_2 integer NULL DEFAULT NULL', + 29 => 'numeric_col numeric NULL DEFAULT NULL', + 30 => 'numeric_col_2 numeric(10) NULL DEFAULT NULL', + 31 => 'numeric_col_3 numeric(10,2) NULL DEFAULT NULL', + 32 => 'double_p_2 double precision NULL DEFAULT NULL', + 33 => 'double_p_3 double precision NULL DEFAULT NULL', + 34 => 'real_col real NULL DEFAULT NULL', + 35 => 'float4_col float4 NULL DEFAULT NULL', + 36 => 'date_col date NULL DEFAULT NULL', + 37 => 'time_col time NULL DEFAULT NULL', + 38 => 'time_col_2 time with time zone NULL DEFAULT NULL', + 39 => 'time_col_3 time without time zone NULL DEFAULT NULL', + 40 => 'time_col_4 time(3) without time zone NULL DEFAULT NULL', + 41 => 'timetz_col timetz NULL DEFAULT NULL', + 42 => 'timetz_col_2 timetz(3) NULL DEFAULT NULL', + 43 => 'timestamp_col timestamp NULL DEFAULT NULL', + 44 => 'timestamp_col_2 timestamp with time zone NULL DEFAULT NULL', + 45 => 'timestamp_col_3 timestamp without time zone NULL DEFAULT NULL', + 46 => 'timestamp_col_4 timestamp(3) without time zone NULL DEFAULT NULL', + 47 => 'timestamptz_col timestamptz NULL DEFAULT NULL', + 48 => 'timestamptz_col_2 timestamptz(3) NULL DEFAULT NULL', + 49 => 'date2 date NULL DEFAULT NULL', + 50 => 'timestamp_col_z timestamp NULL DEFAULT NULL', + 51 => 'bit_varying bit varying NULL DEFAULT NULL', + 52 => 'bit_varying_n bit varying(8) NULL DEFAULT NULL', + 53 => 'bit_varying_n_2 varbit NULL DEFAULT NULL', + 54 => 'bit_varying_n_3 varbit(3) NULL DEFAULT NULL', + 55 => 'bool_col boolean NULL DEFAULT NULL', + 56 => 'bool_col_2 bool NULL DEFAULT NULL', + 57 => 'box_col box NULL DEFAULT NULL', + 58 => 'character_col character NULL DEFAULT NULL', + 59 => 'character_n character(12) NULL DEFAULT NULL', + 60 => 'character_varying character varying NULL DEFAULT NULL', + 61 => 'character_varying_n character varying(12) NULL DEFAULT NULL', + 62 => 'json_col json NOT NULL', + 63 => 'jsonb_col jsonb NOT NULL', + 64 => 'json_col_def json NOT NULL DEFAULT \'[]\'', + 65 => 'json_col_def_2 json NOT NULL DEFAULT \'[]\'', + 66 => 'bytea_def bytea NULL DEFAULT \'the bytea blob default\'', + 67 => 'text_def text NULL DEFAULT \'the text\'', + 68 => 'json_def json NOT NULL DEFAULT \'{"a":"b"}\'', + 69 => 'jsonb_def jsonb NOT NULL DEFAULT \'{"ba":"bb"}\'', + 70 => 'cidr_col cidr NULL DEFAULT NULL', + 71 => 'circle_col circle NULL DEFAULT NULL', + 72 => 'date_col_z date NULL DEFAULT NULL', + 73 => 'float8_col float8 NULL DEFAULT NULL', + 74 => 'inet_col inet NULL DEFAULT NULL', + 75 => 'interval_col interval NULL DEFAULT NULL', + 76 => 'interval_col_2 interval year NULL DEFAULT NULL', + 77 => 'interval_col_3 interval day to second(3) NULL DEFAULT NULL', + 78 => 'line_col line NULL DEFAULT NULL', + 79 => 'lseg_col lseg NULL DEFAULT NULL', + 80 => 'macaddr_col macaddr NULL DEFAULT NULL', + 81 => 'money_col money NULL DEFAULT NULL', + 82 => 'path_col path NULL DEFAULT NULL', + 83 => 'pg_lsn_col pg_lsn NULL DEFAULT NULL', + 84 => 'point_col point NULL DEFAULT NULL', + 85 => 'polygon_col polygon NULL DEFAULT NULL', + 86 => 'serial_col serial NOT NULL', + 87 => 'serial4_col serial4 NOT NULL', + 88 => 'tsquery_col tsquery NULL DEFAULT NULL', + 89 => 'tsvector_col tsvector NULL', + 90 => 'txid_snapshot_col txid_snapshot NULL DEFAULT NULL', + 91 => 'uuid_col uuid NULL DEFAULT NULL', + 92 => 'xml_col xml NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000001_create_table_editcolumns.php b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000001_create_table_editcolumns.php new file mode 100644 index 00000000..93111403 --- /dev/null +++ b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000001_create_table_editcolumns.php @@ -0,0 +1,31 @@ +createTable('{{%editcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(254) NOT NULL DEFAULT \'Horse-2\'', + 'tag' => $this->text()->null()->defaultValue(null), + 1 => 'first_name varchar NULL DEFAULT NULL', + 'string_col' => $this->text()->null()->defaultValue(null), + 2 => 'dec_col decimal(12,2) NULL DEFAULT 3.14', + 3 => 'str_col_def varchar NOT NULL', + 4 => 'json_col text NOT NULL DEFAULT \'fox jumps over dog\'', + 5 => 'json_col_2 json NOT NULL DEFAULT \'[]\'', + 6 => 'numeric_col double precision NULL DEFAULT NULL', + 7 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + 8 => 'json_col_def_n_2 json NOT NULL DEFAULT \'[]\'', + 9 => 'text_col_array text[] NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%editcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000002_create_table_newcolumns.php b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000002_create_table_newcolumns.php new file mode 100644 index 00000000..3604dce0 --- /dev/null +++ b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000002_create_table_newcolumns.php @@ -0,0 +1,29 @@ +createTable('{{%newcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar NOT NULL', + 1 => 'first_name varchar NULL DEFAULT NULL', + 'last_name' => $this->text()->null()->defaultValue(null), + 2 => 'dec_col decimal(12,4) NULL DEFAULT NULL', + 3 => 'json_col json NOT NULL', + 4 => 'varchar_col varchar NULL DEFAULT NULL', + 5 => 'numeric_col double precision NULL DEFAULT NULL', + 6 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + 7 => 'json_col_def_n_2 json NOT NULL DEFAULT \'[]\'', + 8 => 'text_col_array text[] NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%newcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..e4090b6d --- /dev/null +++ b/tests/specs/x_db_type/fresh/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col serial primary key NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null()->defaultValue("4 leg"), + 2 => 'new_col varchar NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar NULL DEFAULT NULL', + 8 => 'col_10 varchar NULL DEFAULT NULL', + 9 => 'col_11 text NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/fresh/pgsql/x_db_type_pgsql.php b/tests/specs/x_db_type/fresh/pgsql/x_db_type_pgsql.php new file mode 100644 index 00000000..99d4eafd --- /dev/null +++ b/tests/specs/x_db_type/fresh/pgsql/x_db_type_pgsql.php @@ -0,0 +1,13 @@ + '@specs/x_db_type/fresh/pgsql/x_db_type_pgsql.yaml', + 'generateUrls' => false, + 'generateModels' => false, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => false, + 'generateMigrations' => true, + 'generateModelFaker' => false, +]; diff --git a/tests/specs/x_db_type/fresh/pgsql/x_db_type_pgsql.yaml b/tests/specs/x_db_type/fresh/pgsql/x_db_type_pgsql.yaml new file mode 100644 index 00000000..b472ecc3 --- /dev/null +++ b/tests/specs/x_db_type/fresh/pgsql/x_db_type_pgsql.yaml @@ -0,0 +1,524 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Column edit by x-db-type test for PgSQL +paths: + /: + get: + summary: List + operationId: list + responses: + '200': + description: The information + +components: + schemas: + Pristine: + type: object + description: New Fresh table with new columns for migration code generation + required: + - custom_id_col + - name + properties: + custom_id_col: + type: integer + format: int64 + x-db-type: SERIAL PRIMARY KEY + name: + type: integer + x-db-type: text + tag: + type: string + default: 4 leg + new_col: + type: string + x-db-type: varchar + col_5: + type: string + x-db-type: decimal(12,4) + col_6: + type: string + x-db-type: decimal(11) + col_7: + type: string + x-db-type: decimal + col_8: + type: string + x-db-type: json + col_9: + type: string + x-db-type: varchar + col_10: + type: string + x-db-type: VARCHAR + col_11: + type: string + x-db-type: TEXT + + + Alldbdatatype: # All DB data type + type: object + description: All DB data type + required: + - id + - char_6_col + properties: + id: + type: integer + format: int64 + string_col: + type: string + x-db-type: varchar + varchar_col: + type: string + x-db-type: varchar + text_col: + type: string + x-db-type: text + text_col_array: + type: string + x-db-type: text[] + varchar_4_col: + type: string + x-db-type: VARCHAR(4) # (4) has no effect, use maxLength instead + varchar_5_col: + type: string + x-db-type: VARCHAR + maxLength: 5 + char_4_col: + type: string + x-db-type: CHAR(4) # (4) has no effect, use maxLength instead + char_5_col: + type: string + x-db-type: CHAR + char_6_col: + type: string + x-db-type: char + char_7_col: + type: string + x-db-type: char + maxLength: 6 + nullable: false + char_8_col: + type: string + x-db-type: char + default: d + decimal_col: + type: float + x-db-type: decimal(12,3) + + # binary_col: + # type: string + # x-db-type: binary # binary is not in $typeMap list in \yii\db\mysql\Schema::class https://github.com/yiisoft/yii2/issues/19705 + + # bytea_col: + # type: string + # x-db-type: bytea + # # nullable: false + # maxLength: 5 # length is required in bytea and binary + bytea_col_2: + type: string + x-db-type: bytea + # set: + # type: string + # x-db-type: SET('a', 'b', 'c', 'd') # set is not in $typeMap list in \yii\db\mysql\Schema::class https://github.com/yiisoft/yii2/issues/19705 + bit_col: + type: string + x-db-type: bit + bit_2: + type: string + x-db-type: bit(1) + bit_3: + type: string + x-db-type: bit(64) + + ti: + type: string + x-db-type: smallint + int2_col: + type: string + x-db-type: int2 + + smallserial_col: + type: string + x-db-type: smallserial + nullable: false + serial2_col: + type: string + x-db-type: serial2 + nullable: false + + si_col: + type: string + x-db-type: smallint + si_col_2: + type: string + x-db-type: SMALLINT # UNSIGNED ZEROFILL + + bi: + type: string + x-db-type: bigint + bi2: + type: string + x-db-type: int8 + int4_col: + type: string + x-db-type: int4 + bigserial_col: + type: string + x-db-type: bigserial + nullable: false + bigserial_col_2: + type: string + x-db-type: serial8 + nullable: false + int_col: + type: string + x-db-type: int + int_col_2: + type: string + x-db-type: integer + + # dec: + # type: string + # x-db-type: dec # not supported + + # fixed: + # type: string + # x-db-type: fixed # not supported + + numeric_col: + type: string + x-db-type: numeric + numeric_col_2: + type: string + x-db-type: numeric(10) + numeric_col_3: + type: string + x-db-type: numeric(10,2) + + double_p_2: + type: string + x-db-type: DOUBLE PRECISION + double_p_3: + type: string + x-db-type: double precision + + real_col: + type: string + x-db-type: real + float4_col: + type: string + x-db-type: float4 + + date_col: + type: string + x-db-type: date + time_col: + type: string + x-db-type: time + time_col_2: + type: string + x-db-type: time with time zone + time_col_3: + type: string + x-db-type: time without time zone + time_col_4: + type: string + x-db-type: time(3) without time zone + timetz_col: + type: string + x-db-type: timetz + timetz_col_2: + type: string + x-db-type: timetz(3) + + + timestamp_col: + type: string + x-db-type: timestamp + timestamp_col_2: + type: string + x-db-type: timestamp with time zone + timestamp_col_3: + type: string + x-db-type: timestamp without time zone + timestamp_col_4: + type: string + x-db-type: timestamp(3) without time zone + timestamptz_col: + type: string + x-db-type: timestamptz + timestamptz_col_2: + type: string + x-db-type: timestamptz(3) + + + date2: + type: string + x-db-type: date + timestamp_col_z: + type: string + x-db-type: timestamp + + bit_varying: + type: string + x-db-type: bit varying + bit_varying_n: + type: string + x-db-type: bit varying(8) + bit_varying_n_2: + type: string + x-db-type: varbit + bit_varying_n_3: + type: string + x-db-type: varbit(3) + + bool_col: + type: string + x-db-type: boolean + bool_col_2: + type: string + x-db-type: bool + + box_col: + type: string + x-db-type: box + + character_col: + type: string + x-db-type: character + character_n: + type: string + x-db-type: character(12) + character_varying: + type: string + x-db-type: character varying + character_varying_n: + type: string + x-db-type: character varying(12) + + + # geometry: + # type: string + # x-db-type: geometry + # below are not implemented in Yii + # GEOMETRY + # point + # LINESTRING + # POLYGON + # MULTIPOINT + # MULTILINESTRING + # MULTIPOLYGON + # GEOMETRYCOLLECTION + + json_col: + type: string + x-db-type: json + jsonb_col: + type: string + x-db-type: jsonb + + json_col_def: + type: string + x-db-type: json + default: [] + json_col_def_2: + type: string + x-db-type: json + default: '[]' + + bytea_def: + type: string + x-db-type: bytea + default: the bytea blob default + text_def: + type: string + x-db-type: text + default: the text + json_def: + type: string + x-db-type: json + default: '{"a":"b"}' + jsonb_def: + type: string + x-db-type: jsonb + default: '{"ba":"bb"}' + cidr_col: + type: string + x-db-type: cidr + circle_col: + type: string + x-db-type: circle + date_col_z: + type: string + x-db-type: date + float8_col: + type: string + x-db-type: float8 + inet_col: + type: string + x-db-type: inet + interval_col: + type: string + x-db-type: interval + interval_col_2: + type: string + x-db-type: interval year + interval_col_3: + type: string + x-db-type: interval day to second(3) + line_col: + type: string + x-db-type: line + lseg_col: + type: string + x-db-type: lseg + macaddr_col: + type: string + x-db-type: macaddr + # macaddr8_col: + # type: string + # x-db-type: macaddr8 # not in Yii Pgsql schema + money_col: + type: string + x-db-type: money + path_col: + type: string + x-db-type: path + pg_lsn_col: + type: string + x-db-type: pg_lsn + # pg_snapshot_col: + # type: string + # x-db-type: pg_snapshot # not in Yii Pgsql schema + point_col: + type: string + x-db-type: point + polygon_col: + type: string + x-db-type: polygon + + serial_col: + type: string + x-db-type: serial + nullable: false + serial4_col: + type: string + x-db-type: serial4 + nullable: false + tsquery_col: + type: string + x-db-type: tsquery + tsvector_col: + type: string + x-db-type: tsvector + txid_snapshot_col: + type: string + x-db-type: txid_snapshot + uuid_col: + type: string + x-db-type: uuid + xml_col: + type: string + x-db-type: xml + + + + Newcolumn: + type: object + description: New Fresh table with new columns for migration code generation + required: + - id + - name + properties: + id: + type: integer + name: + type: string + x-db-type: varchar + nullable: false + first_name: + type: string + x-db-type: varchar + last_name: + type: string + dec_col: + type: string + x-db-type: decimal(12,4) + json_col: + type: string + x-db-type: json + varchar_col: + type: string + x-db-type: varchar + numeric_col: + type: string + x-db-type: double precision + json_col_def_n: + type: string + x-db-type: json + default: [] + json_col_def_n_2: + type: string + x-db-type: json + default: '[]' + text_col_array: + type: string + x-db-type: text[] + + Editcolumn: + type: object + description: Table with edit columns for migration code generation + required: + - id + - name + properties: + id: + type: integer + name: + type: string + x-db-type: varchar + maxLength: 254 + nullable: false + default: Horse-2 + tag: + type: string + first_name: + type: string + x-db-type: varchar + string_col: + type: string # text in DB + nullable: true + dec_col: + type: string + x-db-type: decimal(12,2) + default: 3.14 + str_col_def: + type: string + x-db-type: varchar + nullable: false + json_col: + type: string + x-db-type: text + nullable: false + default: fox jumps over dog + json_col_2: + type: string + x-db-type: json + nullable: false + default: [] + numeric_col: + type: string + x-db-type: double precision + json_col_def_n: + type: string + x-db-type: json + default: [] + json_col_def_n_2: + type: string + x-db-type: json + default: '[]' + text_col_array: + type: string + x-db-type: text[] diff --git a/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..9c002bea --- /dev/null +++ b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,62 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar(255) NULL DEFAULT NULL', + 1 => 'varchar_col varchar(132) NULL DEFAULT NULL', + 2 => 'text_col text NULL DEFAULT NULL', + 3 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 4 => 'char_4_col char(4) NULL DEFAULT NULL', + 5 => 'char_5_col char NULL DEFAULT NULL', + 6 => 'char_6_col char NOT NULL', + 7 => 'char_7_col char(6) NOT NULL', + 8 => 'char_8_col char NULL DEFAULT \'d\'', + 9 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 10 => 'varbinary_col varbinary(5) NULL DEFAULT NULL', + 11 => 'blob_col blob NULL DEFAULT NULL', + 12 => 'bit_col bit NULL DEFAULT NULL', + 13 => 'bit_2 bit(1) NULL DEFAULT NULL', + 14 => 'bit_3 bit(64) NULL DEFAULT NULL', + 15 => 'ti tinyint NULL DEFAULT NULL', + 16 => 'ti_2 tinyint(1) NULL DEFAULT NULL', + 17 => 'ti_3 tinyint(2) NULL DEFAULT NULL', + 18 => 'si_col smallint NULL DEFAULT NULL', + 19 => 'si_col_2 smallint unsigned zerofill NULL DEFAULT NULL', + 20 => 'mi mediumint(10) unsigned zerofill comment "comment" NULL DEFAULT 7', + 21 => 'bi bigint NULL DEFAULT NULL', + 22 => 'int_col int NULL DEFAULT NULL', + 23 => 'int_col_2 integer NULL DEFAULT NULL', + 24 => 'numeric_col numeric NULL DEFAULT NULL', + 25 => 'float_col float NULL DEFAULT NULL', + 26 => 'float_2 float(10, 2) NULL DEFAULT NULL', + 27 => 'float_3 float(8) NULL DEFAULT NULL', + 28 => 'double_col double NULL DEFAULT NULL', + 29 => 'double_p double precision(10,2) NULL DEFAULT NULL', + 30 => 'double_p_2 double precision NULL DEFAULT NULL', + 31 => 'real_col real NULL DEFAULT NULL', + 32 => 'date_col date NULL DEFAULT NULL', + 33 => 'time_col time NULL DEFAULT NULL', + 34 => 'datetime_col datetime NULL DEFAULT NULL', + 35 => 'timestamp_col timestamp NULL DEFAULT NULL', + 36 => 'year_col year NULL DEFAULT NULL', + 37 => 'json_col json NOT NULL', + 38 => 'json_col_def json NOT NULL DEFAULT \'[]\'', + 39 => 'json_col_def_2 json NOT NULL DEFAULT \'[]\'', + 40 => 'blob_def blob NULL DEFAULT \'the blob\'', + 41 => 'text_def text NULL DEFAULT \'the text\'', + 42 => 'json_def json NOT NULL DEFAULT \'{"a":"b"}\'', + ]); + } + + public function down() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000001_create_table_editcolumns.php b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000001_create_table_editcolumns.php new file mode 100644 index 00000000..1de3d8d5 --- /dev/null +++ b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000001_create_table_editcolumns.php @@ -0,0 +1,30 @@ +createTable('{{%editcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL DEFAULT \'Horse-2\'', + 'tag' => $this->text()->null()->defaultValue(null), + 1 => 'first_name varchar(255) NULL DEFAULT NULL', + 'string_col' => $this->text()->null()->defaultValue(null), + 2 => 'dec_col decimal(12,2) NULL DEFAULT 3.14', + 3 => 'str_col_def varchar(3) NOT NULL', + 4 => 'json_col text NOT NULL DEFAULT \'fox jumps over dog\'', + 5 => 'json_col_2 json NOT NULL DEFAULT \'[]\'', + 6 => 'numeric_col double precision NULL DEFAULT NULL', + 7 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + 8 => 'json_col_def_n_2 json NOT NULL DEFAULT \'[]\'', + ]); + } + + public function down() + { + $this->dropTable('{{%editcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000002_change_table_newcolumns.php b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000002_change_table_newcolumns.php new file mode 100644 index 00000000..ab740adb --- /dev/null +++ b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000002_change_table_newcolumns.php @@ -0,0 +1,27 @@ +db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN dec_col decimal(12,4) NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN json_col json NOT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN json_col_def_n json NOT NULL DEFAULT \'[]\'')->execute(); + $this->addColumn('{{%newcolumns}}', 'last_name', $this->text()->null()->defaultValue(null)); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN numeric_col double precision NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN varchar_col varchar(5) NULL DEFAULT NULL')->execute(); + } + + public function down() + { + $this->dropColumn('{{%newcolumns}}', 'varchar_col'); + $this->dropColumn('{{%newcolumns}}', 'numeric_col'); + $this->dropColumn('{{%newcolumns}}', 'last_name'); + $this->dropColumn('{{%newcolumns}}', 'json_col_def_n'); + $this->dropColumn('{{%newcolumns}}', 'json_col'); + $this->dropColumn('{{%newcolumns}}', 'dec_col'); + } +} diff --git a/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..4d1b1590 --- /dev/null +++ b/tests/specs/x_db_type/new_column/maria/app/migrations_maria_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col integer primary key auto_increment NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null()->defaultValue("4 leg"), + 2 => 'new_col varchar(17) NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar(9) NULL DEFAULT NULL', + 8 => 'col_10 varchar(10) NULL DEFAULT NULL', + 9 => 'col_11 text NULL DEFAULT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..2cda660f --- /dev/null +++ b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,62 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar(255) NULL DEFAULT NULL', + 1 => 'varchar_col varchar(132) NULL DEFAULT NULL', + 2 => 'text_col text NULL', + 3 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 4 => 'char_4_col char(4) NULL DEFAULT NULL', + 5 => 'char_5_col char NULL DEFAULT NULL', + 6 => 'char_6_col char NOT NULL', + 7 => 'char_7_col char(6) NOT NULL', + 8 => 'char_8_col char NULL DEFAULT \'d\'', + 9 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 10 => 'varbinary_col varbinary(5) NULL DEFAULT NULL', + 11 => 'blob_col blob NULL', + 12 => 'bit_col bit NULL DEFAULT NULL', + 13 => 'bit_2 bit(1) NULL DEFAULT NULL', + 14 => 'bit_3 bit(64) NULL DEFAULT NULL', + 15 => 'ti tinyint NULL DEFAULT NULL', + 16 => 'ti_2 tinyint(1) NULL DEFAULT NULL', + 17 => 'ti_3 tinyint(2) NULL DEFAULT NULL', + 18 => 'si_col smallint NULL DEFAULT NULL', + 19 => 'si_col_2 smallint unsigned zerofill NULL DEFAULT NULL', + 20 => 'mi mediumint(10) unsigned zerofill comment "comment" NULL DEFAULT 7', + 21 => 'bi bigint NULL DEFAULT NULL', + 22 => 'int_col int NULL DEFAULT NULL', + 23 => 'int_col_2 integer NULL DEFAULT NULL', + 24 => 'numeric_col numeric NULL DEFAULT NULL', + 25 => 'float_col float NULL DEFAULT NULL', + 26 => 'float_2 float(10, 2) NULL DEFAULT NULL', + 27 => 'float_3 float(8) NULL DEFAULT NULL', + 28 => 'double_col double NULL DEFAULT NULL', + 29 => 'double_p double precision(10,2) NULL DEFAULT NULL', + 30 => 'double_p_2 double precision NULL DEFAULT NULL', + 31 => 'real_col real NULL DEFAULT NULL', + 32 => 'date_col date NULL DEFAULT NULL', + 33 => 'time_col time NULL DEFAULT NULL', + 34 => 'datetime_col datetime NULL DEFAULT NULL', + 35 => 'timestamp_col timestamp NULL DEFAULT NULL', + 36 => 'year_col year NULL DEFAULT NULL', + 37 => 'json_col json NOT NULL', + 38 => 'json_col_def json NOT NULL', + 39 => 'json_col_def_2 json NOT NULL', + 40 => 'blob_def blob NULL', + 41 => 'text_def text NULL', + 42 => 'json_def json NOT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000001_create_table_editcolumns.php b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000001_create_table_editcolumns.php new file mode 100644 index 00000000..8c84e731 --- /dev/null +++ b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000001_create_table_editcolumns.php @@ -0,0 +1,30 @@ +createTable('{{%editcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(255) NOT NULL DEFAULT \'Horse-2\'', + 'tag' => $this->text()->null(), + 1 => 'first_name varchar(255) NULL DEFAULT NULL', + 'string_col' => $this->text()->null(), + 2 => 'dec_col decimal(12,2) NULL DEFAULT 3.14', + 3 => 'str_col_def varchar(3) NOT NULL', + 4 => 'json_col text NOT NULL', + 5 => 'json_col_2 json NOT NULL', + 6 => 'numeric_col double precision NULL DEFAULT NULL', + 7 => 'json_col_def_n json NOT NULL', + 8 => 'json_col_def_n_2 json NOT NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%editcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000002_change_table_newcolumns.php b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000002_change_table_newcolumns.php new file mode 100644 index 00000000..511195c2 --- /dev/null +++ b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000002_change_table_newcolumns.php @@ -0,0 +1,27 @@ +db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN dec_col decimal(12,4) NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN json_col json NOT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN json_col_def_n json NOT NULL')->execute(); + $this->addColumn('{{%newcolumns}}', 'last_name', $this->text()->null()); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN numeric_col double precision NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN varchar_col varchar(5) NULL DEFAULT NULL')->execute(); + } + + public function down() + { + $this->dropColumn('{{%newcolumns}}', 'varchar_col'); + $this->dropColumn('{{%newcolumns}}', 'numeric_col'); + $this->dropColumn('{{%newcolumns}}', 'last_name'); + $this->dropColumn('{{%newcolumns}}', 'json_col_def_n'); + $this->dropColumn('{{%newcolumns}}', 'json_col'); + $this->dropColumn('{{%newcolumns}}', 'dec_col'); + } +} diff --git a/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..aeed5fe1 --- /dev/null +++ b/tests/specs/x_db_type/new_column/mysql/app/migrations_mysql_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col integer primary key auto_increment NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null(), + 2 => 'new_col varchar(17) NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar(9) NULL DEFAULT NULL', + 8 => 'col_10 varchar(10) NULL DEFAULT NULL', + 9 => 'col_11 text NULL', + ]); + } + + public function down() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php new file mode 100644 index 00000000..53498798 --- /dev/null +++ b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000000_create_table_alldbdatatypes.php @@ -0,0 +1,112 @@ +createTable('{{%alldbdatatypes}}', [ + 'id' => $this->bigPrimaryKey(), + 0 => 'string_col varchar NULL DEFAULT NULL', + 1 => 'varchar_col varchar NULL DEFAULT NULL', + 2 => 'text_col text NULL DEFAULT NULL', + 3 => 'text_col_array text[] NULL DEFAULT NULL', + 4 => 'varchar_4_col varchar(4) NULL DEFAULT NULL', + 5 => 'varchar_5_col varchar(5) NULL DEFAULT NULL', + 6 => 'char_4_col char(4) NULL DEFAULT NULL', + 7 => 'char_5_col char NULL DEFAULT NULL', + 8 => 'char_6_col char NOT NULL', + 9 => 'char_7_col char(6) NOT NULL', + 10 => 'char_8_col char NULL DEFAULT \'d\'', + 11 => 'decimal_col decimal(12,3) NULL DEFAULT NULL', + 12 => 'bytea_col_2 bytea NULL DEFAULT NULL', + 13 => 'bit_col bit NULL DEFAULT NULL', + 14 => 'bit_2 bit(1) NULL DEFAULT NULL', + 15 => 'bit_3 bit(64) NULL DEFAULT NULL', + 16 => 'ti smallint NULL DEFAULT NULL', + 17 => 'int2_col int2 NULL DEFAULT NULL', + 18 => 'smallserial_col smallserial NOT NULL', + 19 => 'serial2_col serial2 NOT NULL', + 20 => 'si_col smallint NULL DEFAULT NULL', + 21 => 'si_col_2 smallint NULL DEFAULT NULL', + 22 => 'bi bigint NULL DEFAULT NULL', + 23 => 'bi2 int8 NULL DEFAULT NULL', + 24 => 'int4_col int4 NULL DEFAULT NULL', + 25 => 'bigserial_col bigserial NOT NULL', + 26 => 'bigserial_col_2 serial8 NOT NULL', + 27 => 'int_col int NULL DEFAULT NULL', + 28 => 'int_col_2 integer NULL DEFAULT NULL', + 29 => 'numeric_col numeric NULL DEFAULT NULL', + 30 => 'numeric_col_2 numeric(10) NULL DEFAULT NULL', + 31 => 'numeric_col_3 numeric(10,2) NULL DEFAULT NULL', + 32 => 'double_p_2 double precision NULL DEFAULT NULL', + 33 => 'double_p_3 double precision NULL DEFAULT NULL', + 34 => 'real_col real NULL DEFAULT NULL', + 35 => 'float4_col float4 NULL DEFAULT NULL', + 36 => 'date_col date NULL DEFAULT NULL', + 37 => 'time_col time NULL DEFAULT NULL', + 38 => 'time_col_2 time with time zone NULL DEFAULT NULL', + 39 => 'time_col_3 time without time zone NULL DEFAULT NULL', + 40 => 'time_col_4 time(3) without time zone NULL DEFAULT NULL', + 41 => 'timetz_col timetz NULL DEFAULT NULL', + 42 => 'timetz_col_2 timetz(3) NULL DEFAULT NULL', + 43 => 'timestamp_col timestamp NULL DEFAULT NULL', + 44 => 'timestamp_col_2 timestamp with time zone NULL DEFAULT NULL', + 45 => 'timestamp_col_3 timestamp without time zone NULL DEFAULT NULL', + 46 => 'timestamp_col_4 timestamp(3) without time zone NULL DEFAULT NULL', + 47 => 'timestamptz_col timestamptz NULL DEFAULT NULL', + 48 => 'timestamptz_col_2 timestamptz(3) NULL DEFAULT NULL', + 49 => 'date2 date NULL DEFAULT NULL', + 50 => 'timestamp_col_z timestamp NULL DEFAULT NULL', + 51 => 'bit_varying bit varying NULL DEFAULT NULL', + 52 => 'bit_varying_n bit varying(8) NULL DEFAULT NULL', + 53 => 'bit_varying_n_2 varbit NULL DEFAULT NULL', + 54 => 'bit_varying_n_3 varbit(3) NULL DEFAULT NULL', + 55 => 'bool_col boolean NULL DEFAULT NULL', + 56 => 'bool_col_2 bool NULL DEFAULT NULL', + 57 => 'box_col box NULL DEFAULT NULL', + 58 => 'character_col character NULL DEFAULT NULL', + 59 => 'character_n character(12) NULL DEFAULT NULL', + 60 => 'character_varying character varying NULL DEFAULT NULL', + 61 => 'character_varying_n character varying(12) NULL DEFAULT NULL', + 62 => 'json_col json NOT NULL', + 63 => 'jsonb_col jsonb NOT NULL', + 64 => 'json_col_def json NOT NULL DEFAULT \'[]\'', + 65 => 'json_col_def_2 json NOT NULL DEFAULT \'[]\'', + 66 => 'bytea_def bytea NULL DEFAULT \'the bytea blob default\'', + 67 => 'text_def text NULL DEFAULT \'the text\'', + 68 => 'json_def json NOT NULL DEFAULT \'{"a":"b"}\'', + 69 => 'jsonb_def jsonb NOT NULL DEFAULT \'{"ba":"bb"}\'', + 70 => 'cidr_col cidr NULL DEFAULT NULL', + 71 => 'circle_col circle NULL DEFAULT NULL', + 72 => 'date_col_z date NULL DEFAULT NULL', + 73 => 'float8_col float8 NULL DEFAULT NULL', + 74 => 'inet_col inet NULL DEFAULT NULL', + 75 => 'interval_col interval NULL DEFAULT NULL', + 76 => 'interval_col_2 interval year NULL DEFAULT NULL', + 77 => 'interval_col_3 interval day to second(3) NULL DEFAULT NULL', + 78 => 'line_col line NULL DEFAULT NULL', + 79 => 'lseg_col lseg NULL DEFAULT NULL', + 80 => 'macaddr_col macaddr NULL DEFAULT NULL', + 81 => 'money_col money NULL DEFAULT NULL', + 82 => 'path_col path NULL DEFAULT NULL', + 83 => 'pg_lsn_col pg_lsn NULL DEFAULT NULL', + 84 => 'point_col point NULL DEFAULT NULL', + 85 => 'polygon_col polygon NULL DEFAULT NULL', + 86 => 'serial_col serial NOT NULL', + 87 => 'serial4_col serial4 NOT NULL', + 88 => 'tsquery_col tsquery NULL DEFAULT NULL', + 89 => 'tsvector_col tsvector NULL', + 90 => 'txid_snapshot_col txid_snapshot NULL DEFAULT NULL', + 91 => 'uuid_col uuid NULL DEFAULT NULL', + 92 => 'xml_col xml NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%alldbdatatypes}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000001_create_table_editcolumns.php b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000001_create_table_editcolumns.php new file mode 100644 index 00000000..93111403 --- /dev/null +++ b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000001_create_table_editcolumns.php @@ -0,0 +1,31 @@ +createTable('{{%editcolumns}}', [ + 'id' => $this->primaryKey(), + 0 => 'name varchar(254) NOT NULL DEFAULT \'Horse-2\'', + 'tag' => $this->text()->null()->defaultValue(null), + 1 => 'first_name varchar NULL DEFAULT NULL', + 'string_col' => $this->text()->null()->defaultValue(null), + 2 => 'dec_col decimal(12,2) NULL DEFAULT 3.14', + 3 => 'str_col_def varchar NOT NULL', + 4 => 'json_col text NOT NULL DEFAULT \'fox jumps over dog\'', + 5 => 'json_col_2 json NOT NULL DEFAULT \'[]\'', + 6 => 'numeric_col double precision NULL DEFAULT NULL', + 7 => 'json_col_def_n json NOT NULL DEFAULT \'[]\'', + 8 => 'json_col_def_n_2 json NOT NULL DEFAULT \'[]\'', + 9 => 'text_col_array text[] NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%editcolumns}}'); + } +} diff --git a/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000002_change_table_newcolumns.php b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000002_change_table_newcolumns.php new file mode 100644 index 00000000..72747e62 --- /dev/null +++ b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000002_change_table_newcolumns.php @@ -0,0 +1,33 @@ +db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN dec_col decimal(12,4) NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN first_name varchar NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN json_col json NOT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN json_col_def_n json NOT NULL DEFAULT \'[]\'')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN json_col_def_n_2 json NOT NULL DEFAULT \'[]\'')->execute(); + $this->addColumn('{{%newcolumns}}', 'last_name', $this->text()->null()->defaultValue(null)); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN numeric_col double precision NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN text_col_array text[] NULL DEFAULT NULL')->execute(); + $this->db->createCommand('ALTER TABLE {{%newcolumns}} ADD COLUMN varchar_col varchar NULL DEFAULT NULL')->execute(); + } + + public function safeDown() + { + $this->dropColumn('{{%newcolumns}}', 'varchar_col'); + $this->dropColumn('{{%newcolumns}}', 'text_col_array'); + $this->dropColumn('{{%newcolumns}}', 'numeric_col'); + $this->dropColumn('{{%newcolumns}}', 'last_name'); + $this->dropColumn('{{%newcolumns}}', 'json_col_def_n_2'); + $this->dropColumn('{{%newcolumns}}', 'json_col_def_n'); + $this->dropColumn('{{%newcolumns}}', 'json_col'); + $this->dropColumn('{{%newcolumns}}', 'first_name'); + $this->dropColumn('{{%newcolumns}}', 'dec_col'); + } +} diff --git a/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php new file mode 100644 index 00000000..e4090b6d --- /dev/null +++ b/tests/specs/x_db_type/new_column/pgsql/app/migrations_pgsql_db/m200000_000003_create_table_pristines.php @@ -0,0 +1,29 @@ +createTable('{{%pristines}}', [ + 0 => 'custom_id_col serial primary key NOT NULL', + 1 => 'name text NOT NULL', + 'tag' => $this->text()->null()->defaultValue("4 leg"), + 2 => 'new_col varchar NULL DEFAULT NULL', + 3 => 'col_5 decimal(12,4) NULL DEFAULT NULL', + 4 => 'col_6 decimal(11,2) NULL DEFAULT NULL', + 5 => 'col_7 decimal(10,2) NULL DEFAULT NULL', + 6 => 'col_8 json NOT NULL', + 7 => 'col_9 varchar NULL DEFAULT NULL', + 8 => 'col_10 varchar NULL DEFAULT NULL', + 9 => 'col_11 text NULL DEFAULT NULL', + ]); + } + + public function safeDown() + { + $this->dropTable('{{%pristines}}'); + } +} diff --git a/tests/unit/AttributeResolverTest.php b/tests/unit/AttributeResolverTest.php index b144900c..124b56e4 100644 --- a/tests/unit/AttributeResolverTest.php +++ b/tests/unit/AttributeResolverTest.php @@ -10,12 +10,12 @@ use cebe\yii2openapi\lib\items\JunctionSchemas; use cebe\yii2openapi\lib\items\ManyToManyRelation; use cebe\yii2openapi\lib\openapi\ComponentSchema; -use tests\TestCase; +use tests\DbTestCase; use Yii; use yii\helpers\VarDumper; use const PHP_EOL; -class AttributeResolverTest extends TestCase +class AttributeResolverTest extends DbTestCase { public function testManyToManyResolve() { diff --git a/tests/unit/FakerStubResolverTest.php b/tests/unit/FakerStubResolverTest.php index 0aeec365..0b8ebcbc 100644 --- a/tests/unit/FakerStubResolverTest.php +++ b/tests/unit/FakerStubResolverTest.php @@ -97,11 +97,11 @@ public function dataProvider() $schema->getProperty('int_minmax'), '$faker->numberBetween(5, 25)', ], - [ - (new Attribute('uuid'))->setPhpType('string')->setDbType('uuid'), - $schema->getProperty('uuid'), - '$faker->uuid', - ], + // [ + // (new Attribute('uuid'))->setPhpType('string')->setDbType('uuid'), + // $schema->getProperty('uuid'), + // '$faker->uuid', + // ], [ (new Attribute('str_text'))->setPhpType('string')->setDbType(YiiDbSchema::TYPE_TEXT), $schema->getProperty('str_text'), diff --git a/tests/unit/GeneratorTest.php b/tests/unit/GeneratorTest.php index e292a682..1bede214 100644 --- a/tests/unit/GeneratorTest.php +++ b/tests/unit/GeneratorTest.php @@ -4,12 +4,14 @@ use cebe\yii2openapi\generator\ApiGenerator; use tests\TestCase; +use tests\DbTestCase; use Yii; use yii\helpers\FileHelper; use yii\helpers\StringHelper; use function strpos; -class GeneratorTest extends TestCase +// class GeneratorTest extends TestCase +class GeneratorTest extends DbTestCase { public function provideTestcases() { @@ -33,7 +35,15 @@ public function testGenerate($testFile) $this->prepareTempDir(); - $this->mockApplication($this->mockDbSchemaAsEmpty()); + $this->mockApplication(); + // $this->mockApplication($this->mockDbSchemaAsEmpty()); + + if ($testFile === '/app/tests/specs/postgres_custom.php' || + $testFile === '/app/tests/specs/menu.php' + ) { // TODO docs + add separate tests for this + refactor tests + $dbo = Yii::$app->db; + Yii::$app->set('db', Yii::$app->pgsql); + } $generator = $this->createGenerator($testFile); $this->assertTrue($generator->validate(), print_r($generator->getErrors(), true)); @@ -43,6 +53,20 @@ public function testGenerate($testFile) $file->save(); } + // TODO docs + add separate tests for this + refactor tests + if ($testFile === '/app/tests/specs/blog_v2.php') { + FileHelper::removeDirectory('/app/tests/tmp/docker_app/migrations_mysql_db'); + FileHelper::removeDirectory('/app/tests/tmp/docker_app/migrations'); + FileHelper::createDirectory('/app/tests/tmp/docker_app/migrations'); + FileHelper::copyDirectory('/app/tests/specs/blog_v2/migrations', '/app/tests/tmp/docker_app/migrations'); + } + if ($testFile === '/app/tests/specs/postgres_custom.php') { + FileHelper::removeDirectory('/app/tests/tmp/docker_app/migrations_pgsql_db'); + FileHelper::removeDirectory('/app/tests/tmp/docker_app/migrations'); + FileHelper::createDirectory('/app/tests/tmp/docker_app/migrations'); + FileHelper::copyDirectory('/app/tests/specs/postgres_custom/migrations', '/app/tests/tmp/docker_app/migrations'); + } + $expectedFiles = array_map(function($file) use ($testFile) { return '@app' . substr($file, strlen($testFile) - 4); }, @@ -52,7 +76,7 @@ public function testGenerate($testFile) }, FileHelper::findFiles(Yii::getAlias('@app'), ['recursive' => true])); - //Skip database-specific migrations and json-api controllers + // Skip database-specific migrations and json-api controllers $expectedFiles = array_filter($expectedFiles, function($file) { return strpos($file, 'migrations_') === false && strpos($file, 'jsonapi') === false; @@ -73,6 +97,12 @@ function($file) { $this->assertFileExists($actualFile); $this->assertFileEquals($expectedFile, $actualFile, "Failed asserting that file contents of\n$actualFile\nare equal to file contents of\n$expectedFile"); } + + if ($testFile === '/app/tests/specs/postgres_custom.php' || + $testFile === '/app/tests/specs/menu.php' + ) { + Yii::$app->set('db', $dbo); // Mysql is default so set it back + } } protected function createGenerator($configFile) diff --git a/tests/unit/MigrationsGeneratorTest.php b/tests/unit/MigrationsGeneratorTest.php index 118ba34c..7d14479e 100644 --- a/tests/unit/MigrationsGeneratorTest.php +++ b/tests/unit/MigrationsGeneratorTest.php @@ -10,6 +10,7 @@ use cebe\yii2openapi\lib\items\MigrationModel; use cebe\yii2openapi\lib\migrations\MigrationRecordBuilder; use tests\TestCase; +use tests\DbTestCase; use Yii; use yii\db\Schema; use yii\db\TableSchema; @@ -17,18 +18,20 @@ use function count; use function preg_replace; -class MigrationsGeneratorTest extends TestCase +class MigrationsGeneratorTest extends DbTestCase { public function testNoMigrations() { $this->prepareTempDir(); - $this->mockApplication($this->mockDbSchemaAsEmpty()); + // $this->mockApplication($this->mockDbSchemaAsEmpty()); + $this->mockApplication(); $model = new DbModel(['name' => 'dummy', 'tableName' => 'dummy', 'attributes' => []]); $generator = new MigrationsGenerator(new Config(), [$model], Yii::$app->db); $migrations = $generator->buildMigrations(); self::assertEmpty($migrations); } + /** * @dataProvider simpleDbModelsProvider * @param array|DbModel[] $dbModels @@ -38,7 +41,9 @@ public function testNoMigrations() public function testGenerateSimple(array $dbModels, array $expected):void { $this->prepareTempDir(); - $this->mockApplication($this->mockDbSchemaAsEmpty()); + // $this->mockApplication($this->mockDbSchemaAsEmpty()); + // $this->mockRealApplication(); + $this->mockApplication(); $generator = new MigrationsGenerator(new Config(), $dbModels, Yii::$app->db); $models = $generator->buildMigrations(); $model = \array_values($models)[0]; @@ -64,6 +69,56 @@ public function tableSchemaStub(string $tableName):?TableSchema } public function simpleDbModelsProvider():array + { + $dbModel = new DbModel([ + 'name' => 'dummy', + 'tableName' => 'dummy', + 'attributes' => [ + (new Attribute('id'))->setPhpType('int')->setDbType(Schema::TYPE_PK) + ->setRequired(true)->setReadOnly(true), + (new Attribute('title'))->setPhpType('string') + ->setDbType('string') + ->setSize(60) + ->setRequired(true), + (new Attribute('article'))->setPhpType('string')->setDbType('text'), // for Mysql default in text data type is not allowed + ], + 'indexes'=> [ + 'dummy_title_index' => DbIndex::make('dummy', ['title']), + 'dummy_article_hash_index' => DbIndex::make('dummy', ['article'], 'hash'), + 'dummy_article_key' => DbIndex::make('dummy', ['article'], null, true), + ] + ]); + $codes = str_replace(PHP_EOL, + PHP_EOL . MigrationRecordBuilder::INDENT, + VarDumper::export([ + 'id' => '$this->primaryKey()', + 'title' => '$this->string(60)->notNull()', + 'article' => '$this->text()->null()', + ])); + $expect = new MigrationModel($dbModel, true, null, [ + 'dependencies' => [], + 'upCodes' => [ + "\$this->createTable('{{%dummy}}', $codes);", + "\$this->createIndex('dummy_title_index', '{{%dummy}}', 'title', false);", + "\$this->createIndex('dummy_article_hash_index', '{{%dummy}}', 'article', 'hash');", + "\$this->createIndex('dummy_article_key', '{{%dummy}}', 'article', true);", + ], + 'downCodes' => [ + "\$this->dropIndex('dummy_article_key', '{{%dummy}}');", + "\$this->dropIndex('dummy_article_hash_index', '{{%dummy}}');", + "\$this->dropIndex('dummy_title_index', '{{%dummy}}');", + "\$this->dropTable('{{%dummy}}');", + ], + ]); + return [ + [ + [$dbModel], + [$expect], + ], + ]; + } + + public function simpleDbModelsProviderForNonMysqlDb():array { $dbModel = new DbModel([ 'name' => 'dummy', @@ -112,4 +167,45 @@ public function simpleDbModelsProvider():array ], ]; } + + /** + * TODO refactor + * @dataProvider simpleDbModelsProviderForNonMysqlDb + * @param array|DbModel[] $dbModels + * @param array|MigrationModel[] $expected + * @throws \Exception + */ + public function testGenerateSimpleNonMysql(array $dbModels, array $expected):void + { + $this->prepareTempDir(); + // $this->mockApplication($this->mockDbSchemaAsEmpty()); + // $this->mockRealApplication(); + $this->mockApplication(); + foreach(['maria', 'pgsql'] as $database) { + if ($database === 'maria') { + $this->changeDbToMariadb(); + } + if ($database === 'pgsql') { + $this->changeDbToPgsql(); + } + $generator = new MigrationsGenerator(new Config(), $dbModels, Yii::$app->{$database}); + // var_dump(Yii::$app->db); die; + $models = $generator->buildMigrations(); + // var_dump($models); die; + $model = \array_values($models)[0]; + self::assertInstanceOf(MigrationModel::class, $model); + self::assertEquals($expected[0]->fileName, $model->fileName); + self::assertEquals($expected[0]->dependencies, $model->dependencies); + self::assertCount(count($expected[0]->upCodes), $model->upCodes); + self::assertCount(count($expected[0]->downCodes), $model->downCodes); + self::assertEquals( + preg_replace('~\s{1,}~',' ',trim($expected[0]->getUpCodeString())), + preg_replace('~\s{1,}~',' ',trim($model->getUpCodeString())) + ); + self::assertEquals( + preg_replace('~\s{1,}~',' ',trim($expected[0]->getDownCodeString())), + preg_replace('~\s{1,}~',' ',trim($model->getDownCodeString())) + ); + } + } } diff --git a/tests/unit/PropertySchemaTest.php b/tests/unit/PropertySchemaTest.php index 6b71dd04..417d91fd 100644 --- a/tests/unit/PropertySchemaTest.php +++ b/tests/unit/PropertySchemaTest.php @@ -6,10 +6,10 @@ use cebe\openapi\spec\OpenApi; use cebe\yii2openapi\lib\openapi\PropertySchema; use cebe\yii2openapi\lib\openapi\ComponentSchema; -use tests\TestCase; +use tests\DbTestCase; use Yii; -class PropertySchemaTest extends TestCase +class PropertySchemaTest extends DbTestCase { public function testPkProperty() { @@ -21,7 +21,7 @@ public function testPkProperty() self::assertEquals('uid', $prop->getName()); self::assertEquals(null, $prop->guessDefault()); self::assertEquals('string', $prop->guessPhpType()); - self::assertEquals('string', $prop->guessDbType()); + self::assertEquals('varchar', $prop->guessDbType()); self::assertEquals([null, null], $prop->guessMinMax()); self::assertEquals(128, $prop->getMaxLength()); self::assertEquals(null, $prop->getMinLength()); @@ -43,7 +43,6 @@ public function testSimpleProperty() self::assertEquals(null, $prop->getMaxLength()); self::assertEquals(null, $prop->getMinLength()); self::assertEquals(false, $prop->isReadonly()); - self::assertFalse($prop->hasEnum()); } public function testRefProperty() @@ -157,4 +156,4 @@ private function getSchema():ComponentSchema $openApi = Reader::readFromYamlFile($schemaFile, OpenApi::class, false); return new ComponentSchema($openApi->components->schemas['Post'], 'Post'); } -} \ No newline at end of file +} diff --git a/tests/unit/ValidatorRulesBuilderTest.php b/tests/unit/ValidatorRulesBuilderTest.php index dbad43b9..86e4d832 100644 --- a/tests/unit/ValidatorRulesBuilderTest.php +++ b/tests/unit/ValidatorRulesBuilderTest.php @@ -28,7 +28,6 @@ public function testBuild() (new Attribute('active'))->setPhpType('bool')->setDbType('boolean'), (new Attribute('category'))->asReference('Category') ->setRequired(true)->setPhpType('int')->setDbType('integer'), - (new Attribute('state'))->setPhpType('string')->setDbType('string')->setEnumValues(['active', 'draft']), (new Attribute('created_at'))->setPhpType('string')->setDbType('datetime'), (new Attribute('contact_email'))->setPhpType('string')->setDbType('string'), (new Attribute('required_with_def'))->setPhpType('string') @@ -42,7 +41,6 @@ public function testBuild() 'trim' => new ValidationRule([ 'title', 'article', - 'state', 'created_at', 'contact_email', 'required_with_def', @@ -57,8 +55,6 @@ public function testBuild() 'title_string' => new ValidationRule(['title'], 'string', ['max' => 60]), 'article_string' => new ValidationRule(['article'], 'string'), 'active_boolean' => new ValidationRule(['active'], 'boolean'), - 'state_string' => new ValidationRule(['state'], 'string'), - 'state_in' => new ValidationRule(['state'], 'in', ['range' => ['active', 'draft']]), 'created_at_datetime' => new ValidationRule(['created_at'], 'datetime'), 'contact_email_string' => new ValidationRule(['contact_email'], 'string'), 'contact_email_email' => new ValidationRule(['contact_email'], 'email'), diff --git a/tests/unit/XDbTypeTest.php b/tests/unit/XDbTypeTest.php new file mode 100644 index 00000000..223a782b --- /dev/null +++ b/tests/unit/XDbTypeTest.php @@ -0,0 +1,205 @@ +deleteTables(); + $testFile = Yii::getAlias("@specs/x_db_type/fresh/mysql/x_db_type_mysql.php"); + $this->runGenerator($testFile, 'mysql'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_maria_db', 'migrations_pgsql_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/fresh/mysql/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + + // same yaml file is used for MySQL and MariaDB ---------------------- + $this->changeDbToMariadb(); + $this->deleteTables(); + $testFile = Yii::getAlias("@specs/x_db_type/fresh/mysql/x_db_type_mysql.php"); + $this->runGenerator($testFile, 'maria'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_mysql_db', 'migrations_pgsql_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/fresh/maria/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + + // PgSQL ------------------------------------------------ + $this->changeDbToPgsql(); + $this->deleteTables(); + $testFile = Yii::getAlias("@specs/x_db_type/fresh/pgsql/x_db_type_pgsql.php"); + $this->runGenerator($testFile, 'pgsql'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_mysql_db', 'migrations_maria_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/fresh/pgsql/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + } + + public function testXDbTypeSecondaryWithNewColumn() // v2 + { + $this->deleteTables(); + $this->createTableForNewColumns(); + // same yaml file is used as of 'fresh'. Instead of changing the yaml we create new table in db with certain specific columns and then run API generator + $testFile = Yii::getAlias("@specs/x_db_type/fresh/mysql/x_db_type_mysql.php"); + $this->runGenerator($testFile, 'mysql'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_maria_db', 'migrations_pgsql_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/new_column/mysql/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + + // same yaml file is used for MySQL and MariaDB ---------------------- + $this->changeDbToMariadb(); + $this->deleteTables(); + $this->createTableForNewColumns(); + // same yaml file is used as of 'fresh'. Instead of changing the yaml we create new table in db with certain specific columns and then run API generator + $testFile = Yii::getAlias("@specs/x_db_type/fresh/mysql/x_db_type_mysql.php"); + $this->runGenerator($testFile, 'maria'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_mysql_db', 'migrations_pgsql_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/new_column/maria/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + + // PgSQL ------------------------------------------------ + $this->changeDbToPgsql(); + $this->deleteTables(); + $this->createTableForNewColumns(); + // same yaml file is used as of 'fresh'. Instead of changing the yaml we create new table in db with certain specific columns and then run API generator + $testFile = Yii::getAlias("@specs/x_db_type/fresh/pgsql/x_db_type_pgsql.php"); + $this->runGenerator($testFile, 'pgsql'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_mysql_db', 'migrations_maria_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/new_column/pgsql/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + } + + public function testXDbTypeSecondaryWithEditColumn() // v3 + { + $this->deleteTables(); + $this->createTableForEditColumns(); + // same yaml file is used as of 'fresh'. Instead of changing the yaml we create new table in db with certain specific columns and then run API generator + $testFile = Yii::getAlias("@specs/x_db_type/fresh/mysql/x_db_type_mysql.php"); + $this->runGenerator($testFile, 'mysql'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_maria_db', 'migrations_pgsql_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/edit_column/mysql/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + + // same yaml file is used for MySQL and MariaDB ---------------------- + $this->changeDbToMariadb(); + $this->deleteTables(); + $this->createTableForEditColumns(); + // same yaml file is used as of 'fresh'. Instead of changing the yaml we create new table in db with certain specific columns and then run API generator + $testFile = Yii::getAlias("@specs/x_db_type/fresh/mysql/x_db_type_mysql.php"); + $this->runGenerator($testFile, 'maria'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_mysql_db', 'migrations_pgsql_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/edit_column/maria/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + + // PgSQL ------------------------------------------------ + $this->changeDbToPgsql(); + $this->deleteTables(); + $this->createTableForEditColumns(); + // same yaml file is used as of 'fresh'. Instead of changing the yaml we create new table in db with certain specific columns and then run API generator + $testFile = Yii::getAlias("@specs/x_db_type/fresh/pgsql/x_db_type_pgsql.php"); + $this->runGenerator($testFile, 'pgsql'); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + 'except' => ['migrations_mysql_db', 'migrations_maria_db'] + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/x_db_type/edit_column/pgsql/app"), [ + 'recursive' => true, + ]); + $this->compareFiles($actualFiles, $expectedFiles); + } + + protected function compareFiles(array $actual, array $expected) + { + self::assertEquals( + count($actual), + count($expected) + ); + foreach ($actual as $index => $file) { + $expectedFilePath = $expected[$index]; + self::assertFileExists($file); + self::assertFileExists($expectedFilePath); + + $this->assertFileEquals($expectedFilePath, $file, "Failed asserting that file contents of\n$file\nare equal to file contents of\n$expectedFilePath"); + } + } + + private function deleteTables() + { + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%pristines}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%newcolumns}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%editcolumns}}')->execute(); + Yii::$app->db->createCommand('DROP TABLE IF EXISTS {{%alldbdatatypes}}')->execute(); + } + + private function createTableForNewColumns() + { + Yii::$app->db->createCommand()->createTable('{{%newcolumns}}', [ + 'id' => 'pk', + 'name' => 'string not null', + ])->execute(); + } + + private function createTableForEditColumns() + { + Yii::$app->db->createCommand()->createTable('{{%editcolumns}}', [ + 'id' => 'pk', + 'name' => 'varchar(255) not null default \'Horse\'', + 'tag' => 'text null', + 'string_col' => 'string not null', + 'dec_col' => 'decimal(12, 4)', + 'str_col_def' => 'string default \'hi there\'', + 'json_col' => 'json', + 'json_col_2' => 'json', + 'numeric_col' => 'integer', + ])->execute(); + } +}