@contember/schema-migrations 1.3.0-alpha.8 → 1.3.0-beta.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.
Files changed (51) hide show
  1. package/dist/src/SchemaDiffer.d.ts +1 -1
  2. package/dist/src/SchemaDiffer.d.ts.map +1 -1
  3. package/dist/src/SchemaDiffer.js +8 -1
  4. package/dist/src/SchemaDiffer.js.map +1 -1
  5. package/dist/src/modifications/ModificationHandler.d.ts +1 -1
  6. package/dist/src/modifications/ModificationHandler.d.ts.map +1 -1
  7. package/dist/src/modifications/ModificationHandlerFactory.js +1 -2
  8. package/dist/src/modifications/ModificationHandlerFactory.js.map +1 -1
  9. package/dist/src/modifications/columns/CreateColumnModification.d.ts +2 -2
  10. package/dist/src/modifications/columns/CreateColumnModification.d.ts.map +1 -1
  11. package/dist/src/modifications/columns/CreateColumnModification.js +14 -24
  12. package/dist/src/modifications/columns/CreateColumnModification.js.map +1 -1
  13. package/dist/src/modifications/columns/UpdateColumnDefinitionModification.d.ts +5 -3
  14. package/dist/src/modifications/columns/UpdateColumnDefinitionModification.d.ts.map +1 -1
  15. package/dist/src/modifications/columns/UpdateColumnDefinitionModification.js +16 -1
  16. package/dist/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
  17. package/dist/src/modifications/columns/columnUtils.d.ts +14 -0
  18. package/dist/src/modifications/columns/columnUtils.d.ts.map +1 -0
  19. package/dist/src/modifications/columns/columnUtils.js +29 -0
  20. package/dist/src/modifications/columns/columnUtils.js.map +1 -0
  21. package/dist/src/modifications/constraints/RemoveUniqueConstraintModification.d.ts +1 -1
  22. package/dist/src/modifications/constraints/RemoveUniqueConstraintModification.d.ts.map +1 -1
  23. package/dist/src/modifications/indexes/RemoveIndexModification.d.ts +1 -1
  24. package/dist/src/modifications/indexes/RemoveIndexModification.d.ts.map +1 -1
  25. package/dist/src/modifications/relations/CreateRelationModification.d.ts +1 -1
  26. package/dist/src/modifications/relations/CreateRelationModification.d.ts.map +1 -1
  27. package/dist/src/modifications/relations/normalization.d.ts +2 -2
  28. package/dist/src/modifications/relations/normalization.d.ts.map +1 -1
  29. package/dist/src/modifications/settings/UpdateSettingsModification.d.ts +1 -1
  30. package/dist/src/modifications/settings/UpdateSettingsModification.d.ts.map +1 -1
  31. package/dist/src/modifications/upgrade/RemoveIndexNamesModification.d.ts +1 -1
  32. package/dist/src/modifications/upgrade/RemoveIndexNamesModification.d.ts.map +1 -1
  33. package/dist/src/modifications/utils/schemaUpdateUtils.d.ts +10 -10
  34. package/dist/src/modifications/utils/schemaUpdateUtils.d.ts.map +1 -1
  35. package/dist/src/modifications/utils/viewDependencies.d.ts +1 -1
  36. package/dist/src/modifications/utils/viewDependencies.d.ts.map +1 -1
  37. package/dist/src/tsconfig.tsbuildinfo +1 -1
  38. package/dist/src/utils/PartialEntity.d.ts +1 -1
  39. package/dist/src/utils/PartialEntity.d.ts.map +1 -1
  40. package/dist/tests/cases/integration/createColumn.test.js +0 -2
  41. package/dist/tests/cases/integration/createColumn.test.js.map +1 -1
  42. package/dist/tests/cases/integration/updateColumnDefinition.test.js +38 -0
  43. package/dist/tests/cases/integration/updateColumnDefinition.test.js.map +1 -1
  44. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  45. package/package.json +8 -8
  46. package/src/SchemaDiffer.ts +10 -11
  47. package/src/modifications/columns/CreateColumnModification.ts +19 -27
  48. package/src/modifications/columns/UpdateColumnDefinitionModification.ts +21 -2
  49. package/src/modifications/columns/columnUtils.ts +35 -0
  50. package/tests/cases/integration/createColumn.test.ts +0 -2
  51. package/tests/cases/integration/updateColumnDefinition.test.ts +32 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/schema-migrations",
3
- "version": "1.3.0-alpha.8",
3
+ "version": "1.3.0-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -9,20 +9,20 @@
9
9
  "default": "./dist/src/index.js"
10
10
  },
11
11
  "scripts": {
12
- "test": "vitest"
12
+ "test": "vitest --dir ./tests/cases"
13
13
  },
