Skip to content

Commit a6d8786

Browse files
authored
Do not generate ENUM types on postgres if x-db-type is specified for the enum column (cebe#174)
fixes cebe#173
2 parents 70a449f + 705714e commit a6d8786

File tree

45 files changed

+122
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+122
-88
lines changed

src/lib/ColumnToCode.php

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public function getCode(bool $quoted = false):string
169169
$default = '';
170170
} elseif (ApiGenerator::isPostgres() && $this->isEnum()) {
171171
$default =
172-
$this->rawParts['default'] !== null ? ' DEFAULT ' . self::escapeQuotes(trim($this->rawParts['default'])) : '';
172+
$this->rawParts['default'] !== null ? ' DEFAULT ' . trim($this->rawParts['default']) : '';
173173
} else {
174174
$default = $this->rawParts['default'] !== null ? ' DEFAULT ' . trim($this->rawParts['default']) : '';
175175
}
@@ -178,13 +178,10 @@ public function getCode(bool $quoted = false):string
178178
if ((ApiGenerator::isMysql() || ApiGenerator::isMariaDb()) && $this->rawParts['position']) {
179179
$code .= ' ' . $this->rawParts['position'];
180180
}
181-
if ((ApiGenerator::isMysql() || ApiGenerator::isMariaDb()) && $this->isEnum()) {
182-
return $quoted ? "'" . $code . "'" : $code;
183-
}
184181
if (ApiGenerator::isPostgres() && $this->alterByXDbType) {
185-
return $quoted ? "'" . $this->rawParts['type'] . "'" : $this->rawParts['type'];
182+
return $quoted ? VarDumper::export($this->rawParts['type']) : $this->rawParts['type'];
186183
}
187-
return $quoted ? "'" . $code . "'" : $code;
184+
return $quoted ? VarDumper::export($code) : $code;
188185
}
189186

190187
public function getAlterExpression(bool $addUsingExpression = false):string
@@ -226,7 +223,7 @@ public function isJson():bool
226223

227224
public function isEnum():bool
228225
{
229-
return !empty($this->column->enumValues);
226+
return BaseMigrationBuilder::isEnum($this->column);
230227
}
231228

232229
public function isDecimal()
@@ -313,14 +310,14 @@ public static function mysqlEnumToString(array $enum):string
313310
private function defaultValueJson(array $value):string
314311
{
315312
if ($this->alter === true) {
316-
return "'" . str_replace('"', '\"', Json::encode($value)). "'";
313+
return "'" . str_replace('"', '\"', Json::encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT)) . "'";
317314
}
318-
return "\\'" . new Expression(Json::encode($value)) . "\\'";
315+
return "'" . Json::encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT) . "'";
319316
}
320317

321318
private function defaultValueArray(array $value):string
322319
{
323-
return "'{" . str_replace('"', "\"", trim(Json::encode($value), '[]')) . "}'";
320+
return "'{" . trim(Json::encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT), '[]') . "}'";
324321
}
325322

326323
private function resolve():void
@@ -442,10 +439,10 @@ private function resolveDefaultValue():void
442439
break;
443440
case 'object':
444441
if ($value instanceof JsonExpression) {
445-
$this->fluentParts['default'] = "defaultValue('" . Json::encode($value->getValue()) . "')";
442+
$this->fluentParts['default'] = "defaultValue('" . Json::encode($value->getValue(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT) . "')";
446443
$this->rawParts['default'] = $this->defaultValueJson($value->getValue());
447444
} elseif ($value instanceof ArrayExpression) {
448-
$this->fluentParts['default'] = "defaultValue('" . Json::encode($value->getValue()) . "')";
445+
$this->fluentParts['default'] = "defaultValue('" . Json::encode($value->getValue(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT) . "')";
449446
$this->rawParts['default'] = $this->defaultValueArray($value->getValue());
450447
} else {
451448
// $value instanceof \yii\db\Expression
@@ -454,19 +451,15 @@ private function resolveDefaultValue():void
454451
}
455452
break;
456453
case 'array':
457-
$this->fluentParts['default'] = "defaultValue('" . Json::encode($value) . "')";
454+
$this->fluentParts['default'] = "defaultValue('" . Json::encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT) . "')";
458455
$this->rawParts['default'] = $this->isJson()
459456
? $this->defaultValueJson($value)
460457
: $this->defaultValueArray($value);
461458
break;
462459
default:
463460
$this->fluentParts['default'] = $expectInteger
464-
? 'defaultValue(' . $value . ')' : 'defaultValue("' . self::escapeQuotes((string)$value) . '")';
465-
$this->rawParts['default'] = $expectInteger ? $value : self::wrapQuotes($value);
466-
467-
if ((ApiGenerator::isMysql() || ApiGenerator::isMariaDb()) && $this->isEnum()) {
468-
$this->rawParts['default'] = self::escapeQuotes($this->rawParts['default']);
469-
}
461+
? 'defaultValue(' . $value . ')' : 'defaultValue(' . VarDumper::export((string)$value) . ')';
462+
$this->rawParts['default'] = $expectInteger ? $value : VarDumper::export((string)$value);
470463
}
471464
}
472465

