@contember/schema-migrations 2.1.0-alpha.2 → 2.1.0-alpha.21
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/modifications/columns/UpdateColumnDefinitionModification.cjs +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.cjs +5 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.cjs.map +1 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.js +5 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.js.map +1 -1
- package/dist/development/src/modifications/enums/UpdateEnumModification.cjs +36 -8
- package/dist/development/src/modifications/enums/UpdateEnumModification.cjs.map +1 -1
- package/dist/development/src/modifications/enums/UpdateEnumModification.js +34 -6
- package/dist/development/src/modifications/enums/UpdateEnumModification.js.map +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.js +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.cjs +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.js +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.cjs +5 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.cjs.map +1 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.js +5 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.js.map +1 -1
- package/dist/production/src/modifications/enums/UpdateEnumModification.cjs +36 -8
- package/dist/production/src/modifications/enums/UpdateEnumModification.cjs.map +1 -1
- package/dist/production/src/modifications/enums/UpdateEnumModification.js +34 -6
- package/dist/production/src/modifications/enums/UpdateEnumModification.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/modifications/columns/UpdateColumnDefinitionModification.d.ts.map +1 -1
- package/dist/types/modifications/entities/RemoveEntityModification.d.ts.map +1 -1
- package/dist/types/modifications/enums/UpdateEnumModification.d.ts +1 -0
- package/dist/types/modifications/enums/UpdateEnumModification.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/modifications/columns/UpdateColumnDefinitionModification.ts +3 -1
- package/src/modifications/constraints/CreateUniqueConstraintModification.ts +1 -1
- package/src/modifications/entities/RemoveEntityModification.ts +5 -1
- package/src/modifications/enums/UpdateEnumModification.ts +44 -7
- package/tests/cases/integration/createUnique.test.ts +1 -1
- package/tests/cases/integration/updateColumnDefinition.test.ts +28 -1
- package/tests/cases/integration/updateEnum.test.ts +43 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/schema-migrations",
|
|
3
|
-
"version": "2.1.0-alpha.
|
|
3
|
+
"version": "2.1.0-alpha.21",
|
|
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.1.0-alpha.
|
|
27
|
-
"@contember/database-migrations": "2.1.0-alpha.
|
|
28
|
-
"@contember/engine-common": "2.1.0-alpha.
|
|
29
|
-
"@contember/schema": "2.1.0-alpha.
|
|
30
|
-
"@contember/schema-utils": "2.1.0-alpha.
|
|
26
|
+
"@contember/database": "2.1.0-alpha.21",
|
|
27
|
+
"@contember/database-migrations": "2.1.0-alpha.21",
|
|
28
|
+
"@contember/engine-common": "2.1.0-alpha.21",
|
|
29
|
+
"@contember/schema": "2.1.0-alpha.21",
|
|
30
|
+
"@contember/schema-utils": "2.1.0-alpha.21",
|
|
31
31
|
"fast-deep-equal": "^3.1.3",
|
|
32
32
|
"rfc6902": "^5.1.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@contember/schema-definition": "2.1.0-alpha.
|
|
35
|
+
"@contember/schema-definition": "2.1.0-alpha.21"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"pg": "^8.9.0"
|
|
@@ -28,7 +28,9 @@ export class UpdateColumnDefinitionModificationHandler implements ModificationHa
|
|
|
28
28
|
|
|
29
29
|
const columnNameWrapped = wrapIdentifier(oldColumn.columnName)
|
|
30
30
|
const isChangedToArray = !oldColumn.list && newColumn.list
|
|
31
|
-
const usingCast =
|
|
31
|
+
const usingCast = isChangedToArray
|
|
32
|
+
? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? 'NULL' : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END`
|
|
33
|
+
: `${columnNameWrapped}::${columnType}`
|
|
32
34
|
|
|
33
35
|
const seedExpression = formatSeedExpression({
|
|
34
36
|
model: this.schema.model,
|
|
@@ -34,7 +34,7 @@ export class CreateUniqueConstraintModificationHandler implements ModificationHa
|
|
|
34
34
|
const columnNameIds = columns.map(wrapIdentifier)
|
|
35
35
|
|
|
36
36
|
if ('index' in this.data.unique && this.data.unique.index) {
|
|
37
|
-
const nulls = this.data.unique.nulls === 'not distinct' ? ' NULLS NOT DISTINCT' : '
|
|
37
|
+
const nulls = this.data.unique.nulls === 'not distinct' ? ' NULLS NOT DISTINCT' : ''
|
|
38
38
|
builder.sql(`CREATE UNIQUE INDEX ON ${tableNameId} (${columnNameIds.join(', ')})${nulls}`)
|
|
39
39
|
} else {
|
|
40
40
|
let checkModifier = ''
|
|
@@ -31,7 +31,11 @@ export class RemoveEntityModificationHandler implements ModificationHandler<Remo
|
|
|
31
31
|
public createSql(builder: MigrationBuilder, options: ModificationHandlerCreateSqlOptions): void {
|
|
32
32
|
const entity = this.schema.model.entities[this.data.entityName]
|
|
33
33
|
if (entity.view) {
|
|
34
|
-
|
|
34
|
+
if (entity.view.materialized) {
|
|
35
|
+
builder.dropMaterializedView(entity.tableName)
|
|
36
|
+
} else {
|
|
37
|
+
builder.dropView(entity.tableName)
|
|
38
|
+
}
|
|
35
39
|
return
|
|
36
40
|
}
|
|
37
41
|
if (this.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS) {
|
|
@@ -1,20 +1,57 @@
|
|
|
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, updateModel } from '../utils/schemaUpdateUtils'
|
|
4
4
|
import { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'
|
|
5
5
|
import deepEqual from 'fast-deep-equal'
|
|
6
6
|
import { createCheck, getConstraintName } from './enumUtils'
|
|
7
|
+
import { getColumnSqlType } from '../utils/columnUtils'
|
|
7
8
|
|
|
8
9
|
export class UpdateEnumModificationHandler implements ModificationHandler<UpdateEnumModificationData> {
|
|
9
10
|
constructor(private readonly data: UpdateEnumModificationData, private readonly schema: Schema) {}
|
|
10
11
|
|
|
11
12
|
public createSql(builder: MigrationBuilder): void {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
if (!this.requiresNewDomain()) {
|
|
14
|
+
builder.sql(`
|
|
15
|
+
ALTER DOMAIN "${this.data.enumName}"
|
|
16
|
+
DROP CONSTRAINT ${getConstraintName(this.data.enumName)}`)
|
|
17
|
+
builder.sql(`
|
|
18
|
+
ALTER DOMAIN "${this.data.enumName}"
|
|
19
|
+
ADD CONSTRAINT ${getConstraintName(this.data.enumName)} CHECK (${createCheck(this.data.values)})`)
|
|
20
|
+
} else {
|
|
21
|
+
/**
|
|
22
|
+
* Because postgres does not support altering domain constrains
|
|
23
|
+
* when used in composite types (like arrays) we need to:
|
|
24
|
+
* - create a new domain with the new constraint
|
|
25
|
+
* - update all the columns using the old domain to use the new domain
|
|
26
|
+
* - drop the old domain and rename the new domain to the old name
|
|
27
|
+
*/
|
|
28
|
+
const oldName = `${this.data.enumName}__old`
|
|
29
|
+
builder.renameDomain(this.data.enumName, oldName)
|
|
30
|
+
|
|
31
|
+
builder.createDomain(this.data.enumName, 'text', {
|
|
32
|
+
check: createCheck(this.data.values),
|
|
33
|
+
constraintName: getConstraintName(this.data.enumName),
|
|
34
|
+
})
|
|
35
|
+
for (const entity of Object.values(this.schema.model.entities)) {
|
|
36
|
+
for (const field of Object.values(entity.fields)) {
|
|
37
|
+
if (field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName) {
|
|
38
|
+
builder.alterColumn(entity.tableName, field.columnName, {
|
|
39
|
+
type: getColumnSqlType(field),
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
builder.dropDomain(oldName)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private requiresNewDomain(): boolean {
|
|
50
|
+
return Object.values(this.schema.model.entities).some(it => {
|
|
51
|
+
return Object.values(it.fields).some(field => {
|
|
52
|
+
return field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName && field.list
|
|
53
|
+
})
|
|
54
|
+
})
|
|
18
55
|
}
|
|
19
56
|
|
|
20
57
|
public getSchemaUpdater(): SchemaUpdater {
|
|
@@ -251,5 +251,32 @@ describe('change string to array string', () => testMigrations({
|
|
|
251
251
|
},
|
|
252
252
|
}),
|
|
253
253
|
],
|
|
254
|
-
sql: SQL`ALTER TABLE "author" ALTER "email" SET DATA TYPE text[] USING ARRAY["email"]::text[];`,
|
|
254
|
+
sql: SQL`ALTER TABLE "author" ALTER "email" SET DATA TYPE text[] USING CASE WHEN "email" IS NULL THEN NULL ELSE ARRAY["email"]::text[] END;`,
|
|
255
|
+
}))
|
|
256
|
+
|
|
257
|
+
describe('change string to array string not null', () => testMigrations({
|
|
258
|
+
original: createSchema({
|
|
259
|
+
Author: class Author {
|
|
260
|
+
email = def.stringColumn().notNull()
|
|
261
|
+
},
|
|
262
|
+
}),
|
|
263
|
+
updated: createSchema({
|
|
264
|
+
Author: class Author {
|
|
265
|
+
email = def.stringColumn().list().notNull()
|
|
266
|
+
},
|
|
267
|
+
}),
|
|
268
|
+
diff: [
|
|
269
|
+
updateColumnDefinitionModification.createModification({
|
|
270
|
+
entityName: 'Author',
|
|
271
|
+
fieldName: 'email',
|
|
272
|
+
definition: {
|
|
273
|
+
type: Model.ColumnType.String,
|
|
274
|
+
columnType: 'text',
|
|
275
|
+
nullable: false,
|
|
276
|
+
list: true,
|
|
277
|
+
},
|
|
278
|
+
}),
|
|
279
|
+
],
|
|
280
|
+
sql: SQL`ALTER TABLE "author"
|
|
281
|
+
ALTER "email" SET DATA TYPE text[] USING CASE WHEN "email" IS NULL THEN ARRAY[]::text[] ELSE ARRAY["email"]::text[] END;`,
|
|
255
282
|
}))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe } from 'bun:test'
|
|
2
2
|
import { testMigrations } from '../../src/tests'
|
|
3
|
-
import { SchemaBuilder } from '@contember/schema-definition'
|
|
3
|
+
import { c, createSchema, SchemaBuilder } from '@contember/schema-definition'
|
|
4
4
|
import { Model } from '@contember/schema'
|
|
5
5
|
import { SQL } from '../../src/tags'
|
|
6
6
|
|
|
@@ -35,3 +35,45 @@ describe('update enum', () => testMigrations({
|
|
|
35
35
|
sql: SQL`ALTER DOMAIN "postStatus" DROP CONSTRAINT poststatus_check;
|
|
36
36
|
ALTER DOMAIN "postStatus" ADD CONSTRAINT poststatus_check CHECK (VALUE IN('publish','draft'));`,
|
|
37
37
|
}))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
namespace EnumModelOriginal {
|
|
41
|
+
export const FooStatus = c.createEnum('foo', 'bar')
|
|
42
|
+
export class Foo {
|
|
43
|
+
|
|
44
|
+
status = c.enumColumn(FooStatus).notNull()
|
|
45
|
+
statusList = c.enumColumn(FooStatus).notNull().list()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
namespace EnumModelUpdated {
|
|
50
|
+
export const FooStatus = c.createEnum('foo', 'bar', 'baz')
|
|
51
|
+
|
|
52
|
+
export class Foo {
|
|
53
|
+
|
|
54
|
+
status = c.enumColumn(FooStatus).notNull()
|
|
55
|
+
statusList = c.enumColumn(FooStatus).notNull().list()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
describe('update enum if used in list', () => testMigrations({
|
|
61
|
+
original: {
|
|
62
|
+
model: createSchema(EnumModelOriginal).model,
|
|
63
|
+
},
|
|
64
|
+
updated: {
|
|
65
|
+
model: createSchema(EnumModelUpdated).model,
|
|
66
|
+
},
|
|
67
|
+
diff: [
|
|
68
|
+
{
|
|
69
|
+
modification: 'updateEnum',
|
|
70
|
+
enumName: 'FooStatus',
|
|
71
|
+
values: ['foo', 'bar', 'baz'],
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
sql: SQL`ALTER DOMAIN "FooStatus" RENAME TO "FooStatus__old";
|
|
75
|
+
CREATE DOMAIN "FooStatus" AS text CONSTRAINT "foostatus_check" CHECK (VALUE IN('foo','bar','baz'));
|
|
76
|
+
ALTER TABLE "foo" ALTER "status" SET DATA TYPE "FooStatus";
|
|
77
|
+
ALTER TABLE "foo" ALTER "status_list" SET DATA TYPE "FooStatus"[];
|
|
78
|
+
DROP DOMAIN "FooStatus__old";`,
|
|
79
|
+
}))
|