14
14
  "dependencies": {
15
- "@contember/database-migrations": "^1.3.0-alpha.8",
16
- "@contember/engine-common": "^1.3.0-alpha.8",
17
- "@contember/schema": "^1.3.0-alpha.8",
18
- "@contember/schema-utils": "^1.3.0-alpha.8",
15
+ "@contember/database-migrations": "1.3.0-beta.2",
16
+ "@contember/engine-common": "1.3.0-beta.2",
17
+ "@contember/schema": "1.3.0-beta.2",
18
+ "@contember/schema-utils": "1.3.0-beta.2",
19
19
  "fast-deep-equal": "^3.1.3",
20
20
  "rfc6902": "^5.0.1"
21
21
  },
22
22
  "devDependencies": {
23
- "@contember/schema-definition": "^1.3.0-alpha.8"
23
+ "@contember/schema-definition": "1.3.0-beta.2"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "pg": "^8.9.0"
27
27
  }
28
- }
28
+ }
@@ -1,12 +1,5 @@
1
1
  import { Schema } from '@contember/schema'
2
- import {
3
- deepCompare,
4
- isInverseRelation,
5
- isOwningRelation,
6
- isRelation,
7
- SchemaValidator,
8
- ValidationError,
9
- } from '@contember/schema-utils'
2
+ import { compareArraysIgnoreOrder, deepCompare, isInverseRelation, isOwningRelation, isRelation, SchemaValidator, ValidationError } from '@contember/schema-utils'
10
3
  import { SchemaMigrator } from './SchemaMigrator'
11
4
  import { Migration } from './Migration'
12
5
  import { ImplementationException } from './exceptions'
@@ -34,11 +27,11 @@ import {
34
27
  UpdateAclSchemaDiffer,
35
28
  UpdateColumnDefinitionDiffer,
36
29
  UpdateColumnNameDiffer,
30
+ UpdateEntityOrderByDiffer,
37
31
  UpdateEntityTableNameDiffer,
38
32
  UpdateEnumDiffer,
39
33
  UpdateRelationOnDeleteDiffer,
40
34
  UpdateRelationOrderByDiffer,
41
- UpdateEntityOrderByDiffer,
42
35
  UpdateValidationSchemaDiffer,
43
36
  VERSION_LATEST,
44
37
  } from './modifications'
@@ -124,9 +117,15 @@ export class SchemaDiffer {
124
117
  diffs.push(...differDiffs)
125
118
  }
126
119
 