src/lib/migrations/BaseMigrationBuilder.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,7 @@ public function newColStr(string $tableAlias, \cebe\yii2openapi\db\ColumnSchema
479479

480480
public static function isEnum(\yii\db\ColumnSchema $columnSchema): bool
481481
{
482-
if (!empty($columnSchema->enumValues) && is_array($columnSchema->enumValues)) {
483-
return true;
484-
}
485-
return false;
482+
return !empty($columnSchema->enumValues) && is_array($columnSchema->enumValues) && empty($columnSchema->xDbType);
486483
}
487484

488485
public static function isEnumValuesChanged(

src/lib/migrations/MigrationRecordBuilder.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public function addColumn(string $tableAlias, ColumnSchema $column, ?string $pos
8888
if (is_string($column->xDbType) && !empty($column->xDbType)) {
8989
$converter = $this->columnToCode($tableAlias, $column, false, false, false, false, $position);
9090
$name = static::quote($column->name);
91-
return sprintf(self::ADD_COLUMN_RAW, $tableAlias, $name, $converter->getCode());
91+
return sprintf(self::ADD_COLUMN_RAW, $tableAlias, $name, ColumnToCode::escapeQuotes($converter->getCode()));
9292
}
9393

9494
$converter = $this->columnToCode($tableAlias, $column, false, false, false, false, $position);
@@ -103,7 +103,7 @@ public function addDbColumn(string $tableAlias, ColumnSchema $column, ?string $p
103103
if (property_exists($column, 'xDbType') && is_string($column->xDbType) && !empty($column->xDbType)) {
104104
$converter = $this->columnToCode($tableAlias, $column, true, false, false, false, $position);
105105
$name = static::quote($column->name);
106-
return sprintf(self::ADD_COLUMN_RAW, $tableAlias, $column->name, $converter->getCode());
106+
return sprintf(self::ADD_COLUMN_RAW, $tableAlias, $column->name, ColumnToCode::escapeQuotes($converter->getCode()));
107107
}
108108
$converter = $this->columnToCode($tableAlias, $column, true, false, false, false, $position);
109109
return sprintf(self::ADD_COLUMN, $tableAlias, $column->name, $converter->getCode(true));
@@ -120,7 +120,7 @@ public function alterColumn(string $tableAlias, ColumnSchema $column):string
120120
ApiGenerator::isPostgres() ? self::ALTER_COLUMN_RAW_PGSQL : self::ALTER_COLUMN_RAW,
121121
$tableAlias,
122122
$column->name,
123-
$converter->getCode()
123+
ColumnToCode::escapeQuotes($converter->getCode())
124124
);
125125
}
126126
$converter = $this->columnToCode($tableAlias, $column, true);
@@ -340,7 +340,7 @@ public static function makeString(array $codeColumns): string
340340
}
341341
}
342342

343-
$codeColumns = str_replace([PHP_EOL, "\\\'"], [PHP_EOL . self::INDENT.' ', "'"], $finalStr);
343+
$codeColumns = str_replace([PHP_EOL], [PHP_EOL . self::INDENT.' '], $finalStr);
344344
$codeColumns = trim($codeColumns);
345345
$codeColumns = '['.PHP_EOL.self::INDENT.' '.$codeColumns.PHP_EOL . self::INDENT.']';
346346
return $codeColumns;

