typeorm 0.3.12-dev.ae91c05 → 0.3.12-dev.defb409
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/decorator/options/SpatialColumnOptions.d.ts +2 -1
- package/browser/decorator/options/SpatialColumnOptions.js.map +1 -1
- package/browser/driver/Driver.d.ts +1 -1
- package/browser/driver/Driver.js.map +1 -1
- package/browser/driver/DriverUtils.js +1 -1
- package/browser/driver/DriverUtils.js.map +1 -1
- package/browser/driver/aurora-mysql/AuroraMysqlDriver.d.ts +2 -1
- package/browser/driver/aurora-mysql/AuroraMysqlDriver.js +1 -1
- package/browser/driver/aurora-mysql/AuroraMysqlDriver.js.map +1 -1
- package/browser/driver/cockroachdb/CockroachConnectionOptions.d.ts +5 -0
- package/browser/driver/cockroachdb/CockroachConnectionOptions.js.map +1 -1
- package/browser/driver/cockroachdb/CockroachDriver.d.ts +19 -14
- package/browser/driver/cockroachdb/CockroachDriver.js +128 -13
- package/browser/driver/cockroachdb/CockroachDriver.js.map +1 -1
- package/browser/driver/cockroachdb/CockroachQueryRunner.d.ts +28 -0
- package/browser/driver/cockroachdb/CockroachQueryRunner.js +283 -11
- package/browser/driver/cockroachdb/CockroachQueryRunner.js.map +1 -1
- package/browser/driver/mongodb/MongoDriver.d.ts +5 -0
- package/browser/driver/mongodb/MongoDriver.js.map +1 -1
- package/browser/driver/mysql/MysqlDriver.d.ts +2 -1
- package/browser/driver/mysql/MysqlDriver.js +1 -1
- package/browser/driver/mysql/MysqlDriver.js.map +1 -1
- package/browser/driver/oracle/OracleDriver.d.ts +5 -0
- package/browser/driver/oracle/OracleDriver.js +4 -0
- package/browser/driver/oracle/OracleDriver.js.map +1 -1
- package/browser/driver/oracle/OracleQueryRunner.js +15 -7
- package/browser/driver/oracle/OracleQueryRunner.js.map +1 -1
- package/browser/driver/postgres/PostgresDriver.d.ts +2 -1
- package/browser/driver/postgres/PostgresDriver.js +1 -1
- package/browser/driver/postgres/PostgresDriver.js.map +1 -1
- package/browser/driver/postgres/PostgresQueryRunner.js +11 -36
- package/browser/driver/postgres/PostgresQueryRunner.js.map +1 -1
- package/browser/driver/sap/SapDriver.d.ts +5 -0
- package/browser/driver/sap/SapDriver.js +4 -0
- package/browser/driver/sap/SapDriver.js.map +1 -1
- package/browser/driver/spanner/SpannerDriver.d.ts +2 -1
- package/browser/driver/spanner/SpannerDriver.js +1 -1
- package/browser/driver/spanner/SpannerDriver.js.map +1 -1
- package/browser/driver/sqlite/SqliteConnectionOptions.d.ts +7 -0
- package/browser/driver/sqlite/SqliteConnectionOptions.js.map +1 -1
- package/browser/driver/sqlite/SqliteDriver.js +5 -0
- package/browser/driver/sqlite/SqliteDriver.js.map +1 -1
- package/browser/driver/sqlite-abstract/AbstractSqliteDriver.d.ts +2 -1
- package/browser/driver/sqlite-abstract/AbstractSqliteDriver.js +1 -1
- package/browser/driver/sqlite-abstract/AbstractSqliteDriver.js.map +1 -1
- package/browser/driver/sqlserver/SqlServerDriver.d.ts +5 -0
- package/browser/driver/sqlserver/SqlServerDriver.js +4 -0
- package/browser/driver/sqlserver/SqlServerDriver.js.map +1 -1
- package/browser/driver/types/GeoJsonTypes.d.ts +87 -0
- package/browser/driver/types/GeoJsonTypes.js +3 -0
- package/browser/driver/types/GeoJsonTypes.js.map +1 -0
- package/browser/driver/types/UpsertType.d.ts +1 -1
- package/browser/driver/types/UpsertType.js.map +1 -1
- package/browser/entity-manager/EntityManager.js +2 -0
- package/browser/entity-manager/EntityManager.js.map +1 -1
- package/browser/find-options/mongodb/MongoFindOneOptions.d.ts +2 -2
- package/browser/find-options/mongodb/MongoFindOneOptions.js.map +1 -1
- package/browser/index.d.ts +1 -0
- package/browser/index.js +1 -0
- package/browser/index.js.map +1 -1
- package/browser/query-builder/InsertOrUpdateOptions.d.ts +2 -0
- package/browser/query-builder/InsertOrUpdateOptions.js.map +1 -1
- package/browser/query-builder/InsertQueryBuilder.d.ts +4 -4
- package/browser/query-builder/InsertQueryBuilder.js +80 -74
- package/browser/query-builder/InsertQueryBuilder.js.map +1 -1
- package/browser/query-builder/QueryBuilder.d.ts +4 -0
- package/browser/query-builder/QueryBuilder.js +28 -8
- package/browser/query-builder/QueryBuilder.js.map +1 -1
- package/browser/query-builder/QueryExpressionMap.d.ts +7 -0
- package/browser/query-builder/QueryExpressionMap.js +4 -0
- package/browser/query-builder/QueryExpressionMap.js.map +1 -1
- package/browser/query-builder/SelectQueryBuilder.d.ts +4 -0
- package/browser/query-builder/SelectQueryBuilder.js +22 -1
- package/browser/query-builder/SelectQueryBuilder.js.map +1 -1
- package/browser/query-builder/UpdateQueryBuilder.js +1 -2
- package/browser/query-builder/UpdateQueryBuilder.js.map +1 -1
- package/browser/repository/UpsertOptions.d.ts +7 -0
- package/browser/repository/UpsertOptions.js.map +1 -1
- package/decorator/options/SpatialColumnOptions.d.ts +2 -1
- package/decorator/options/SpatialColumnOptions.js.map +1 -1
- package/driver/Driver.d.ts +1 -1
- package/driver/Driver.js.map +1 -1
- package/driver/DriverUtils.js +1 -1
- package/driver/DriverUtils.js.map +1 -1
- package/driver/aurora-mysql/AuroraMysqlDriver.d.ts +2 -1
- package/driver/aurora-mysql/AuroraMysqlDriver.js +1 -1
- package/driver/aurora-mysql/AuroraMysqlDriver.js.map +1 -1
- package/driver/cockroachdb/CockroachConnectionOptions.d.ts +5 -0
- package/driver/cockroachdb/CockroachConnectionOptions.js.map +1 -1
- package/driver/cockroachdb/CockroachDriver.d.ts +19 -14
- package/driver/cockroachdb/CockroachDriver.js +128 -13
- package/driver/cockroachdb/CockroachDriver.js.map +1 -1
- package/driver/cockroachdb/CockroachQueryRunner.d.ts +28 -0
- package/driver/cockroachdb/CockroachQueryRunner.js +283 -11
- package/driver/cockroachdb/CockroachQueryRunner.js.map +1 -1
- package/driver/mongodb/MongoDriver.d.ts +5 -0
- package/driver/mongodb/MongoDriver.js.map +1 -1
- package/driver/mysql/MysqlDriver.d.ts +2 -1
- package/driver/mysql/MysqlDriver.js +1 -1
- package/driver/mysql/MysqlDriver.js.map +1 -1
- package/driver/oracle/OracleDriver.d.ts +5 -0
- package/driver/oracle/OracleDriver.js +4 -0
- package/driver/oracle/OracleDriver.js.map +1 -1
- package/driver/oracle/OracleQueryRunner.js +15 -7
- package/driver/oracle/OracleQueryRunner.js.map +1 -1
- package/driver/postgres/PostgresDriver.d.ts +2 -1
- package/driver/postgres/PostgresDriver.js +1 -1
- package/driver/postgres/PostgresDriver.js.map +1 -1
- package/driver/postgres/PostgresQueryRunner.js +11 -36
- package/driver/postgres/PostgresQueryRunner.js.map +1 -1
- package/driver/sap/SapDriver.d.ts +5 -0
- package/driver/sap/SapDriver.js +4 -0
- package/driver/sap/SapDriver.js.map +1 -1
- package/driver/spanner/SpannerDriver.d.ts +2 -1
- package/driver/spanner/SpannerDriver.js +1 -1
- package/driver/spanner/SpannerDriver.js.map +1 -1
- package/driver/sqlite/SqliteConnectionOptions.d.ts +7 -0
- package/driver/sqlite/SqliteConnectionOptions.js.map +1 -1
- package/driver/sqlite/SqliteDriver.js +5 -0
- package/driver/sqlite/SqliteDriver.js.map +1 -1
- package/driver/sqlite-abstract/AbstractSqliteDriver.d.ts +2 -1
- package/driver/sqlite-abstract/AbstractSqliteDriver.js +1 -1
- package/driver/sqlite-abstract/AbstractSqliteDriver.js.map +1 -1
- package/driver/sqlserver/SqlServerDriver.d.ts +5 -0
- package/driver/sqlserver/SqlServerDriver.js +4 -0
- package/driver/sqlserver/SqlServerDriver.js.map +1 -1
- package/driver/types/GeoJsonTypes.d.ts +87 -0
- package/driver/types/GeoJsonTypes.js +4 -0
- package/driver/types/GeoJsonTypes.js.map +1 -0
- package/driver/types/UpsertType.d.ts +1 -1
- package/driver/types/UpsertType.js.map +1 -1
- package/entity-manager/EntityManager.js +2 -0
- package/entity-manager/EntityManager.js.map +1 -1
- package/find-options/mongodb/MongoFindOneOptions.d.ts +2 -2
- package/find-options/mongodb/MongoFindOneOptions.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/query-builder/InsertOrUpdateOptions.d.ts +2 -0
- package/query-builder/InsertOrUpdateOptions.js.map +1 -1
- package/query-builder/InsertQueryBuilder.d.ts +4 -4
- package/query-builder/InsertQueryBuilder.js +80 -74
- package/query-builder/InsertQueryBuilder.js.map +1 -1
- package/query-builder/QueryBuilder.d.ts +4 -0
- package/query-builder/QueryBuilder.js +28 -8
- package/query-builder/QueryBuilder.js.map +1 -1
- package/query-builder/QueryExpressionMap.d.ts +7 -0
- package/query-builder/QueryExpressionMap.js +4 -0
- package/query-builder/QueryExpressionMap.js.map +1 -1
- package/query-builder/SelectQueryBuilder.d.ts +4 -0
- package/query-builder/SelectQueryBuilder.js +22 -1
- package/query-builder/SelectQueryBuilder.js.map +1 -1
- package/query-builder/UpdateQueryBuilder.js +1 -2
- package/query-builder/UpdateQueryBuilder.js.map +1 -1
- package/repository/UpsertOptions.d.ts +7 -0
- package/repository/UpsertOptions.js.map +1 -1
|
@@ -17,6 +17,7 @@ import { TableExclusion } from "../../schema-builder/table/TableExclusion";
|
|
|
17
17
|
import { TypeORMError } from "../../error";
|
|
18
18
|
import { MetadataTableType } from "../types/MetadataTableType";
|
|
19
19
|
import { InstanceChecker } from "../../util/InstanceChecker";
|
|
20
|
+
import { VersionUtils } from "../../util/VersionUtils.js";
|
|
20
21
|
/**
|
|
21
22
|
* Runs queries on a single postgres database connection.
|
|
22
23
|
*/
|
|
@@ -79,6 +80,9 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
79
80
|
* You cannot use query runner methods once its released.
|
|
80
81
|
*/
|
|
81
82
|
release() {
|
|
83
|
+
if (this.isReleased) {
|
|
84
|
+
return Promise.resolve();
|
|
85
|
+
}
|
|
82
86
|
this.isReleased = true;
|
|
83
87
|
if (this.releaseCallback)
|
|
84
88
|
this.releaseCallback();
|
|
@@ -356,6 +360,20 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
356
360
|
}
|
|
357
361
|
const upQueries = [];
|
|
358
362
|
const downQueries = [];
|
|
363
|
+
// if table have column with ENUM type, we must create this type in postgres.
|
|
364
|
+
const enumColumns = table.columns.filter((column) => column.type === "enum" || column.type === "simple-enum");
|
|
365
|
+
const createdEnumTypes = [];
|
|
366
|
+
for (const column of enumColumns) {
|
|
367
|
+
// TODO: Should also check if values of existing type matches expected ones
|
|
368
|
+
const hasEnum = await this.hasEnumType(table, column);
|
|
369
|
+
const enumName = this.buildEnumName(table, column);
|
|
370
|
+
// if enum with the same "enumName" is defined more then once, me must prevent double creation
|
|
371
|
+
if (!hasEnum && createdEnumTypes.indexOf(enumName) === -1) {
|
|
372
|
+
createdEnumTypes.push(enumName);
|
|
373
|
+
upQueries.push(this.createEnumTypeSql(table, column, enumName));
|
|
374
|
+
downQueries.push(this.dropEnumTypeSql(table, column, enumName));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
359
377
|
table.columns
|
|
360
378
|
.filter((column) => column.isGenerated &&
|
|
361
379
|
column.generationStrategy === "increment")
|
|
@@ -569,6 +587,16 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
569
587
|
// replace constraint name
|
|
570
588
|
foreignKey.name = newForeignKeyName;
|
|
571
589
|
});
|
|
590
|
+
// rename ENUM types
|
|
591
|
+
const enumColumns = newTable.columns.filter((column) => column.type === "enum" || column.type === "simple-enum");
|
|
592
|
+
for (let column of enumColumns) {
|
|
593
|
+
// skip renaming for user-defined enum name
|
|
594
|
+
if (column.enumName)
|
|
595
|
+
continue;
|
|
596
|
+
const oldEnumType = await this.getUserDefinedTypeName(oldTable, column);
|
|
597
|
+
upQueries.push(new Query(`ALTER TYPE "${oldEnumType.schema}"."${oldEnumType.name}" RENAME TO ${this.buildEnumName(newTable, column, false)}`));
|
|
598
|
+
downQueries.push(new Query(`ALTER TYPE ${this.buildEnumName(newTable, column)} RENAME TO "${oldEnumType.name}"`));
|
|
599
|
+
}
|
|
572
600
|
await this.executeQueries(upQueries, downQueries);
|
|
573
601
|
}
|
|
574
602
|
/**
|
|
@@ -584,6 +612,13 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
584
612
|
if (column.generationStrategy === "increment") {
|
|
585
613
|
throw new TypeORMError(`Adding sequential generated columns into existing table is not supported`);
|
|
586
614
|
}
|
|
615
|
+
if (column.type === "enum" || column.type === "simple-enum") {
|
|
616
|
+
const hasEnum = await this.hasEnumType(table, column);
|
|
617
|
+
if (!hasEnum) {
|
|
618
|
+
upQueries.push(this.createEnumTypeSql(table, column));
|
|
619
|
+
downQueries.push(this.dropEnumTypeSql(table, column));
|
|
620
|
+
}
|
|
621
|
+
}
|
|
587
622
|
upQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ADD ${this.buildCreateColumnSql(table, column)}`));
|
|
588
623
|
downQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} DROP COLUMN "${column.name}"`));
|
|
589
624
|
// create or update primary key constraint
|
|
@@ -711,6 +746,7 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
711
746
|
let clonedTable = table.clone();
|
|
712
747
|
const upQueries = [];
|
|
713
748
|
const downQueries = [];
|
|
749
|
+
let defaultValueChanged = false;
|
|
714
750
|
const oldColumn = InstanceChecker.isTableColumn(oldTableColumnOrName)
|
|
715
751
|
? oldTableColumnOrName
|
|
716
752
|
: table.columns.find((column) => column.name === oldTableColumnOrName);
|
|
@@ -718,6 +754,7 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
718
754
|
throw new TypeORMError(`Column "${oldTableColumnOrName}" was not found in the "${table.name}" table.`);
|
|
719
755
|
if (oldColumn.type !== newColumn.type ||
|
|
720
756
|
oldColumn.length !== newColumn.length ||
|
|
757
|
+
newColumn.isArray !== oldColumn.isArray ||
|
|
721
758
|
oldColumn.generatedType !== newColumn.generatedType ||
|
|
722
759
|
oldColumn.asExpression !== newColumn.asExpression) {
|
|
723
760
|
// To avoid data conversion, we just recreate column
|
|
@@ -731,6 +768,13 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
731
768
|
// rename column
|
|
732
769
|
upQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} RENAME COLUMN "${oldColumn.name}" TO "${newColumn.name}"`));
|
|
733
770
|
downQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} RENAME COLUMN "${newColumn.name}" TO "${oldColumn.name}"`));
|
|
771
|
+
// rename ENUM type
|
|
772
|
+
if (oldColumn.type === "enum" ||
|
|
773
|
+
oldColumn.type === "simple-enum") {
|
|
774
|
+
const oldEnumType = await this.getUserDefinedTypeName(table, oldColumn);
|
|
775
|
+
upQueries.push(new Query(`ALTER TYPE "${oldEnumType.schema}"."${oldEnumType.name}" RENAME TO ${this.buildEnumName(table, newColumn, false)}`));
|
|
776
|
+
downQueries.push(new Query(`ALTER TYPE ${this.buildEnumName(table, newColumn)} RENAME TO "${oldEnumType.name}"`));
|
|
777
|
+
}
|
|
734
778
|
// rename column primary key constraint
|
|
735
779
|
if (oldColumn.isPrimary === true &&
|
|
736
780
|
!oldColumn.primaryKeyConstraintName) {
|
|
@@ -898,6 +942,57 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
898
942
|
downQueries.push(this.createUniqueConstraintSql(table, uniqueConstraint));
|
|
899
943
|
}
|
|
900
944
|
}
|
|
945
|
+
if ((newColumn.type === "enum" ||
|
|
946
|
+
newColumn.type === "simple-enum") &&
|
|
947
|
+
(oldColumn.type === "enum" ||
|
|
948
|
+
oldColumn.type === "simple-enum") &&
|
|
949
|
+
(!OrmUtils.isArraysEqual(newColumn.enum, oldColumn.enum) ||
|
|
950
|
+
newColumn.enumName !== oldColumn.enumName)) {
|
|
951
|
+
const arraySuffix = newColumn.isArray ? "[]" : "";
|
|
952
|
+
// "public"."new_enum"
|
|
953
|
+
const newEnumName = this.buildEnumName(table, newColumn);
|
|
954
|
+
// "public"."old_enum"
|
|
955
|
+
const oldEnumName = this.buildEnumName(table, oldColumn);
|
|
956
|
+
// "old_enum"
|
|
957
|
+
const oldEnumNameWithoutSchema = this.buildEnumName(table, oldColumn, false);
|
|
958
|
+
//"public"."old_enum_old"
|
|
959
|
+
const oldEnumNameWithSchema_old = this.buildEnumName(table, oldColumn, true, false, true);
|
|
960
|
+
//"old_enum_old"
|
|
961
|
+
const oldEnumNameWithoutSchema_old = this.buildEnumName(table, oldColumn, false, false, true);
|
|
962
|
+
// rename old ENUM
|
|
963
|
+
upQueries.push(new Query(`ALTER TYPE ${oldEnumName} RENAME TO ${oldEnumNameWithoutSchema_old}`));
|
|
964
|
+
downQueries.push(new Query(`ALTER TYPE ${oldEnumNameWithSchema_old} RENAME TO ${oldEnumNameWithoutSchema}`));
|
|
965
|
+
// create new ENUM
|
|
966
|
+
upQueries.push(this.createEnumTypeSql(table, newColumn, newEnumName));
|
|
967
|
+
downQueries.push(this.dropEnumTypeSql(table, newColumn, newEnumName));
|
|
968
|
+
// if column have default value, we must drop it to avoid issues with type casting
|
|
969
|
+
if (oldColumn.default !== null &&
|
|
970
|
+
oldColumn.default !== undefined) {
|
|
971
|
+
// mark default as changed to prevent double update
|
|
972
|
+
defaultValueChanged = true;
|
|
973
|
+
upQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${oldColumn.name}" DROP DEFAULT`));
|
|
974
|
+
downQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${oldColumn.name}" SET DEFAULT ${oldColumn.default}`));
|
|
975
|
+
}
|
|
976
|
+
// build column types
|
|
977
|
+
const upType = `${newEnumName}${arraySuffix} USING "${newColumn.name}"::"text"::${newEnumName}${arraySuffix}`;
|
|
978
|
+
const downType = `${oldEnumNameWithSchema_old}${arraySuffix} USING "${newColumn.name}"::"text"::${oldEnumNameWithSchema_old}${arraySuffix}`;
|
|
979
|
+
upQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" TYPE ${upType}`));
|
|
980
|
+
// we add a delay here since for some reason cockroachdb fails with
|
|
981
|
+
// "cannot drop type because other objects still depend on it" error
|
|
982
|
+
// if we are trying to drop type right after we altered it.
|
|
983
|
+
upQueries.push(new Query(`SELECT pg_sleep(0.1)`));
|
|
984
|
+
downQueries.push(new Query(`SELECT pg_sleep(0.1)`));
|
|
985
|
+
downQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" TYPE ${downType}`));
|
|
986
|
+
// restore column default or create new one
|
|
987
|
+
if (newColumn.default !== null &&
|
|
988
|
+
newColumn.default !== undefined) {
|
|
989
|
+
upQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" SET DEFAULT ${newColumn.default}`));
|
|
990
|
+
downQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" DROP DEFAULT`));
|
|
991
|
+
}
|
|
992
|
+
// remove old ENUM
|
|
993
|
+
upQueries.push(this.dropEnumTypeSql(table, oldColumn, oldEnumNameWithSchema_old));
|
|
994
|
+
downQueries.push(this.createEnumTypeSql(table, oldColumn, oldEnumNameWithSchema_old));
|
|
995
|
+
}
|
|
901
996
|
if (oldColumn.isGenerated !== newColumn.isGenerated &&
|
|
902
997
|
newColumn.generationStrategy !== "uuid") {
|
|
903
998
|
if (newColumn.isGenerated) {
|
|
@@ -914,7 +1009,8 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
914
1009
|
downQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" SET DEFAULT unique_rowid()`));
|
|
915
1010
|
}
|
|
916
1011
|
}
|
|
917
|
-
if (newColumn.default !== oldColumn.default
|
|
1012
|
+
if (newColumn.default !== oldColumn.default &&
|
|
1013
|
+
!defaultValueChanged) {
|
|
918
1014
|
if (newColumn.default !== null &&
|
|
919
1015
|
newColumn.default !== undefined) {
|
|
920
1016
|
upQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" SET DEFAULT ${newColumn.default}`));
|
|
@@ -933,6 +1029,12 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
933
1029
|
}
|
|
934
1030
|
}
|
|
935
1031
|
}
|
|
1032
|
+
if ((newColumn.spatialFeatureType || "").toLowerCase() !==
|
|
1033
|
+
(oldColumn.spatialFeatureType || "").toLowerCase() ||
|
|
1034
|
+
newColumn.srid !== oldColumn.srid) {
|
|
1035
|
+
upQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" TYPE ${this.driver.createFullType(newColumn)}`));
|
|
1036
|
+
downQueries.push(new Query(`ALTER TABLE ${this.escapePath(table)} ALTER COLUMN "${newColumn.name}" TYPE ${this.driver.createFullType(oldColumn)}`));
|
|
1037
|
+
}
|
|
936
1038
|
await this.executeQueries(upQueries, downQueries);
|
|
937
1039
|
this.replaceCachedTable(table, clonedTable);
|
|
938
1040
|
}
|
|
@@ -1039,6 +1141,16 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1039
1141
|
upQueries.push(deleteQuery);
|
|
1040
1142
|
downQueries.push(insertQuery);
|
|
1041
1143
|
}
|
|
1144
|
+
// drop enum type
|
|
1145
|
+
if (column.type === "enum" || column.type === "simple-enum") {
|
|
1146
|
+
const hasEnum = await this.hasEnumType(table, column);
|
|
1147
|
+
if (hasEnum) {
|
|
1148
|
+
const enumType = await this.getUserDefinedTypeName(table, column);
|
|
1149
|
+
const escapedEnumName = `"${enumType.schema}"."${enumType.name}"`;
|
|
1150
|
+
upQueries.push(this.dropEnumTypeSql(table, column, escapedEnumName));
|
|
1151
|
+
downQueries.push(this.createEnumTypeSql(table, column, escapedEnumName));
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1042
1154
|
await this.executeQueries(upQueries, downQueries);
|
|
1043
1155
|
clonedTable.removeColumn(column);
|
|
1044
1156
|
this.replaceCachedTable(table, clonedTable);
|
|
@@ -1388,6 +1500,7 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1388
1500
|
if (!isAnotherTransactionActive)
|
|
1389
1501
|
await this.startTransaction();
|
|
1390
1502
|
try {
|
|
1503
|
+
const version = await this.getVersion();
|
|
1391
1504
|
const selectViewDropsQuery = `SELECT 'DROP VIEW IF EXISTS "' || schemaname || '"."' || viewname || '" CASCADE;' as "query" ` +
|
|
1392
1505
|
`FROM "pg_views" WHERE "schemaname" IN (${schemaNamesString})`;
|
|
1393
1506
|
const dropViewQueries = await this.query(selectViewDropsQuery);
|
|
@@ -1398,6 +1511,10 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1398
1511
|
const selectSequenceDropsQuery = `SELECT 'DROP SEQUENCE "' || sequence_schema || '"."' || sequence_name || '";' as "query" FROM "information_schema"."sequences" WHERE "sequence_schema" IN (${schemaNamesString})`;
|
|
1399
1512
|
const sequenceDropQueries = await this.query(selectSequenceDropsQuery);
|
|
1400
1513
|
await Promise.all(sequenceDropQueries.map((q) => this.query(q["query"])));
|
|
1514
|
+
// drop enum types. Supported starting from v20.2.19.
|
|
1515
|
+
if (VersionUtils.isGreaterOrEqual(version, "20.2.19")) {
|
|
1516
|
+
await this.dropEnumTypes(schemaNamesString);
|
|
1517
|
+
}
|
|
1401
1518
|
if (!isAnotherTransactionActive)
|
|
1402
1519
|
await this.commitTransaction();
|
|
1403
1520
|
}
|
|
@@ -1532,11 +1649,21 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1532
1649
|
`INNER JOIN "pg_class" "cl" ON "cl"."oid" = "con"."confrelid" ` +
|
|
1533
1650
|
`INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" ` +
|
|
1534
1651
|
`INNER JOIN "pg_attribute" "att2" ON "att2"."attrelid" = "con"."conrelid" AND "att2"."attnum" = "con"."parent"`;
|
|
1535
|
-
const
|
|
1652
|
+
const tableSchemas = dbTables
|
|
1653
|
+
.map((dbTable) => `'${dbTable.table_schema}'`)
|
|
1654
|
+
.join(", ");
|
|
1655
|
+
const enumsSql = `SELECT "t"."typname" AS "name", string_agg("e"."enumlabel", '|') AS "value" ` +
|
|
1656
|
+
`FROM "pg_enum" "e" ` +
|
|
1657
|
+
`INNER JOIN "pg_type" "t" ON "t"."oid" = "e"."enumtypid" ` +
|
|
1658
|
+
`INNER JOIN "pg_namespace" "n" ON "n"."oid" = "t"."typnamespace" ` +
|
|
1659
|
+
`WHERE "n"."nspname" IN (${tableSchemas}) ` +
|
|
1660
|
+
`GROUP BY "t"."typname"`;
|
|
1661
|
+
const [dbColumns, dbConstraints, dbIndices, dbForeignKeys, dbEnums,] = await Promise.all([
|
|
1536
1662
|
this.query(columnsSql),
|
|
1537
1663
|
this.query(constraintsSql),
|
|
1538
1664
|
this.query(indicesSql),
|
|
1539
1665
|
this.query(foreignKeysSql),
|
|
1666
|
+
this.query(enumsSql),
|
|
1540
1667
|
]);
|
|
1541
1668
|
// create tables for loaded tables
|
|
1542
1669
|
return Promise.all(dbTables.map(async (dbTable) => {
|
|
@@ -1600,15 +1727,39 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1600
1727
|
tableColumn.scale = undefined;
|
|
1601
1728
|
}
|
|
1602
1729
|
}
|
|
1730
|
+
// docs: https://www.postgresql.org/docs/current/xtypes.html
|
|
1731
|
+
// When you define a new base type, PostgreSQL automatically provides support for arrays of that type.
|
|
1732
|
+
// The array type typically has the same name as the base type with the underscore character (_) prepended.
|
|
1733
|
+
// ----
|
|
1734
|
+
// so, we must remove this underscore character from enum type name
|
|
1735
|
+
let udtName = dbColumn["udt_name"];
|
|
1736
|
+
if (udtName.indexOf("_") === 0) {
|
|
1737
|
+
udtName = udtName.substr(1, udtName.length);
|
|
1738
|
+
}
|
|
1739
|
+
const enumType = dbEnums.find((dbEnum) => {
|
|
1740
|
+
return dbEnum["name"] === udtName;
|
|
1741
|
+
});
|
|
1742
|
+
if (enumType) {
|
|
1743
|
+
// check if `enumName` is specified by user
|
|
1744
|
+
const builtEnumName = this.buildEnumName(table, tableColumn, false, true);
|
|
1745
|
+
const enumName = builtEnumName !== enumType["name"]
|
|
1746
|
+
? enumType["name"]
|
|
1747
|
+
: undefined;
|
|
1748
|
+
tableColumn.type = "enum";
|
|
1749
|
+
tableColumn.enum = enumType["value"].split("|");
|
|
1750
|
+
tableColumn.enumName = enumName;
|
|
1751
|
+
}
|
|
1603
1752
|
if (dbColumn["data_type"].toLowerCase() === "array") {
|
|
1604
1753
|
tableColumn.isArray = true;
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1754
|
+
if (!enumType) {
|
|
1755
|
+
const type = dbColumn["crdb_sql_type"]
|
|
1756
|
+
.replace("[]", "")
|
|
1757
|
+
.toLowerCase();
|
|
1758
|
+
tableColumn.type =
|
|
1759
|
+
this.connection.driver.normalizeType({
|
|
1760
|
+
type: type,
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1612
1763
|
}
|
|
1613
1764
|
// check only columns that have length property
|
|
1614
1765
|
if (this.driver.withLengthColumnTypes.indexOf(tableColumn.type) !== -1 &&
|
|
@@ -1677,6 +1828,10 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1677
1828
|
tableColumn.default = dbColumn["column_default"].replace(/:::[\w\s\[\]\"]+/g, "");
|
|
1678
1829
|
tableColumn.default =
|
|
1679
1830
|
tableColumn.default.replace(/^(-?[\d\.]+)$/, "($1)");
|
|
1831
|
+
if (enumType) {
|
|
1832
|
+
tableColumn.default =
|
|
1833
|
+
tableColumn.default.replace(`.${enumType["name"]}`, "");
|
|
1834
|
+
}
|
|
1680
1835
|
}
|
|
1681
1836
|
}
|
|
1682
1837
|
if (dbColumn["is_generated"] === "YES" &&
|
|
@@ -1707,6 +1862,25 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1707
1862
|
if (dbColumn["character_set_name"])
|
|
1708
1863
|
tableColumn.charset =
|
|
1709
1864
|
dbColumn["character_set_name"];
|
|
1865
|
+
if (tableColumn.type === "geometry" ||
|
|
1866
|
+
tableColumn.type === "geography") {
|
|
1867
|
+
const sql = `SELECT * FROM (` +
|
|
1868
|
+
`SELECT "f_table_schema" "table_schema", "f_table_name" "table_name", ` +
|
|
1869
|
+
`"f_${tableColumn.type}_column" "column_name", "srid", "type" ` +
|
|
1870
|
+
`FROM "${tableColumn.type}_columns"` +
|
|
1871
|
+
`) AS _ ` +
|
|
1872
|
+
`WHERE "column_name" = '${dbColumn["column_name"]}' AND ` +
|
|
1873
|
+
`"table_schema" = '${dbColumn["table_schema"]}' AND ` +
|
|
1874
|
+
`"table_name" = '${dbColumn["table_name"]}'`;
|
|
1875
|
+
const results = await this.query(sql);
|
|
1876
|
+
if (results.length > 0) {
|
|
1877
|
+
tableColumn.spatialFeatureType =
|
|
1878
|
+
results[0].type;
|
|
1879
|
+
tableColumn.srid = results[0].srid
|
|
1880
|
+
? parseInt(results[0].srid)
|
|
1881
|
+
: undefined;
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1710
1884
|
return tableColumn;
|
|
1711
1885
|
}));
|
|
1712
1886
|
// find unique constraints of table, group them by constraint name and build TableUnique.
|
|
@@ -1889,6 +2063,13 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1889
2063
|
.forEach((it) => (sql += `; COMMENT ON COLUMN ${this.escapePath(table)}."${it.name}" IS ${this.escapeComment(it.comment)}`));
|
|
1890
2064
|
return new Query(sql);
|
|
1891
2065
|
}
|
|
2066
|
+
/**
|
|
2067
|
+
* Loads Cockroachdb version.
|
|
2068
|
+
*/
|
|
2069
|
+
async getVersion() {
|
|
2070
|
+
const result = await this.query(`SELECT version()`);
|
|
2071
|
+
return result[0]["version"].replace(/^CockroachDB CCL v([\d\.]+) .*$/, "$1");
|
|
2072
|
+
}
|
|
1892
2073
|
/**
|
|
1893
2074
|
* Builds drop table sql.
|
|
1894
2075
|
*/
|
|
@@ -1942,6 +2123,51 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1942
2123
|
name,
|
|
1943
2124
|
});
|
|
1944
2125
|
}
|
|
2126
|
+
/**
|
|
2127
|
+
* Drops ENUM type from given schemas.
|
|
2128
|
+
*/
|
|
2129
|
+
async dropEnumTypes(schemaNames) {
|
|
2130
|
+
const selectDropsQuery = `SELECT 'DROP TYPE IF EXISTS "' || n.nspname || '"."' || t.typname || '";' as "query" FROM "pg_type" "t" ` +
|
|
2131
|
+
`INNER JOIN "pg_enum" "e" ON "e"."enumtypid" = "t"."oid" ` +
|
|
2132
|
+
`INNER JOIN "pg_namespace" "n" ON "n"."oid" = "t"."typnamespace" ` +
|
|
2133
|
+
`WHERE "n"."nspname" IN (${schemaNames}) GROUP BY "n"."nspname", "t"."typname"`;
|
|
2134
|
+
const dropQueries = await this.query(selectDropsQuery);
|
|
2135
|
+
await Promise.all(dropQueries.map((q) => this.query(q["query"])));
|
|
2136
|
+
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Checks if enum with the given name exist in the database.
|
|
2139
|
+
*/
|
|
2140
|
+
async hasEnumType(table, column) {
|
|
2141
|
+
let { schema } = this.driver.parseTableName(table);
|
|
2142
|
+
if (!schema) {
|
|
2143
|
+
schema = await this.getCurrentSchema();
|
|
2144
|
+
}
|
|
2145
|
+
const enumName = this.buildEnumName(table, column, false, true);
|
|
2146
|
+
const sql = `SELECT "n"."nspname", "t"."typname" FROM "pg_type" "t" ` +
|
|
2147
|
+
`INNER JOIN "pg_namespace" "n" ON "n"."oid" = "t"."typnamespace" ` +
|
|
2148
|
+
`WHERE "n"."nspname" = '${schema}' AND "t"."typname" = '${enumName}'`;
|
|
2149
|
+
const result = await this.query(sql);
|
|
2150
|
+
return result.length ? true : false;
|
|
2151
|
+
}
|
|
2152
|
+
/**
|
|
2153
|
+
* Builds create ENUM type sql.
|
|
2154
|
+
*/
|
|
2155
|
+
createEnumTypeSql(table, column, enumName) {
|
|
2156
|
+
if (!enumName)
|
|
2157
|
+
enumName = this.buildEnumName(table, column);
|
|
2158
|
+
const enumValues = column
|
|
2159
|
+
.enum.map((value) => `'${value.replace("'", "''")}'`)
|
|
2160
|
+
.join(", ");
|
|
2161
|
+
return new Query(`CREATE TYPE ${enumName} AS ENUM(${enumValues})`);
|
|
2162
|
+
}
|
|
2163
|
+
/**
|
|
2164
|
+
* Builds create ENUM type sql.
|
|
2165
|
+
*/
|
|
2166
|
+
dropEnumTypeSql(table, column, enumName) {
|
|
2167
|
+
if (!enumName)
|
|
2168
|
+
enumName = this.buildEnumName(table, column);
|
|
2169
|
+
return new Query(`DROP TYPE ${enumName}`);
|
|
2170
|
+
}
|
|
1945
2171
|
/**
|
|
1946
2172
|
* Builds create index sql.
|
|
1947
2173
|
* UNIQUE indices creates as UNIQUE constraints.
|
|
@@ -1950,7 +2176,7 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
1950
2176
|
const columns = index.columnNames
|
|
1951
2177
|
.map((columnName) => `"${columnName}"`)
|
|
1952
2178
|
.join(", ");
|
|
1953
|
-
return new Query(`CREATE INDEX "${index.name}" ON ${this.escapePath(table)} (${columns}) ${index.where ? "WHERE " + index.where : ""}`);
|
|
2179
|
+
return new Query(`CREATE ${index.isUnique ? "UNIQUE " : ""}INDEX "${index.name}" ON ${this.escapePath(table)} ${index.isSpatial ? "USING GiST " : ""}(${columns}) ${index.where ? "WHERE " + index.where : ""}`);
|
|
1954
2180
|
}
|
|
1955
2181
|
/**
|
|
1956
2182
|
* Builds drop index sql.
|
|
@@ -2063,6 +2289,46 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
2063
2289
|
? `${schema}.${this.buildSequenceName(table, columnOrName)}`
|
|
2064
2290
|
: this.buildSequenceName(table, columnOrName);
|
|
2065
2291
|
}
|
|
2292
|
+
/**
|
|
2293
|
+
* Builds ENUM type name from given table and column.
|
|
2294
|
+
*/
|
|
2295
|
+
buildEnumName(table, column, withSchema = true, disableEscape, toOld) {
|
|
2296
|
+
const { schema, tableName } = this.driver.parseTableName(table);
|
|
2297
|
+
let enumName = column.enumName
|
|
2298
|
+
? column.enumName
|
|
2299
|
+
: `${tableName}_${column.name.toLowerCase()}_enum`;
|
|
2300
|
+
if (schema && withSchema)
|
|
2301
|
+
enumName = `${schema}.${enumName}`;
|
|
2302
|
+
if (toOld)
|
|
2303
|
+
enumName = enumName + "_old";
|
|
2304
|
+
return enumName
|
|
2305
|
+
.split(".")
|
|
2306
|
+
.map((i) => {
|
|
2307
|
+
return disableEscape ? i : `"${i}"`;
|
|
2308
|
+
})
|
|
2309
|
+
.join(".");
|
|
2310
|
+
}
|
|
2311
|
+
async getUserDefinedTypeName(table, column) {
|
|
2312
|
+
let { schema, tableName: name } = this.driver.parseTableName(table);
|
|
2313
|
+
if (!schema) {
|
|
2314
|
+
schema = await this.getCurrentSchema();
|
|
2315
|
+
}
|
|
2316
|
+
const result = await this.query(`SELECT "udt_schema", "udt_name" ` +
|
|
2317
|
+
`FROM "information_schema"."columns" WHERE "table_schema" = '${schema}' AND "table_name" = '${name}' AND "column_name"='${column.name}'`);
|
|
2318
|
+
// docs: https://www.postgresql.org/docs/current/xtypes.html
|
|
2319
|
+
// When you define a new base type, PostgreSQL automatically provides support for arrays of that type.
|
|
2320
|
+
// The array type typically has the same name as the base type with the underscore character (_) prepended.
|
|
2321
|
+
// ----
|
|
2322
|
+
// so, we must remove this underscore character from enum type name
|
|
2323
|
+
let udtName = result[0]["udt_name"];
|
|
2324
|
+
if (udtName.indexOf("_") === 0) {
|
|
2325
|
+
udtName = udtName.substr(1, udtName.length);
|
|
2326
|
+
}
|
|
2327
|
+
return {
|
|
2328
|
+
schema: result[0]["udt_schema"],
|
|
2329
|
+
name: udtName,
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2066
2332
|
/**
|
|
2067
2333
|
* Escapes a given comment so it's safe to include in a query.
|
|
2068
2334
|
*/
|
|
@@ -2099,8 +2365,14 @@ export class CockroachQueryRunner extends BaseQueryRunner {
|
|
|
2099
2365
|
c += " UUID DEFAULT gen_random_uuid()";
|
|
2100
2366
|
}
|
|
2101
2367
|
}
|
|
2102
|
-
if (
|
|
2368
|
+
if (column.type === "enum" || column.type === "simple-enum") {
|
|
2369
|
+
c += " " + this.buildEnumName(table, column);
|
|
2370
|
+
if (column.isArray)
|
|
2371
|
+
c += " array";
|
|
2372
|
+
}
|
|
2373
|
+
else if (!column.isGenerated) {
|
|
2103
2374
|
c += " " + this.connection.driver.createFullType(column);
|
|
2375
|
+
}
|
|
2104
2376
|
if (column.asExpression) {
|
|
2105
2377
|
c += ` AS (${column.asExpression}) ${column.generatedType ? column.generatedType : "VIRTUAL"}`;
|
|
2106
2378
|
}
|