127
-
128
120
  if (!skipRecreateValidation) {
129
- const errors = deepCompare(updatedSchema, appliedDiffsSchema, [])
121
+ const errors = deepCompare(updatedSchema, appliedDiffsSchema, [], path => {
122
+ if (path[0] === 'model' && path[1] === 'entities' && (path[3] === 'unique' || path[3] === 'index')) {
123
+ return (a, b) => {
124
+ return compareArraysIgnoreOrder(a, b, path)
125
+ }
126
+ }
127
+ return null
128
+ })
130
129
  if (errors.length === 0) {
131
130
  return diffs
132
131
  }
@@ -1,12 +1,11 @@
1
- import { escapeValue, MigrationBuilder } from '@contember/database-migrations'
2
- import { Model, Schema } from '@contember/schema'
1
+ import { MigrationBuilder } from '@contember/database-migrations'
2
+ import { JSONValue, Model, Schema } from '@contember/schema'
3
3
  import { addField, SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'
4
4
  import { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'
5
- import { wrapIdentifier } from '../../utils/dbHelpers'
6
- import { getColumnName, isColumn } from '@contember/schema-utils'
7
- import { ImplementationException } from '../../exceptions'
5
+ import { isColumn } from '@contember/schema-utils'
8
6
  import { createFields } from '../utils/diffUtils'
9
7
  import { getColumnSqlType } from '../utils/columnUtils'
8
+ import { fillSeed } from './columnUtils'
10
9
 
11
10
  export class CreateColumnModificationHandler implements ModificationHandler<CreateColumnModificationData> {
12
11
  constructor(private readonly data: CreateColumnModificationData, private readonly schema: Schema) {}
@@ -18,34 +17,27 @@ export class CreateColumnModificationHandler implements ModificationHandler<Crea
18
17
  }
19
18
  const column = this.data.field
20
19
  const hasSeed = this.data.fillValue !== undefined || this.data.copyValue !== undefined
20
+ const columnType = getColumnSqlType(column)
21
21
  builder.addColumn(entity.tableName, {
22
22
  [column.columnName]: {
23
- type: getColumnSqlType(column),
23
+ type: columnType,
24
24
  notNull: !column.nullable && !hasSeed,
25
25
  sequenceGenerated: column.sequence,
26
26
  },
27
27
  })
28
- if (hasSeed) {
29
- if (this.data.fillValue !== undefined) {
30
- builder.sql(`UPDATE ${wrapIdentifier(entity.tableName)}
31
- SET ${wrapIdentifier(column.columnName)} = ${escapeValue(this.data.fillValue)}`)
32
- } else if (this.data.copyValue !== undefined) {
33
- const copyFrom = getColumnName(this.schema.model, entity, this.data.copyValue)
34
- builder.sql(`UPDATE ${wrapIdentifier(entity.tableName)}
35
- SET ${wrapIdentifier(column.columnName)} = ${wrapIdentifier(copyFrom)}::${getColumnSqlType(column)}`)
36
- } else {
37
- throw new ImplementationException()
38
- }
39
-
40
- // event applier defers constraint check, we need to fire them before ALTER
41
- builder.sql(`SET CONSTRAINTS ALL IMMEDIATE`)
42
- builder.sql(`SET CONSTRAINTS ALL DEFERRED`)
43
28
 
44
- if (!column.nullable) {
45
- builder.alterColumn(entity.tableName, column.columnName, {
46
- notNull: true,
47
- })
48
- }
29
+ if (hasSeed) {
30
+ fillSeed({
31
+ builder,
32
+ type: 'creating',
33
+ model: this.schema.model,
34
+ entity,
35
+ columnName: column.columnName,
36
+ nullable: column.nullable,
37
+ columnType,
38
+ copyValue: this.data.copyValue,
39
+ fillValue: this.data.fillValue,
40
+ })
49
41
  }
50
42
  }
51
43
 
@@ -67,7 +59,7 @@ export class CreateColumnModificationHandler implements ModificationHandler<Crea
67
59
  export interface CreateColumnModificationData {
68
60
  entityName: string
69
61
  field: Model.AnyColumn
70
- fillValue?: any
62
+ fillValue?: JSONValue
71
63
  copyValue?: string
72
64
  }
73
65
 
@@ -1,11 +1,12 @@
1
1
  import { escapeValue, MigrationBuilder } from '@contember/database-migrations'
2
- import { Model, Schema } from '@contember/schema'
2
+ import { JSONValue, Model, Schema } from '@contember/schema'
3
3
  import { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/schemaUpdateUtils'
4
4
  import { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'
5
5
  import deepEqual from 'fast-deep-equal'
6
6
  import { updateColumns } from '../utils/diffUtils'
7
7
  import { wrapIdentifier } from '../../utils/dbHelpers'
8
8
  import { getColumnSqlType } from '../utils/columnUtils'
9
+ import { fillSeed } from './columnUtils'
9
10
 
10
11
  export class UpdateColumnDefinitionModificationHandler implements ModificationHandler<UpdateColumnDefinitionModificationData> {
11
12
  constructor(private readonly data: UpdateColumnDefinitionModificationData, private readonly schema: Schema) {}
@@ -24,9 +25,11 @@ export class UpdateColumnDefinitionModificationHandler implements ModificationHa
24
25
 
25
26
  const usingCast = `${wrapIdentifier(oldColumn.columnName)}::${columnType}`
26
27
 
28
+ const hasSeed = this.data.fillValue !== undefined || this.data.copyValue !== undefined
29
+
27
30
  builder.alterColumn(entity.tableName, oldColumn.columnName, {
28
31
  type: hasNewSequence || hasNewType ? columnType : undefined,
29
- notNull: oldColumn.nullable !== newColumn.nullable ? !newColumn.nullable : undefined,
32
+ notNull: oldColumn.nullable !== newColumn.nullable && (!hasSeed || newColumn.nullable) ? !newColumn.nullable : undefined,
30
33
  using: hasNewSequence
31
34
  ? `COALESCE(${usingCast}, nextval(PG_GET_SERIAL_SEQUENCE(${escapeValue(entity.tableName)}, ${escapeValue(oldColumn.columnName)})))`
32
35
  : hasNewType
@@ -35,6 +38,20 @@ export class UpdateColumnDefinitionModificationHandler implements ModificationHa
35
38
  sequenceGenerated: oldColumn.sequence && !newColumn.sequence ? false : (!oldColumn.sequence ? newColumn.sequence : undefined),
36
39
  })
37
40
 
41
+ if (hasSeed) {
42
+ fillSeed({
43
+ builder,
44
+ type: 'updating',
45
+ model: this.schema.model,
46
+ entity,
47
+ columnName: oldColumn.columnName,
48
+ nullable: newColumn.nullable,
49
+ columnType,
50
+ copyValue: this.data.copyValue,
51
+ fillValue: this.data.fillValue,
52
+ })
53
+ }
54
+
38
55
  const seqAlter = []
39
56
  if (oldColumn.sequence && newColumn.sequence) {
40
57
  if (oldColumn.sequence.precedence !== newColumn.sequence.precedence) {
@@ -95,6 +112,8 @@ export interface UpdateColumnDefinitionModificationData {
95
112
  entityName: string
96
113
  fieldName: string
97
114
  definition: ColumnDefinitionAlter
115
+ fillValue?: JSONValue
116
+ copyValue?: string
98
117
  }
99
118
 
100
119
  export const updateColumnDefinitionModification = createModificationType({
@@ -0,0 +1,35 @@
1
+ import { wrapIdentifier } from '../../utils/dbHelpers'
2
+ import { ImplementationException } from '../../exceptions'
3
+ import { JSONValue, Model } from '@contember/schema'
4
+ import { escapeValue, MigrationBuilder } from '@contember/database-migrations'
5
+ import { getColumnName } from '@contember/schema-utils'
6
+
7
+ export const fillSeed = ({ builder, fillValue, copyValue, entity, columnName, nullable, model, columnType, type }: {
8
+ model: Model.Schema
9
+ entity: Model.Entity
10
+ columnName: string
11
+ columnType: string
12
+ nullable: boolean
13
+ builder: MigrationBuilder
14
+ fillValue?: JSONValue
15
+ copyValue?: string
16
+ type: 'creating' | 'updating'
17
+ }) => {
18
+ const where = type === 'updating' ? ` WHERE ${wrapIdentifier(columnName)} IS NULL` : ''
19
+ if (fillValue !== undefined) {
20
+ builder.sql(`UPDATE ${wrapIdentifier(entity.tableName)}
21
+ SET ${wrapIdentifier(columnName)} = ${escapeValue(fillValue)}${where}`)
22
+ } else if (copyValue !== undefined) {
23
+ const copyFrom = getColumnName(model, entity, copyValue)
24
+ builder.sql(`UPDATE ${wrapIdentifier(entity.tableName)}
25
+ SET ${wrapIdentifier(columnName)} = ${wrapIdentifier(copyFrom)}::${columnType}${where}`)
26
+ } else {
27
+ throw new ImplementationException()
28
+ }
29
+
30
+ if (!nullable) {
31
+ builder.alterColumn(entity.tableName, columnName, {
32
+ notNull: true,
33
+ })
34
+ }
35
+ }
@@ -32,7 +32,6 @@ testMigrations('create a column with default value', {
32
32
  ],
33
33
  sql: SQL`ALTER TABLE "author" ADD "name" text;
34
34
  UPDATE "author" SET "name" = $pga$unnamed author$pga$;
35
- SET CONSTRAINTS ALL IMMEDIATE; SET CONSTRAINTS ALL DEFERRED;
36
35
  ALTER TABLE "author" ALTER "name" SET NOT NULL;`,
37
36
  })
38
37
 
@@ -65,6 +64,5 @@ testMigrations('create a column with copy value', {
65
64
  noDiff: true,
66
65
  sql: SQL`ALTER TABLE "author" ADD "name" text;
67
66
  UPDATE "author" SET "name" = "email"::text;
68
- SET CONSTRAINTS ALL IMMEDIATE; SET CONSTRAINTS ALL DEFERRED;
69
67
  ALTER TABLE "author" ALTER "name" SET NOT NULL;`,
70
68
  })
@@ -168,3 +168,35 @@ ALTER TABLE "author"
168
168
  CREATE VIEW "author_meta_x" AS SELECT * FROM author;
169
169
  CREATE VIEW "author_meta_y" AS SELECT * FROM author_meta_x;`,
170
170
  })
171
+
172
+
173
+ namespace NotNullOrig {
174
+ export class Author {
175
+ name = def.stringColumn()
176
+ }
177
+ }
178
+ namespace NotNullUpdated {
179
+ export class Author {
180
+ name = def.stringColumn().notNull()
181
+ }
182
+ }
183
+ testMigrations('set not null and fill', {
184
+ originalSchema: createSchema(NotNullOrig).model,
185
+ updatedSchema: createSchema(NotNullUpdated).model,
186
+ noDiff: true,
187
+ diff: [
188
+ updateColumnDefinitionModification.createModification({
189
+ entityName: 'Author',
190
+ fieldName: 'name',
191
+ definition: {
192
+ type: Model.ColumnType.String,
193
+ columnType: 'text',
194
+ nullable: false,
195
+ },
196
+ fillValue: 'unnamed',
197
+ }),
198
+ ],
199
+ sql: SQL`
200
+ UPDATE "author" SET "name" = $pga$unnamed$pga$ WHERE "name" IS NULL;
201
+ ALTER TABLE "author" ALTER "name" SET NOT NULL;`,
202
+ })