src/lib/migrations/PostgresMigrationBuilder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ protected function createEnumMigrations():void
147147
$tableAlias = $this->model->getTableAlias();
148148
$enums = $this->model->getEnumAttributes();
149149
foreach ($enums as $attr) {
150+
if (!empty($attr->xDbType)) {
151+
// do not generate enum types when custom x-db-type is used
152+
continue;
153+
}
150154
$this->migration
151155
->addUpCode($this->recordBuilder->createEnum($tableAlias, $attr->columnName, $attr->enumValues), true)
152156
->addDownCode($this->recordBuilder->dropEnum($tableAlias, $attr->columnName), true);

tests/migrations/m100000_000000_pgsql.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public function safeUp()
103103
'json3' => $this->json()->defaultValue(Json::encode(['foo' => 'bar', 'bar' => 'baz'])),
104104
'json4' => "json DEFAULT '" . new Expression(Json::encode(['ffo' => 'bar'])) . "'",
105105
'status' => '"'.$enumTypeName.'"',
106+
'status_x' => 'varchar(10)',
106107
'search' => 'tsvector'
107108
]);
108109
$columns = [

tests/specs/blog/migrations/m200000_000001_create_table_users.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function up()
1212
'username' => $this->string(200)->notNull(),
1313
'email' => $this->string(200)->notNull(),
1414
'password' => $this->string()->notNull(),
15-
'role' => $this->string(20)->null()->defaultValue("reader"),
15+
'role' => $this->string(20)->null()->defaultValue('reader'),
1616
'flags' => $this->integer()->null()->defaultValue(0),
1717
'created_at' => $this->timestamp()->null()->defaultExpression("(CURRENT_TIMESTAMP)"),
1818
]);

tests/specs/blog/migrations_maria_db/m200000_000001_create_table_users.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function up()
1212
'username' => $this->string(200)->notNull(),
1313
'email' => $this->string(200)->notNull(),
1414
'password' => $this->string()->notNull(),
15-
'role' => $this->string(20)->null()->defaultValue("reader"),
15+
'role' => $this->string(20)->null()->defaultValue('reader'),
1616
'flags' => $this->integer()->null()->defaultValue(0),
1717
'created_at' => $this->timestamp()->null()->defaultExpression("(CURRENT_TIMESTAMP)"),
1818
]);

tests/specs/blog/migrations_mysql_db/m200000_000001_create_table_users.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function up()
1212
'username' => $this->string(200)->notNull(),
1313
'email' => $this->string(200)->notNull(),
1414
'password' => $this->string()->notNull(),
15-
'role' => $this->string(20)->null()->defaultValue("reader"),
15+
'role' => $this->string(20)->null()->defaultValue('reader'),
1616
'flags' => $this->integer()->null()->defaultValue(0),
1717
'created_at' => $this->timestamp()->null()->defaultExpression("(CURRENT_TIMESTAMP)"),
1818
]);

tests/specs/blog/migrations_pgsql_db/m200000_000001_create_table_users.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function safeUp()
1212
'username' => $this->string(200)->notNull(),
1313
'email' => $this->string(200)->notNull(),
1414
'password' => $this->string()->notNull(),
15-
'role' => $this->string(20)->null()->defaultValue("reader"),
15+
'role' => $this->string(20)->null()->defaultValue('reader'),
1616
'flags' => $this->integer()->null()->defaultValue(0),
1717
'created_at' => $this->timestamp()->null()->defaultExpression("(CURRENT_TIMESTAMP)"),
1818
]);

tests/specs/blog_v2/migrations/m200000_000005_create_table_v2_comments.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function up()
1212
'post_id' => $this->bigInteger()->notNull(),
1313
'user_id' => $this->bigInteger()->null()->defaultValue(null),
1414
'message' => $this->text()->notNull(),
15-
'meta_data' => $this->string(300)->null()->defaultValue(""),
15+
'meta_data' => $this->string(300)->null()->defaultValue(''),
1616
'created_at' => $this->timestamp()->notNull(),
1717
]);
1818
$this->addForeignKey('fk_v2_comments_post_id_v2_posts_id', '{{%v2_comments}}', 'post_id', '{{%v2_posts}}', 'id');

0 commit comments

Comments
 (0)