@contember/schema-migrations 2.0.1 → 2.1.0-alpha.2
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/dist/development/src/MigrationDescriber.cjs +2 -1
- package/dist/development/src/MigrationDescriber.cjs.map +1 -1
- package/dist/development/src/MigrationDescriber.js +2 -1
- package/dist/development/src/MigrationDescriber.js.map +1 -1
- package/dist/development/src/modifications/columns/CreateColumnModification.cjs +2 -1
- package/dist/development/src/modifications/columns/CreateColumnModification.cjs.map +1 -1
- package/dist/development/src/modifications/columns/CreateColumnModification.js +2 -1
- package/dist/development/src/modifications/columns/CreateColumnModification.js.map +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.cjs +8 -3
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js +8 -3
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs +15 -9
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js +15 -9
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
- package/dist/development/src/modifications/constraints/RemoveUniqueConstraintModification.cjs +34 -16
- package/dist/development/src/modifications/constraints/RemoveUniqueConstraintModification.cjs.map +1 -1
- package/dist/development/src/modifications/constraints/RemoveUniqueConstraintModification.js +34 -16
- package/dist/development/src/modifications/constraints/RemoveUniqueConstraintModification.js.map +1 -1
- package/dist/development/src/modifications/entities/CreateEntityModification.cjs +2 -1
- package/dist/development/src/modifications/entities/CreateEntityModification.cjs.map +1 -1
- package/dist/development/src/modifications/entities/CreateEntityModification.js +2 -1
- package/dist/development/src/modifications/entities/CreateEntityModification.js.map +1 -1
- package/dist/development/src/modifications/entities/CreateViewModification.cjs +12 -2
- package/dist/development/src/modifications/entities/CreateViewModification.cjs.map +1 -1
- package/dist/development/src/modifications/entities/CreateViewModification.js +12 -2
- package/dist/development/src/modifications/entities/CreateViewModification.js.map +1 -1
- package/dist/development/src/modifications/indexes/CreateIndexModification.cjs +2 -2
- package/dist/development/src/modifications/indexes/CreateIndexModification.cjs.map +1 -1
- package/dist/development/src/modifications/indexes/CreateIndexModification.js +2 -2
- package/dist/development/src/modifications/indexes/CreateIndexModification.js.map +1 -1
- package/dist/development/src/modifications/indexes/RemoveIndexModification.cjs +3 -3
- package/dist/development/src/modifications/indexes/RemoveIndexModification.cjs.map +1 -1
- package/dist/development/src/modifications/indexes/RemoveIndexModification.js +3 -3
- package/dist/development/src/modifications/indexes/RemoveIndexModification.js.map +1 -1
- package/dist/development/src/modifications/upgrade/RemoveIndexNamesModification.cjs +8 -2
- package/dist/development/src/modifications/upgrade/RemoveIndexNamesModification.cjs.map +1 -1
- package/dist/development/src/modifications/upgrade/RemoveIndexNamesModification.js +8 -2
- package/dist/development/src/modifications/upgrade/RemoveIndexNamesModification.js.map +1 -1
- package/dist/development/src/modifications/utils/columnUtils.cjs +1 -1
- package/dist/development/src/modifications/utils/columnUtils.cjs.map +1 -1
- package/dist/development/src/modifications/utils/columnUtils.js +1 -1
- package/dist/development/src/modifications/utils/columnUtils.js.map +1 -1
- package/dist/development/src/modifications/utils/schemaUpdateUtils.cjs +1 -0
- package/dist/development/src/modifications/utils/schemaUpdateUtils.cjs.map +1 -1
- package/dist/development/src/modifications/utils/schemaUpdateUtils.js +1 -0
- package/dist/development/src/modifications/utils/schemaUpdateUtils.js.map +1 -1
- package/dist/production/src/MigrationDescriber.cjs +2 -1
- package/dist/production/src/MigrationDescriber.cjs.map +1 -1
- package/dist/production/src/MigrationDescriber.js +2 -1
- package/dist/production/src/MigrationDescriber.js.map +1 -1
- package/dist/production/src/modifications/columns/CreateColumnModification.cjs +2 -1
- package/dist/production/src/modifications/columns/CreateColumnModification.cjs.map +1 -1
- package/dist/production/src/modifications/columns/CreateColumnModification.js +2 -1
- package/dist/production/src/modifications/columns/CreateColumnModification.js.map +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs +8 -3
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.js +8 -3
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.cjs +15 -9
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.js +15 -9
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
- package/dist/production/src/modifications/constraints/RemoveUniqueConstraintModification.cjs +34 -16
- package/dist/production/src/modifications/constraints/RemoveUniqueConstraintModification.cjs.map +1 -1
- package/dist/production/src/modifications/constraints/RemoveUniqueConstraintModification.js +34 -16
- package/dist/production/src/modifications/constraints/RemoveUniqueConstraintModification.js.map +1 -1
- package/dist/production/src/modifications/entities/CreateEntityModification.cjs +2 -1
- package/dist/production/src/modifications/entities/CreateEntityModification.cjs.map +1 -1
- package/dist/production/src/modifications/entities/CreateEntityModification.js +2 -1
- package/dist/production/src/modifications/entities/CreateEntityModification.js.map +1 -1
- package/dist/production/src/modifications/entities/CreateViewModification.cjs +12 -2
- package/dist/production/src/modifications/entities/CreateViewModification.cjs.map +1 -1
- package/dist/production/src/modifications/entities/CreateViewModification.js +12 -2
- package/dist/production/src/modifications/entities/CreateViewModification.js.map +1 -1
- package/dist/production/src/modifications/indexes/CreateIndexModification.cjs +2 -2
- package/dist/production/src/modifications/indexes/CreateIndexModification.cjs.map +1 -1
- package/dist/production/src/modifications/indexes/CreateIndexModification.js +2 -2
- package/dist/production/src/modifications/indexes/CreateIndexModification.js.map +1 -1
- package/dist/production/src/modifications/indexes/RemoveIndexModification.cjs +3 -3
- package/dist/production/src/modifications/indexes/RemoveIndexModification.cjs.map +1 -1
- package/dist/production/src/modifications/indexes/RemoveIndexModification.js +3 -3
- package/dist/production/src/modifications/indexes/RemoveIndexModification.js.map +1 -1
- package/dist/production/src/modifications/upgrade/RemoveIndexNamesModification.cjs +8 -2
- package/dist/production/src/modifications/upgrade/RemoveIndexNamesModification.cjs.map +1 -1
- package/dist/production/src/modifications/upgrade/RemoveIndexNamesModification.js +8 -2
- package/dist/production/src/modifications/upgrade/RemoveIndexNamesModification.js.map +1 -1
- package/dist/production/src/modifications/utils/columnUtils.cjs +1 -1
- package/dist/production/src/modifications/utils/columnUtils.cjs.map +1 -1
- package/dist/production/src/modifications/utils/columnUtils.js +1 -1
- package/dist/production/src/modifications/utils/columnUtils.js.map +1 -1
- package/dist/production/src/modifications/utils/schemaUpdateUtils.cjs +1 -0
- package/dist/production/src/modifications/utils/schemaUpdateUtils.cjs.map +1 -1
- package/dist/production/src/modifications/utils/schemaUpdateUtils.js +1 -0
- package/dist/production/src/modifications/utils/schemaUpdateUtils.js.map +1 -1
- package/dist/tests/src/tags.d.ts.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/Migration.d.ts.map +1 -1
- package/dist/types/modifications/ModificationHandler.d.ts.map +1 -1
- package/dist/types/modifications/columns/CreateColumnModification.d.ts.map +1 -1
- package/dist/types/modifications/columns/UpdateColumnDefinitionModification.d.ts.map +1 -1
- package/dist/types/modifications/columns/columnUtils.d.ts.map +1 -1
- package/dist/types/modifications/constraints/CreateUniqueConstraintModification.d.ts +2 -2
- package/dist/types/modifications/constraints/CreateUniqueConstraintModification.d.ts.map +1 -1
- package/dist/types/modifications/constraints/RemoveUniqueConstraintModification.d.ts +7 -2
- package/dist/types/modifications/constraints/RemoveUniqueConstraintModification.d.ts.map +1 -1
- package/dist/types/modifications/constraints/utils.d.ts.map +1 -1
- package/dist/types/modifications/entities/CreateEntityModification.d.ts.map +1 -1
- package/dist/types/modifications/entities/CreateViewModification.d.ts +1 -0
- package/dist/types/modifications/entities/CreateViewModification.d.ts.map +1 -1
- package/dist/types/modifications/enums/enumUtils.d.ts.map +1 -1
- package/dist/types/modifications/indexes/utils.d.ts.map +1 -1
- package/dist/types/modifications/relations/helpers.d.ts.map +1 -1
- package/dist/types/modifications/relations/normalization.d.ts.map +1 -1
- package/dist/types/modifications/upgrade/RemoveIndexNamesModification.d.ts.map +1 -1
- package/dist/types/modifications/utils/columnUtils.d.ts +1 -1
- package/dist/types/modifications/utils/columnUtils.d.ts.map +1 -1
- package/dist/types/modifications/utils/createJunctionTable.d.ts.map +1 -1
- package/dist/types/modifications/utils/diffUtils.d.ts.map +1 -1
- package/dist/types/modifications/utils/getPrimaryColumnType.d.ts.map +1 -1
- package/dist/types/modifications/utils/schemaUpdateUtils.d.ts.map +1 -1
- package/dist/types/modifications/utils/sqlUpdateUtils.d.ts.map +1 -1
- package/dist/types/modifications/utils/stringArrayEquals.d.ts.map +1 -1
- package/dist/types/modifications/utils/valueUtils.d.ts.map +1 -1
- package/dist/types/modifications/utils/viewDependencies.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/utils/PartialEntity.d.ts +1 -1
- package/dist/types/utils/PartialEntity.d.ts.map +1 -1
- package/dist/types/utils/dbHelpers.d.ts.map +1 -1
- package/dist/types/utils/isDefined.d.ts.map +1 -1
- package/dist/types/utils/isIt.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/MigrationDescriber.ts +2 -2
- package/src/modifications/columns/CreateColumnModification.ts +1 -0
- package/src/modifications/columns/UpdateColumnDefinitionModification.ts +8 -3
- package/src/modifications/constraints/CreateUniqueConstraintModification.ts +19 -10
- package/src/modifications/constraints/RemoveUniqueConstraintModification.ts +52 -19
- package/src/modifications/entities/CreateEntityModification.ts +1 -0
- package/src/modifications/entities/CreateViewModification.ts +13 -2
- package/src/modifications/indexes/CreateIndexModification.ts +2 -2
- package/src/modifications/indexes/RemoveIndexModification.ts +3 -3
- package/src/modifications/upgrade/RemoveIndexNamesModification.ts +8 -2
- package/src/modifications/utils/columnUtils.ts +6 -3
- package/src/modifications/utils/schemaUpdateUtils.ts +1 -0
- package/src/utils/PartialEntity.ts +1 -1
- package/tests/cases/integration/convertManyHasOneToOneHasOneRelation.test.ts +1 -0
- package/tests/cases/integration/createAndDropIndex.test.ts +1 -0
- package/tests/cases/integration/createColumn.test.ts +27 -0
- package/tests/cases/integration/createEntity.test.ts +69 -0
- package/tests/cases/integration/createUnique.test.ts +91 -1
- package/tests/cases/integration/removeField.test.ts +6 -4
- package/tests/cases/integration/updateColumnDefinition.test.ts +27 -0
|
@@ -2,6 +2,6 @@ import { Model } from '@contember/schema';
|
|
|
2
2
|
export type PossibleEntityShapeInMigrations = Omit<Model.Entity, 'eventLog' | 'indexes' | 'unique'> & {
|
|
3
3
|
eventLog?: Model.Entity['eventLog'];
|
|
4
4
|
indexes?: (readonly Model.Index[]) | Readonly<Record<string, Model.Index>>;
|
|
5
|
-
unique: (readonly Model.UniqueConstraint[]) | Readonly<Record<string, Model.UniqueConstraint>>;
|
|
5
|
+
unique: (readonly (Model.UniqueConstraint | Model.UniqueIndex)[]) | Readonly<Record<string, Model.UniqueConstraint>>;
|
|
6
6
|
};
|
|
7
7
|
//# sourceMappingURL=PartialEntity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PartialEntity.d.ts","sourceRoot":"","sources":["../../../src/utils/PartialEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAIzC,MAAM,MAAM,+BAA+B,GACxC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC,GACrD;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,SAAU,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3E,MAAM,EAAE,CAAC,SAAU,KAAK,CAAC,gBAAgB,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"PartialEntity.d.ts","sourceRoot":"","sources":["../../../src/utils/PartialEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAIzC,MAAM,MAAM,+BAA+B,GACxC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC,GACrD;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,SAAU,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3E,MAAM,EAAE,CAAC,SAAU,CAAC,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAA;CACrH,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dbHelpers.d.ts","sourceRoot":"","sources":["../../../src/utils/dbHelpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"dbHelpers.d.ts","sourceRoot":"","sources":["../../../src/utils/dbHelpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,WAA0C,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isDefined.d.ts","sourceRoot":"","sources":["../../../src/utils/isDefined.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,GAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"isDefined.d.ts","sourceRoot":"","sources":["../../../src/utils/isDefined.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,OAAO,SAAS,GAAG,CAAC,KAAG,KAAK,IAAI,CAAwB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isIt.d.ts","sourceRoot":"","sources":["../../../src/utils/isIt.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"isIt.d.ts","sourceRoot":"","sources":["../../../src/utils/isIt.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAG,GAAG,IAAI,CAKhH,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/schema-migrations",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.1.0-alpha.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/production/index.js",
|
|
6
6
|
"typings": "./dist/types/index.d.ts",
|
|
@@ -23,16 +23,16 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@contember/database": "2.0.
|
|
27
|
-
"@contember/database-migrations": "2.0.
|
|
28
|
-
"@contember/engine-common": "2.0.
|
|
29
|
-
"@contember/schema": "2.0.
|
|
30
|
-
"@contember/schema-utils": "2.0.
|
|
26
|
+
"@contember/database": "2.1.0-alpha.2",
|
|
27
|
+
"@contember/database-migrations": "2.1.0-alpha.2",
|
|
28
|
+
"@contember/engine-common": "2.1.0-alpha.2",
|
|
29
|
+
"@contember/schema": "2.1.0-alpha.2",
|
|
30
|
+
"@contember/schema-utils": "2.1.0-alpha.2",
|
|
31
31
|
"fast-deep-equal": "^3.1.3",
|
|
32
32
|
"rfc6902": "^5.1.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@contember/schema-definition": "2.0.
|
|
35
|
+
"@contember/schema-definition": "2.1.0-alpha.2"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"pg": "^8.9.0"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createEntityModification,
|
|
2
|
+
createEntityModification, createViewModification,
|
|
3
3
|
emptyModificationDescriptionContext,
|
|
4
4
|
ModificationDescription,
|
|
5
5
|
ModificationDescriptionContext,
|
|
@@ -62,7 +62,7 @@ export class MigrationDescriber {
|
|
|
62
62
|
const result = []
|
|
63
63
|
const createdEntities = []
|
|
64
64
|
for (const modification of migration.modifications) {
|
|
65
|
-
if (modification.modification === createEntityModification.id) {
|
|
65
|
+
if (modification.modification === createEntityModification.id || modification.modification === createViewModification.id) {
|
|
66
66
|
createdEntities.push(modification.entity.name)
|
|
67
67
|
}
|
|
68
68
|
const description = this.describeModification(
|
|
@@ -20,11 +20,15 @@ export class UpdateColumnDefinitionModificationHandler implements ModificationHa
|
|
|
20
20
|
const newColumn = this.data.definition
|
|
21
21
|
|
|
22
22
|
const hasNewSequence = !oldColumn.sequence && newColumn.sequence
|
|
23
|
-
const
|
|
23
|
+
const oldColumnType = getColumnSqlType(oldColumn)
|
|
24
24
|
const columnType = getColumnSqlType(newColumn)
|
|
25
|
+
const hasNewType = columnType !== oldColumnType
|
|
25
26
|
const hasNullableChanged = oldColumn.nullable !== newColumn.nullable
|
|
27
|
+
const hasNewCollation = newColumn.collation !== oldColumn.collation
|
|
26
28
|
|
|
27
|
-
const
|
|
29
|
+
const columnNameWrapped = wrapIdentifier(oldColumn.columnName)
|
|
30
|
+
const isChangedToArray = !oldColumn.list && newColumn.list
|
|
31
|
+
const usingCast = (isChangedToArray ? `ARRAY[${columnNameWrapped}]` : columnNameWrapped) + `::${columnType}`
|
|
28
32
|
|
|
29
33
|
const seedExpression = formatSeedExpression({
|
|
30
34
|
model: this.schema.model,
|
|
@@ -38,7 +42,8 @@ export class UpdateColumnDefinitionModificationHandler implements ModificationHa
|
|
|
38
42
|
const migrateWithUpdate = hasSeed && this.data.valueMigrationStrategy !== 'using'
|
|
39
43
|
|
|
40
44
|
builder.alterColumn(entity.tableName, oldColumn.columnName, {
|
|
41
|
-
|
|
45
|
+
collation: hasNewCollation ? wrapIdentifier(newColumn.collation || 'default') : undefined,
|
|
46
|
+
type: hasNewCollation || hasNewSequence || hasNewType || migrateWithUsing ? columnType : undefined,
|
|
42
47
|
notNull: hasNullableChanged && (!migrateWithUpdate || newColumn.nullable) ? !newColumn.nullable : undefined,
|
|
43
48
|
using: (() => {
|
|
44
49
|
if (hasNewSequence) {
|
|
@@ -15,9 +15,12 @@ export class CreateUniqueConstraintModificationHandler implements ModificationHa
|
|
|
15
15
|
constructor(private readonly data: CreateUniqueConstraintModificationData, private readonly schema: Schema) {
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
public createSql(builder: MigrationBuilder, {
|
|
18
|
+
public createSql(builder: MigrationBuilder, { invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {
|
|
19
19
|
const entity = this.schema.model.entities[this.data.entityName]
|
|
20
|
-
|
|
20
|
+
const shouldExecuteSql =
|
|
21
|
+
!entity.view
|
|
22
|
+
|| (this.data.unique.index && entity.view.materialized)
|
|
23
|
+
if (!shouldExecuteSql) {
|
|
21
24
|
return
|
|
22
25
|
}
|
|
23
26
|
const fields = this.data.unique.fields
|
|
@@ -30,14 +33,20 @@ export class CreateUniqueConstraintModificationHandler implements ModificationHa
|
|
|
30
33
|
const tableNameId = wrapIdentifier(entity.tableName)
|
|
31
34
|
const columnNameIds = columns.map(wrapIdentifier)
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} else
|
|
37
|
-
checkModifier = '
|
|
36
|
+
if ('index' in this.data.unique && this.data.unique.index) {
|
|
37
|
+
const nulls = this.data.unique.nulls === 'not distinct' ? ' NULLS NOT DISTINCT' : ' NULLS DISTINCT'
|
|
38
|
+
builder.sql(`CREATE UNIQUE INDEX ON ${tableNameId} (${columnNameIds.join(', ')})${nulls}`)
|
|
39
|
+
} else {
|
|
40
|
+
let checkModifier = ''
|
|
41
|
+
if (this.data.unique.timing === 'deferred') {
|
|
42
|
+
checkModifier = ' INITIALLY DEFERRED'
|
|
43
|
+
} else if (this.data.unique.timing === 'deferrable') {
|
|
44
|
+
checkModifier = ' DEFERRABLE'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
builder.sql(`ALTER TABLE ${tableNameId} ADD UNIQUE (${columnNameIds.join(', ')})${checkModifier}`)
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
builder.sql(`ALTER TABLE ${tableNameId} ADD UNIQUE (${columnNameIds.join(', ')})${checkModifier}`)
|
|
41
50
|
|
|
42
51
|
invalidateDatabaseMetadata()
|
|
43
52
|
}
|
|
@@ -56,7 +65,7 @@ export class CreateUniqueConstraintModificationHandler implements ModificationHa
|
|
|
56
65
|
|
|
57
66
|
describe({ createdEntities }: { createdEntities: string[] }) {
|
|
58
67
|
return {
|
|
59
|
-
message: `Create unique constraint (${this.data.unique.fields.join(', ')}) on entity ${this.data.entityName}`,
|
|
68
|
+
message: `Create unique ${this.data.unique.index ? 'index' : 'constraint'} (${this.data.unique.fields.join(', ')}) on entity ${this.data.entityName}`,
|
|
60
69
|
failureWarning: !createdEntities.includes(this.data.entityName)
|
|
61
70
|
? 'Make sure no conflicting rows exists, otherwise this may fail in runtime.'
|
|
62
71
|
: undefined,
|
|
@@ -72,7 +81,7 @@ export const createUniqueConstraintModification = createModificationType({
|
|
|
72
81
|
|
|
73
82
|
export interface CreateUniqueConstraintModificationData {
|
|
74
83
|
entityName: string
|
|
75
|
-
unique: Model.UniqueConstraint
|
|
84
|
+
unique: Model.UniqueConstraint | Model.UniqueIndex
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
export class CreateUniqueConstraintDiffer implements Differ {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MigrationBuilder } from '@contember/database-migrations'
|
|
2
|
-
import { Schema } from '@contember/schema'
|
|
2
|
+
import { Model, Schema } from '@contember/schema'
|
|
3
3
|
import { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'
|
|
4
4
|
import {
|
|
5
5
|
createModificationType,
|
|
@@ -17,32 +17,55 @@ export class RemoveUniqueConstraintModificationHandler implements ModificationHa
|
|
|
17
17
|
|
|
18
18
|
public createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {
|
|
19
19
|
const entity = this.schema.model.entities[this.data.entityName]
|
|
20
|
-
|
|
20
|
+
const unique = this.getUnique()
|
|
21
|
+
|
|
22
|
+
const shouldExecuteSql =
|
|
23
|
+
!entity.view
|
|
24
|
+
|| (unique.index && entity.view.materialized)
|
|
25
|
+
|
|
26
|
+
if (!shouldExecuteSql) {
|
|
21
27
|
return
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
const fields = this.getFields()
|
|
25
30
|
|
|
26
31
|
const columns = getUniqueConstraintColumns({
|
|
27
32
|
entity,
|
|
28
|
-
fields: fields,
|
|
33
|
+
fields: unique.fields,
|
|
29
34
|
model: this.schema.model,
|
|
30
35
|
})
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
if (unique.index) {
|
|
38
|
+
const indexNames = databaseMetadata.indexes.filter({
|
|
39
|
+
tableName: entity.tableName,
|
|
40
|
+
columnNames: columns,
|
|
41
|
+
unique: true,
|
|
42
|
+
}).getNames()
|
|
43
|
+
|
|
44
|
+
for (const name of indexNames) {
|
|
45
|
+
builder.sql(`DROP INDEX ${wrapIdentifier(name)}`)
|
|
46
|
+
}
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
} else {
|
|
49
|
+
|
|
50
|
+
const constraintNames = databaseMetadata.uniqueConstraints.filter({
|
|
51
|
+
tableName: entity.tableName,
|
|
52
|
+
columnNames: columns,
|
|
53
|
+
}).getNames()
|
|
54
|
+
|
|
55
|
+
for (const name of constraintNames) {
|
|
56
|
+
builder.sql(`ALTER TABLE ${wrapIdentifier(entity.tableName)} DROP CONSTRAINT ${wrapIdentifier(name)}`)
|
|
57
|
+
}
|
|
36
58
|
}
|
|
37
59
|
|
|
60
|
+
|
|
38
61
|
invalidateDatabaseMetadata()
|
|
39
62
|
}
|
|
40
63
|
|
|
41
64
|
public getSchemaUpdater(): SchemaUpdater {
|
|
42
|
-
const
|
|
65
|
+
const thisUnique = this.getUnique()
|
|
43
66
|
return updateModel(
|
|
44
67
|
updateEntity(this.data.entityName, ({ entity }) => {
|
|
45
|
-
const unique = entity.unique.filter(it => !deepEqual(it
|
|
68
|
+
const unique = entity.unique.filter(it => !deepEqual(it, thisUnique))
|
|
46
69
|
return {
|
|
47
70
|
...entity,
|
|
48
71
|
unique,
|
|
@@ -52,20 +75,23 @@ export class RemoveUniqueConstraintModificationHandler implements ModificationHa
|
|
|
52
75
|
}
|
|
53
76
|
|
|
54
77
|
describe() {
|
|
55
|
-
const
|
|
56
|
-
return { message: `Remove unique constraint (${fields.join(', ')}) on entity ${this.data.entityName}` }
|
|
78
|
+
const unique = this.getUnique()
|
|
79
|
+
return { message: `Remove unique ${unique.index ? 'index' : 'constraint'} (${unique.fields.join(', ')}) on entity ${this.data.entityName}` }
|
|
57
80
|
}
|
|
58
81
|
|
|
59
|
-
|
|
82
|
+
getUnique(): Model.Unique {
|
|
83
|
+
if ('unique' in this.data) {
|
|
84
|
+
return this.data.unique
|
|
85
|
+
}
|
|
60
86
|
const entity = this.schema.model.entities[this.data.entityName]
|
|
61
|
-
const
|
|
62
|
-
? entity.unique.find(it => it.name === this.data.constraintName)
|
|
63
|
-
: this.data.fields
|
|
87
|
+
const unique = 'constraintName' in this.data
|
|
88
|
+
? entity.unique.find(it => 'name' in it && it.name === this.data.constraintName)
|
|
89
|
+
: entity.unique.find(it => deepEqual(it.fields, this.data.fields))
|
|
64
90
|
|
|
65
|
-
if (!
|
|
91
|
+
if (!unique) {
|
|
66
92
|
throw new Error()
|
|
67
93
|
}
|
|
68
|
-
return
|
|
94
|
+
return unique
|
|
69
95
|
}
|
|
70
96
|
}
|
|
71
97
|
|
|
@@ -75,6 +101,13 @@ export const removeUniqueConstraintModification = createModificationType({
|
|
|
75
101
|
})
|
|
76
102
|
|
|
77
103
|
export type RemoveUniqueConstraintModificationData =
|
|
104
|
+
| {
|
|
105
|
+
entityName: string
|
|
106
|
+
fields?: never
|
|
107
|
+
constraintName?: never
|
|
108
|
+
unique: Model.Unique
|
|
109
|
+
}
|
|
110
|
+
// deprecated
|
|
78
111
|
| {
|
|
79
112
|
entityName: string
|
|
80
113
|
constraintName: string
|
|
@@ -96,12 +129,12 @@ export class RemoveUniqueConstraintDiffer implements Differ {
|
|
|
96
129
|
if (!updatedEntity) {
|
|
97
130
|
return false
|
|
98
131
|
}
|
|
99
|
-
return !updatedEntity.unique.find(uniq => deepEqual(uniq
|
|
132
|
+
return !updatedEntity.unique.find(uniq => deepEqual(uniq, it))
|
|
100
133
|
})
|
|
101
134
|
.map(unique =>
|
|
102
135
|
removeUniqueConstraintModification.createModification({
|
|
103
136
|
entityName: entity.name,
|
|
104
|
-
|
|
137
|
+
unique: unique,
|
|
105
138
|
}),
|
|
106
139
|
),
|
|
107
140
|
)
|
|
@@ -13,7 +13,13 @@ export class CreateViewModificationHandler implements ModificationHandler<Create
|
|
|
13
13
|
if (!entity.view) {
|
|
14
14
|
throw new Error()
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
if (entity.view.materialized) {
|
|
17
|
+
builder.createMaterializedView(entity.tableName, {
|
|
18
|
+
data: this.data.noData !== true,
|
|
19
|
+
}, entity.view.sql)
|
|
20
|
+
} else {
|
|
21
|
+
builder.createView(entity.tableName, {}, entity.view.sql)
|
|
22
|
+
}
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
public getSchemaUpdater(): SchemaUpdater {
|
|
@@ -58,7 +64,11 @@ export class CreateViewDiffer implements Differ {
|
|
|
58
64
|
cascadeCreate(updatedSchema.model.entities[dependency])
|
|
59
65
|
}
|
|
60
66
|
modifications.push(createViewModification.createModification({
|
|
61
|
-
entity:
|
|
67
|
+
entity: {
|
|
68
|
+
...entity,
|
|
69
|
+
indexes: [],
|
|
70
|
+
unique: [],
|
|
71
|
+
},
|
|
62
72
|
}))
|
|
63
73
|
}
|
|
64
74
|
for (const view of newViews) {
|
|
@@ -70,4 +80,5 @@ export class CreateViewDiffer implements Differ {
|
|
|
70
80
|
|
|
71
81
|
export interface CreateViewModificationData {
|
|
72
82
|
entity: PossibleEntityShapeInMigrations
|
|
83
|
+
noData?: boolean
|
|
73
84
|
}
|
|
@@ -16,7 +16,7 @@ export class CreateIndexModificationHandler implements ModificationHandler<Creat
|
|
|
16
16
|
|
|
17
17
|
public createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {
|
|
18
18
|
const entity = this.schema.model.entities[this.data.entityName]
|
|
19
|
-
if (entity.view) {
|
|
19
|
+
if (entity.view && !entity.view.materialized) {
|
|
20
20
|
return
|
|
21
21
|
}
|
|
22
22
|
const fields = this.data.index.fields
|
|
@@ -67,7 +67,7 @@ export class CreateIndexDiffer implements Differ {
|
|
|
67
67
|
createDiff(originalSchema: Schema, updatedSchema: Schema) {
|
|
68
68
|
return Object.values(updatedSchema.model.entities).flatMap(entity =>
|
|
69
69
|
entity.indexes
|
|
70
|
-
.filter(it => !originalSchema.model.entities[entity.name].indexes.find(idx => deepEqual(idx
|
|
70
|
+
.filter(it => !originalSchema.model.entities[entity.name].indexes.find(idx => deepEqual(idx, it)))
|
|
71
71
|
.map(index => createIndexModification.createModification({
|
|
72
72
|
entityName: entity.name,
|
|
73
73
|
index,
|
|
@@ -16,7 +16,7 @@ export class RemoveIndexModificationHandler implements ModificationHandler<Remov
|
|
|
16
16
|
|
|
17
17
|
public createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {
|
|
18
18
|
const entity = this.schema.model.entities[this.data.entityName]
|
|
19
|
-
if (entity.view) {
|
|
19
|
+
if (entity.view && !entity.view.materialized) {
|
|
20
20
|
return
|
|
21
21
|
}
|
|
22
22
|
const fields = this.getFields()
|
|
@@ -27,7 +27,7 @@ export class RemoveIndexModificationHandler implements ModificationHandler<Remov
|
|
|
27
27
|
model: this.schema.model,
|
|
28
28
|
})
|
|
29
29
|
|
|
30
|
-
const indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns }).getNames()
|
|
30
|
+
const indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns, unique: false }).getNames()
|
|
31
31
|
|
|
32
32
|
for (const name of indexNames) {
|
|
33
33
|
builder.sql(`DROP INDEX ${wrapIdentifier(name)}`)
|
|
@@ -94,7 +94,7 @@ export class RemoveIndexDiffer implements Differ {
|
|
|
94
94
|
if (!updatedEntity) {
|
|
95
95
|
return false
|
|
96
96
|
}
|
|
97
|
-
return !updatedEntity.indexes.find(index => deepEqual(index
|
|
97
|
+
return !updatedEntity.indexes.find(index => deepEqual(index, it))
|
|
98
98
|
},
|
|
99
99
|
)
|
|
100
100
|
.map(index =>
|
|
@@ -14,7 +14,13 @@ export class RemoveIndexNamesModificationHandler implements ModificationHandler<
|
|
|
14
14
|
return {
|
|
15
15
|
...entity,
|
|
16
16
|
indexes: entity.indexes.map(({ name, ...other }) => other),
|
|
17
|
-
unique: entity.unique.map(
|
|
17
|
+
unique: entity.unique.map(it => {
|
|
18
|
+
if ('name' in it) {
|
|
19
|
+
const { name, ...other } = it
|
|
20
|
+
return other
|
|
21
|
+
}
|
|
22
|
+
return it
|
|
23
|
+
}),
|
|
18
24
|
}
|
|
19
25
|
}),
|
|
20
26
|
)
|
|
@@ -36,7 +42,7 @@ export type RemoveIndexNamesModificationData = {}
|
|
|
36
42
|
export class RemoveIndexNamesDiffer implements Differ {
|
|
37
43
|
createDiff(originalSchema: Schema) {
|
|
38
44
|
const hasNames = !!Object.values(originalSchema.model.entities).find(it => {
|
|
39
|
-
return it.indexes.find(it => !!it.name) || it.unique.find(it => !!it.name)
|
|
45
|
+
return it.indexes.find(it => !!it.name) || it.unique.find(it => 'name' in it && !!it.name)
|
|
40
46
|
})
|
|
41
47
|
if (hasNames) {
|
|
42
48
|
return [removeIndexNamesModification.createModification({})]
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Model } from '@contember/schema'
|
|
2
2
|
|
|
3
|
-
export const getColumnSqlType = (column: Pick<Model.AnyColumn, 'type' | 'columnType'>) =>
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
export const getColumnSqlType = (column: Pick<Model.AnyColumn, 'type' | 'columnType' | 'list'>) =>
|
|
4
|
+
(column.type === Model.ColumnType.Enum
|
|
5
|
+
? `"${column.columnType}"`
|
|
6
|
+
: column.columnType
|
|
7
|
+
)
|
|
8
|
+
+ (column.list ? '[]' : '')
|
|
@@ -119,6 +119,7 @@ export const updateAclFieldPermissions =
|
|
|
119
119
|
read: value => updater(value, entityName, Acl.Operation.read),
|
|
120
120
|
delete: value => value,
|
|
121
121
|
customPrimary: value => value,
|
|
122
|
+
refreshMaterializedView: value => value,
|
|
122
123
|
noRoot: value => value,
|
|
123
124
|
}
|
|
124
125
|
const types: (keyof Acl.EntityOperations)[] = ['create', 'update', 'read', 'delete', 'customPrimary', 'noRoot']
|
|
@@ -7,5 +7,5 @@ export type PossibleEntityShapeInMigrations =
|
|
|
7
7
|
& {
|
|
8
8
|
eventLog?: Model.Entity['eventLog']
|
|
9
9
|
indexes?: (readonly Model.Index[]) | Readonly<Record<string, Model.Index>>
|
|
10
|
-
unique: (readonly Model.UniqueConstraint[]) | Readonly<Record<string, Model.UniqueConstraint>>
|
|
10
|
+
unique: (readonly (Model.UniqueConstraint | Model.UniqueIndex)[]) | Readonly<Record<string, Model.UniqueConstraint>>
|
|
11
11
|
}
|
|
@@ -172,3 +172,30 @@ ALTER "active" SET NOT NULL; ALTER TABLE "author" ADD "created_at" timestamptz;
|
|
|
172
172
|
ALTER TABLE "author" ALTER "created_at" SET DATA TYPE timestamptz USING $pga$2024-01-01 10:00$pga$, ALTER "created_at" SET NOT NULL;
|
|
173
173
|
`,
|
|
174
174
|
}))
|
|
175
|
+
|
|
176
|
+
describe('create list column', () => testMigrations({
|
|
177
|
+
original: createSchema({
|
|
178
|
+
Author: class Author {
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
updated: createSchema({
|
|
182
|
+
Author: class Author {
|
|
183
|
+
emails = def.stringColumn().list()
|
|
184
|
+
},
|
|
185
|
+
}),
|
|
186
|
+
diff: [
|
|
187
|
+
{
|
|
188
|
+
modification: 'createColumn',
|
|
189
|
+
entityName: 'Author',
|
|
190
|
+
field: {
|
|
191
|
+
columnName: 'emails',
|
|
192
|
+
name: 'emails',
|
|
193
|
+
nullable: true,
|
|
194
|
+
type: Model.ColumnType.String,
|
|
195
|
+
columnType: 'text',
|
|
196
|
+
list: true,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
sql: SQL`ALTER TABLE "author" ADD "emails" text[];`,
|
|
201
|
+
}))
|
|
@@ -199,3 +199,72 @@ CREATE TRIGGER "log_event" AFTER INSERT OR UPDATE OR DELETE ON "author" FOR EACH
|
|
|
199
199
|
CREATE CONSTRAINT TRIGGER "log_event_trx" AFTER INSERT OR UPDATE OR DELETE ON "author" DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE "system"."trigger_event_commit"();
|
|
200
200
|
ALTER TABLE "author" ADD "name" text;`,
|
|
201
201
|
}))
|
|
202
|
+
|
|
203
|
+
namespace SchemaWithIndex {
|
|
204
|
+
@def.Index('name')
|
|
205
|
+
export class Author {
|
|
206
|
+
name = def.stringColumn()
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
describe('entity with index', () => testMigrations({
|
|
210
|
+
original: {},
|
|
211
|
+
updated: createSchema(SchemaWithIndex),
|
|
212
|
+
diff: [
|
|
213
|
+
{
|
|
214
|
+
modification: 'createEntity',
|
|
215
|
+
entity: {
|
|
216
|
+
fields: {
|
|
217
|
+
id: {
|
|
218
|
+
columnName: 'id',
|
|
219
|
+
name: 'id',
|
|
220
|
+
nullable: false,
|
|
221
|
+
type: Model.ColumnType.Uuid,
|
|
222
|
+
columnType: 'uuid',
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
name: 'Author',
|
|
226
|
+
primary: 'id',
|
|
227
|
+
primaryColumn: 'id',
|
|
228
|
+
tableName: 'author',
|
|
229
|
+
unique: [],
|
|
230
|
+
eventLog: {
|
|
231
|
+
enabled: true,
|
|
232
|
+
},
|
|
233
|
+
indexes: [],
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
modification: 'createColumn',
|
|
238
|
+
entityName: 'Author',
|
|
239
|
+
field: {
|
|
240
|
+
columnName: 'name',
|
|
241
|
+
name: 'name',
|
|
242
|
+
nullable: true,
|
|
243
|
+
type: Model.ColumnType.String,
|
|
244
|
+
columnType: 'text',
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
modification: 'createIndex',
|
|
249
|
+
entityName: 'Author',
|
|
250
|
+
index: { fields: ['name'] },
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
sql: SQL`CREATE TABLE "author"
|
|
254
|
+
(
|
|
255
|
+
"id" uuid PRIMARY KEY NOT NULL
|
|
256
|
+
);
|
|
257
|
+
CREATE TRIGGER "log_event"
|
|
258
|
+
AFTER INSERT OR UPDATE OR DELETE
|
|
259
|
+
ON "author"
|
|
260
|
+
FOR EACH ROW
|
|
261
|
+
EXECUTE PROCEDURE "system"."trigger_event"($pga$id$pga$);
|
|
262
|
+
CREATE CONSTRAINT TRIGGER "log_event_trx"
|
|
263
|
+
AFTER INSERT OR UPDATE OR DELETE
|
|
264
|
+
ON "author" DEFERRABLE INITIALLY DEFERRED
|
|
265
|
+
FOR EACH ROW
|
|
266
|
+
EXECUTE PROCEDURE "system"."trigger_event_commit"();
|
|
267
|
+
ALTER TABLE "author"
|
|
268
|
+
ADD "name" text;
|
|
269
|
+
CREATE INDEX ON "author" ("name");`,
|
|
270
|
+
}))
|