@contember/schema-migrations 1.2.1 → 1.3.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.
Files changed (93) hide show
  1. package/dist/src/MigrationCreator.js +2 -2
  2. package/dist/src/MigrationCreator.js.map +1 -1
  3. package/dist/src/MigrationFilesManager.js +2 -2
  4. package/dist/src/MigrationFilesManager.js.map +1 -1
  5. package/dist/src/MigrationsResolver.js +3 -3
  6. package/dist/src/MigrationsResolver.js.map +1 -1
  7. package/dist/src/SchemaDiffer.d.ts.map +1 -1
  8. package/dist/src/SchemaDiffer.js +1 -0
  9. package/dist/src/SchemaDiffer.js.map +1 -1
  10. package/dist/src/index.d.ts +1 -1
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +3 -1
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/modifications/ModificationHandlerFactory.d.ts.map +1 -1
  15. package/dist/src/modifications/ModificationHandlerFactory.js +2 -0
  16. package/dist/src/modifications/ModificationHandlerFactory.js.map +1 -1
  17. package/dist/src/modifications/ModificationVersions.d.ts +2 -1
  18. package/dist/src/modifications/ModificationVersions.d.ts.map +1 -1
  19. package/dist/src/modifications/ModificationVersions.js +3 -2
  20. package/dist/src/modifications/ModificationVersions.js.map +1 -1
  21. package/dist/src/modifications/entities/UpdateEntityNameModification.d.ts.map +1 -1
  22. package/dist/src/modifications/entities/UpdateEntityNameModification.js +15 -0
  23. package/dist/src/modifications/entities/UpdateEntityNameModification.js.map +1 -1
  24. package/dist/src/modifications/entities/UpdateEntityOrderByModification.d.ts +23 -0
  25. package/dist/src/modifications/entities/UpdateEntityOrderByModification.d.ts.map +1 -0
  26. package/dist/src/modifications/entities/UpdateEntityOrderByModification.js +63 -0
  27. package/dist/src/modifications/entities/UpdateEntityOrderByModification.js.map +1 -0
  28. package/dist/src/modifications/entities/index.d.ts +1 -0
  29. package/dist/src/modifications/entities/index.d.ts.map +1 -1
  30. package/dist/src/modifications/entities/index.js +1 -0
  31. package/dist/src/modifications/entities/index.js.map +1 -1
  32. package/dist/src/modifications/fields/UpdateFieldNameModification.d.ts.map +1 -1
  33. package/dist/src/modifications/fields/UpdateFieldNameModification.js +15 -0
  34. package/dist/src/modifications/fields/UpdateFieldNameModification.js.map +1 -1
  35. package/dist/src/modifications/relations/CreateRelationModification.d.ts.map +1 -1
  36. package/dist/src/modifications/relations/CreateRelationModification.js +2 -10
  37. package/dist/src/modifications/relations/CreateRelationModification.js.map +1 -1
  38. package/dist/src/modifications/relations/UpdateRelationOnDeleteModification.d.ts.map +1 -1
  39. package/dist/src/modifications/relations/UpdateRelationOnDeleteModification.js +20 -1
  40. package/dist/src/modifications/relations/UpdateRelationOnDeleteModification.js.map +1 -1
  41. package/dist/src/modifications/relations/helpers.d.ts +10 -0
  42. package/dist/src/modifications/relations/helpers.d.ts.map +1 -0
  43. package/dist/src/modifications/relations/helpers.js +26 -0
  44. package/dist/src/modifications/relations/helpers.js.map +1 -0
  45. package/dist/src/tsconfig.tsbuildinfo +1 -1
  46. package/dist/tests/cases/integration/createManyHasOne.test.js +1 -1
  47. package/dist/tests/cases/integration/createRelationInverseSide.test.js +1 -1
  48. package/dist/tests/cases/integration/createRelationInverseSide.test.js.map +1 -1
  49. package/dist/tests/cases/integration/takenIndexName.test.js +2 -2
  50. package/dist/tests/cases/integration/updateEntityName.test.js +20 -0
  51. package/dist/tests/cases/integration/updateEntityName.test.js.map +1 -1
  52. package/dist/tests/cases/integration/updateEntityOrderBy.test.d.ts +2 -0
  53. package/dist/tests/cases/integration/updateEntityOrderBy.test.d.ts.map +1 -0
  54. package/dist/tests/cases/integration/updateEntityOrderBy.test.js +57 -0
  55. package/dist/tests/cases/integration/updateEntityOrderBy.test.js.map +1 -0
  56. package/dist/tests/cases/integration/updateFieldName.test.js +21 -0
  57. package/dist/tests/cases/integration/updateFieldName.test.js.map +1 -1
  58. package/dist/tests/cases/integration/updateRelationOnDelete.test.js +2 -1
  59. package/dist/tests/cases/integration/updateRelationOnDelete.test.js.map +1 -1
  60. package/dist/tests/src/tests.d.ts.map +1 -1
  61. package/dist/tests/src/tests.js +4 -6
  62. package/dist/tests/src/tests.js.map +1 -1
  63. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  64. package/package.json +7 -6
  65. package/src/MigrationCreator.ts +1 -1
  66. package/src/MigrationFilesManager.ts +1 -1
  67. package/src/MigrationsResolver.ts +1 -1
  68. package/src/SchemaDiffer.ts +2 -0
  69. package/src/index.ts +1 -1
  70. package/src/modifications/ModificationHandlerFactory.ts +2 -0
  71. package/src/modifications/ModificationVersions.ts +2 -1
  72. package/src/modifications/entities/UpdateEntityNameModification.ts +23 -2
  73. package/src/modifications/entities/UpdateEntityOrderByModification.ts +68 -0
  74. package/src/modifications/entities/index.ts +1 -0
  75. package/src/modifications/fields/UpdateFieldNameModification.ts +22 -1
  76. package/src/modifications/relations/CreateRelationModification.ts +2 -15
  77. package/src/modifications/relations/UpdateRelationOnDeleteModification.ts +20 -1
  78. package/src/modifications/relations/helpers.ts +34 -0
  79. package/src/tsconfig.json +5 -12
  80. package/tests/cases/integration/createManyHasOne.test.ts +1 -1
  81. package/tests/cases/integration/createRelationInverseSide.test.ts +1 -1
  82. package/tests/cases/integration/takenIndexName.test.ts +2 -2
  83. package/tests/cases/integration/updateEntityName.test.ts +21 -0
  84. package/tests/cases/integration/updateEntityOrderBy.test.ts +43 -0
  85. package/tests/cases/integration/updateFieldName.test.ts +22 -0
  86. package/tests/cases/integration/updateRelationOnDelete.test.ts +2 -1
  87. package/tests/src/tests.ts +5 -7
  88. package/tests/tsconfig.json +2 -6
  89. package/dist/src/MigrationVersionHelper.d.ts +0 -9
  90. package/dist/src/MigrationVersionHelper.d.ts.map +0 -1
  91. package/dist/src/MigrationVersionHelper.js +0 -45
  92. package/dist/src/MigrationVersionHelper.js.map +0 -1
  93. package/src/MigrationVersionHelper.ts +0 -46
@@ -31,6 +31,7 @@ import { patchValidationSchemaModification, updateValidationSchemaModification }
31
31
  import { createIndexModification, removeIndexModification } from './indexes'
32
32
  import { SchemaWithMeta } from './utils/schemaMeta'
33
33
  import { updateSettingsModification } from './settings'
34
+ import { updateEntityOrderByModification } from './entities/UpdateEntityOrderByModification'
34
35
 
35
36
 
36
37
  class ModificationHandlerFactory {
@@ -83,6 +84,7 @@ namespace ModificationHandlerFactory {
83
84
  toggleEventLogModification,
84
85
  toggleJunctionEventLogModification,
85
86
  convertOneHasManyToManyHasManyRelationModification,
87
+ updateEntityOrderByModification,
86
88
  ]
87
89
 
88
90
  export const defaultFactoryMap: HandlerMap<any> = Object.fromEntries(handlers.map(it => [it.id, it]))
@@ -1,7 +1,8 @@
1
1
  export const VERSION_INITIAL = 1
2
- export const VERSION_LATEST = 3
2
+ export const VERSION_LATEST = 4
3
3
 
4
4
  export const VERSION_ACL_PATCH = 2
5
5
  export const VERSION_UPDATE_CONSTRAINT_NAME = 2
6
6
  export const VERSION_REMOVE_RELATION_INVERSE_SIDE = 3
7
7
  export const VERSION_REMOVE_REFERENCING_RELATIONS = 3
8
+ export const VERSION_UPDATE_CONSTRAINT_NAME_ONE_HAS_ONE = 4
@@ -13,8 +13,12 @@ import {
13
13
  } from '../utils/schemaUpdateUtils'
14
14
  import { createModificationType, ModificationHandler, ModificationHandlerOptions } from '../ModificationHandler'
15
15
  import { isIt } from '../../utils/isIt'
16
- import { VERSION_ACL_PATCH, VERSION_UPDATE_CONSTRAINT_NAME } from '../ModificationVersions'
17
- import { NamingHelper } from '@contember/schema-utils'
16
+ import {
17
+ VERSION_ACL_PATCH,
18
+ VERSION_UPDATE_CONSTRAINT_NAME,
19
+ VERSION_UPDATE_CONSTRAINT_NAME_ONE_HAS_ONE,
20
+ } from '../ModificationVersions'
21
+ import { acceptEveryFieldVisitor, NamingHelper } from '@contember/schema-utils'
18
22
  import { NoopModification } from '../NoopModification'
19
23
  import { renameConstraintSchemaUpdater, renameConstraintsSqlBuilder } from '../utils/renameConstraintsHelper'
20
24
  import { changeValue } from '../utils/valueUtils'
@@ -43,6 +47,23 @@ export class UpdateEntityNameModificationHandler implements ModificationHandler<
43
47
  if (!entity.view && this.options.formatVersion >= VERSION_UPDATE_CONSTRAINT_NAME) {
44
48
  renameConstraintsSqlBuilder(builder, entity, this.getNewConstraintName.bind(this))
45
49
  }
50
+
51
+ if (this.options.formatVersion >= VERSION_UPDATE_CONSTRAINT_NAME_ONE_HAS_ONE) {
52
+ acceptEveryFieldVisitor(this.schema.model, this.data.entityName, {
53
+ visitColumn: () => {},
54
+ visitManyHasManyOwning: () => {},
55
+ visitManyHasManyInverse: () => {},
56
+ visitOneHasOneInverse: () => {},
57
+ visitManyHasOne: () => {},
58
+ visitOneHasMany: () => {},
59
+ visitOneHasOneOwning: ({ relation }) => {
60
+ const uniqueConstraintName = NamingHelper.createUniqueConstraintName(entity.name, [relation.name])
61
+ const newUniqueConstraintName = NamingHelper.createUniqueConstraintName(this.data.newEntityName, [relation.name])
62
+ builder.renameConstraint(entity.tableName, uniqueConstraintName, newUniqueConstraintName)
63
+ },
64
+ })
65
+ }
66
+
46
67
  this.subModification.createSql(builder)
47
68
  }
48
69
 
@@ -0,0 +1,68 @@
1
+ import { MigrationBuilder } from '@contember/database-migrations'
2
+ import { Model, Schema } from '@contember/schema'
3
+ import { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'
4
+ import { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'
5
+ import deepEqual from 'fast-deep-equal'
6
+
7
+ export class UpdateEntityOrderByModificationHandler implements ModificationHandler<UpdateEntityOrderByModificationData> {
8
+
9
+ constructor(private readonly data: UpdateEntityOrderByModificationData, private readonly schema: Schema) { }
10
+
11
+ public createSql(builder: MigrationBuilder): void { }
12
+
13
+ public getSchemaUpdater(): SchemaUpdater {
14
+ const { entityName, orderBy } = this.data
15
+ return updateModel(
16
+ updateEntity(entityName, ({ entity }) => {
17
+ if (orderBy) {
18
+ return {
19
+ ...entity,
20
+ orderBy,
21
+ }
22
+ }
23
+ const { orderBy: _, ...rest } = entity
24
+ return rest
25
+ }),
26
+ )
27
+ }
28
+
29
+ describe() {
30
+ return { message: `Update order-by of entity ${this.data.entityName}` }
31
+ }
32
+ }
33
+
34
+ export interface UpdateEntityOrderByModificationData {
35
+ entityName: string
36
+ orderBy?: readonly Model.OrderBy[]
37
+ }
38
+
39
+ export const updateEntityOrderByModification = createModificationType({
40
+ id: 'updateEntityOrderBy',
41
+ handler: UpdateEntityOrderByModificationHandler,
42
+ })
43
+
44
+ export class UpdateEntityOrderByDiffer implements Differ {
45
+ createDiff(originalSchema: Schema, updatedSchema: Schema) {
46
+ return Object.values(updatedSchema.model.entities)
47
+ .flatMap(updatedEntity => {
48
+ const origEntity = originalSchema.model.entities[updatedEntity.name]
49
+ if (!origEntity) {
50
+ return []
51
+ }
52
+
53
+ if (!deepEqual(updatedEntity.orderBy ?? [], origEntity.orderBy ?? [])) {
54
+ if (updatedEntity.orderBy) {
55
+ return [updateEntityOrderByModification.createModification({
56
+ entityName: updatedEntity.name,
57
+ orderBy: updatedEntity.orderBy,
58
+ })]
59
+ }
60
+ return [updateEntityOrderByModification.createModification({
61
+ entityName: updatedEntity.name,
62
+ })]
63
+ }
64
+ return []
65
+ })
66
+
67
+ }
68
+ }
@@ -4,3 +4,4 @@ export * from './RemoveEntityModification'
4
4
  export * from './ToggleEventLogModification'
5
5
  export * from './UpdateEntityNameModification'
6
6
  export * from './UpdateEntityTableNameModification'
7
+ export * from './UpdateEntityOrderByModification'
@@ -15,7 +15,11 @@ import {
15
15
  } from '../utils/schemaUpdateUtils'
16
16
  import { createModificationType, ModificationHandler, ModificationHandlerOptions } from '../ModificationHandler'
17
17
  import { acceptFieldVisitor, NamingHelper, PredicateDefinitionProcessor } from '@contember/schema-utils'
18
- import { VERSION_ACL_PATCH, VERSION_UPDATE_CONSTRAINT_NAME } from '../ModificationVersions'
18
+ import {
19
+ VERSION_ACL_PATCH,
20
+ VERSION_UPDATE_CONSTRAINT_NAME,
21
+ VERSION_UPDATE_CONSTRAINT_NAME_ONE_HAS_ONE,
22
+ } from '../ModificationVersions'
19
23
  import { renameConstraintSchemaUpdater, renameConstraintsSqlBuilder } from '../utils/renameConstraintsHelper'
20
24
  import { changeValue } from '../utils/valueUtils'
21
25
  import { updateColumnNameModification } from '../columns'
@@ -47,6 +51,23 @@ export class UpdateFieldNameModificationHandler implements ModificationHandler<U
47
51
  if (this.options.formatVersion >= VERSION_UPDATE_CONSTRAINT_NAME) {
48
52
  renameConstraintsSqlBuilder(builder, entity, this.getNewConstraintName.bind(this))
49
53
  }
54
+
55
+ if (this.options.formatVersion >= VERSION_UPDATE_CONSTRAINT_NAME_ONE_HAS_ONE) {
56
+ acceptFieldVisitor(this.schema.model, this.data.entityName, this.data.fieldName, {
57
+ visitColumn: () => {},
58
+ visitManyHasManyOwning: () => {},
59
+ visitManyHasManyInverse: () => {},
60
+ visitOneHasOneInverse: () => {},
61
+ visitManyHasOne: () => {},
62
+ visitOneHasMany: () => {},
63
+ visitOneHasOneOwning: ({ relation }) => {
64
+ const uniqueConstraintName = NamingHelper.createUniqueConstraintName(entity.name, [relation.name])
65
+ const newUniqueConstraintName = NamingHelper.createUniqueConstraintName(entity.name, [this.data.newFieldName])
66
+ builder.renameConstraint(entity.tableName, uniqueConstraintName, newUniqueConstraintName)
67
+ },
68
+ })
69
+ }
70
+
50
71
  this.renameColumnSubModification.createSql(builder)
51
72
  }
52
73
 
@@ -27,6 +27,7 @@ import { getPrimaryColumnType } from '../utils/getPrimaryColumnType'
27
27
  import { createJunctionTableSql } from '../utils/createJunctionTable'
28
28
  import { normalizeManyHasManyRelation, PartialManyHasManyRelation } from './normalization'
29
29
  import { resolveIndexName, SchemaWithMeta } from '../utils/schemaMeta'
30
+ import { addForeignKeyConstraint } from './helpers'
30
31
 
31
32
 
32
33
  export class CreateRelationModificationHandler implements ModificationHandler<CreateRelationModificationData> {
@@ -50,21 +51,7 @@ export class CreateRelationModificationHandler implements ModificationHandler<Cr
50
51
  notNull: !relation.nullable,
51
52
  },
52
53
  })
53
- const fkName = NamingHelper.createForeignKeyName(
54
- entity.tableName,
55
- relation.joiningColumn.columnName,
56
- targetEntity.tableName,
57
- targetEntity.primaryColumn,
58
- )
59
- builder.addConstraint(entity.tableName, fkName, {
60
- foreignKeys: {
61
- columns: relation.joiningColumn.columnName,
62
- references: `"${targetEntity.tableName}"("${targetEntity.primaryColumn}")`,
63
- onDelete: 'NO ACTION',
64
- },
65
- deferrable: true,
66
- deferred: false,
67
- })
54
+ addForeignKeyConstraint({ builder, entity, targetEntity, relation })
68
55
  }
69
56
  acceptRelationTypeVisitor(this.schema.model, entity, this.getNormalizedOwningSide(), {
70
57
  visitManyHasOne: ({ relation }) => {
@@ -4,11 +4,30 @@ import { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/
4
4
  import { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'
5
5
  import { isIt } from '../../utils/isIt'
6
6
  import { updateRelations } from '../utils/diffUtils'
7
+ import { acceptRelationTypeVisitor } from '@contember/schema-utils'
8
+ import { addForeignKeyConstraint } from './helpers'
7
9
 
8
10
  export class UpdateRelationOnDeleteModificationHandler implements ModificationHandler<UpdateRelationOnDeleteModificationData> {
9
11
  constructor(private readonly data: UpdateRelationOnDeleteModificationData, private readonly schema: Schema) {}
10
12
 
11
- public createSql(builder: MigrationBuilder): void {}
13
+ public createSql(builder: MigrationBuilder): void {
14
+ const entity = this.schema.model.entities[this.data.entityName]
15
+ if (entity.view) {
16
+ return
17
+ }
18
+ acceptRelationTypeVisitor(this.schema.model, entity, this.data.fieldName, {
19
+ visitManyHasOne: ({ entity, relation, targetEntity }) => {
20
+ addForeignKeyConstraint({ builder, entity, targetEntity, relation, recreate: true })
21
+ },
22
+ visitOneHasOneOwning: ({ entity, relation, targetEntity }) => {
23
+ addForeignKeyConstraint({ builder, entity, targetEntity, relation, recreate: true })
24
+ },
25
+ visitOneHasMany: () => {},
26
+ visitOneHasOneInverse: () => {},
27
+ visitManyHasManyOwning: () => {},
28
+ visitManyHasManyInverse: () => {},
29
+ })
30
+ }
12
31
 
13
32
  public getSchemaUpdater(): SchemaUpdater {
14
33
  const { entityName, fieldName, onDelete } = this.data
@@ -0,0 +1,34 @@
1
+ import { MigrationBuilder } from '@contember/database-migrations'
2
+ import { NamingHelper } from '@contember/schema-utils'
3
+ import { Model } from '@contember/schema'
4
+
5
+ export const addForeignKeyConstraint = ({ builder, entity, relation, targetEntity, recreate = false }: {
6
+ recreate?: boolean
7
+ builder: MigrationBuilder
8
+ entity: Model.Entity
9
+ targetEntity: Model.Entity
10
+ relation: Model.OneHasOneOwningRelation | Model.ManyHasOneRelation
11
+ }) => {
12
+ const fkName = NamingHelper.createForeignKeyName(
13
+ entity.tableName,
14
+ relation.joiningColumn.columnName,
15
+ targetEntity.tableName,
16
+ targetEntity.primaryColumn,
17
+ )
18
+ if (recreate) {
19
+ builder.dropConstraint(entity.tableName, fkName)
20
+ }
21
+ builder.addConstraint(entity.tableName, fkName, {
22
+ foreignKeys: {
23
+ columns: relation.joiningColumn.columnName,
24
+ references: `"${targetEntity.tableName}"("${targetEntity.primaryColumn}")`,
25
+ onDelete: ({
26
+ [Model.OnDelete.setNull]: 'SET NULL',
27
+ [Model.OnDelete.cascade]: 'CASCADE',
28
+ [Model.OnDelete.restrict]: 'NO ACTION',
29
+ } as const)[relation.joiningColumn.onDelete],
30
+ },
31
+ deferrable: true,
32
+ deferred: false,
33
+ })
34
+ }
package/src/tsconfig.json CHANGED
@@ -6,17 +6,10 @@
6
6
  "downlevelIteration": true
7
7
  },
8
8
  "references": [
9
- {
10
- "path": "../../database/src"
11
- },
12
- {
13
- "path": "../../database-migrations/src"
14
- },
15
- {
16
- "path": "../../schema/src"
17
- },
18
- {
19
- "path": "../../schema-utils/src"
20
- }
9
+ { "path": "../../database/src" },
10
+ { "path": "../../database-migrations/src" },
11
+ { "path": "../../engine-common/src" },
12
+ { "path": "../../schema/src" },
13
+ { "path": "../../schema-utils/src" }
21
14
  ]
22
15
  }
@@ -84,6 +84,6 @@ testMigrations('create many has one relation (post with author)', {
84
84
  ALTER TABLE "post"
85
85
  ADD "author_id" uuid;
86
86
  ALTER TABLE "post"
87
- ADD CONSTRAINT "fk_post_author_id_87ef9a" FOREIGN KEY ("author_id") REFERENCES "author"("id") ON DELETE NO ACTION DEFERRABLE INITIALLY IMMEDIATE;
87
+ ADD CONSTRAINT "fk_post_author_id_87ef9a" FOREIGN KEY ("author_id") REFERENCES "author"("id") ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE;
88
88
  CREATE INDEX "post_author_id_index" ON "post" ("author_id");`,
89
89
  })
@@ -56,5 +56,5 @@ testMigrations('create inverse side relation together with changing onDelete beh
56
56
  },
57
57
  },
58
58
  ],
59
- sql: SQL``,
59
+ sql: SQL`ALTER TABLE "post_locale" DROP CONSTRAINT "fk_post_locale_post_id_f3d2e5"; ALTER TABLE "post_locale" ADD CONSTRAINT "fk_post_locale_post_id_f3d2e5" FOREIGN KEY ("post_id") REFERENCES "post"("id") ON DELETE NO ACTION DEFERRABLE INITIALLY IMMEDIATE;`,
60
60
  })
@@ -138,7 +138,7 @@ CREATE CONSTRAINT TRIGGER "log_event_trx"
138
138
  ALTER TABLE "post"
139
139
  ADD "author_id" uuid;
140
140
  ALTER TABLE "post"
141
- ADD CONSTRAINT "fk_post_author_id_87ef9a" FOREIGN KEY ("author_id") REFERENCES "author"("id") ON DELETE NO ACTION DEFERRABLE INITIALLY IMMEDIATE;
141
+ ADD CONSTRAINT "fk_post_author_id_87ef9a" FOREIGN KEY ("author_id") REFERENCES "author"("id") ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE;
142
142
  CREATE INDEX "post_author_id_index" ON "post" ("author_id");
143
143
  ALTER TABLE "post" RENAME TO "article";
144
144
  CREATE TABLE "post" (
@@ -156,7 +156,7 @@ CREATE CONSTRAINT TRIGGER "log_event_trx"
156
156
  ALTER TABLE "post"
157
157
  ADD "author_id" uuid;
158
158
  ALTER TABLE "post"
159
- ADD CONSTRAINT "fk_post_author_id_87ef9a" FOREIGN KEY ("author_id") REFERENCES "author"("id") ON DELETE NO ACTION DEFERRABLE INITIALLY IMMEDIATE;
159
+ ADD CONSTRAINT "fk_post_author_id_87ef9a" FOREIGN KEY ("author_id") REFERENCES "author"("id") ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE;
160
160
  CREATE INDEX "post_author_id_index1" ON "post" ("author_id");`)
161
161
  })
162
162
 
@@ -62,6 +62,27 @@ testMigrations('rename entity with a constraint', {
62
62
  noDiff: true,
63
63
  })
64
64
 
65
+ testMigrations('rename entity with one-has-one (constraint)', {
66
+ originalSchema: new SchemaBuilder()
67
+ .entity('Author', e => e.oneHasOne('content', r => r.target('Content')))
68
+ .entity('Content', e => e.column('foo'))
69
+ .buildSchema(),
70
+ updatedSchema: new SchemaBuilder()
71
+ .entity('User', e => e.tableName('author').oneHasOne('content', r => r.target('Content')))
72
+ .entity('Content', e => e.column('foo'))
73
+ .buildSchema(),
74
+ diff: [
75
+ {
76
+ modification: 'updateEntityName',
77
+ entityName: 'Author',
78
+ newEntityName: 'User',
79
+ },
80
+ ],
81
+ sql: SQL`ALTER TABLE "author"
82
+ RENAME CONSTRAINT "unique_Author_content_b64856" TO "unique_User_content_43c77f";`,
83
+ noDiff: true,
84
+ })
85
+
65
86
  testMigrations('rename table with acl', {
66
87
  originalSchema: new SchemaBuilder()
67
88
  .entity('Site', entity => entity.column('name', c => c.type(Model.ColumnType.String)))
@@ -0,0 +1,43 @@
1
+ import { testMigrations } from '../../src/tests'
2
+ import { SchemaBuilder, SchemaDefinition as def } from '@contember/schema-definition'
3
+ import { Model } from '@contember/schema'
4
+ import { SQL } from '../../src/tags'
5
+
6
+
7
+ namespace SchemaWithoutOrderBy {
8
+ export class Article {
9
+ title = def.stringColumn()
10
+ }
11
+ }
12
+
13
+ namespace SchemaWithOrderBy {
14
+ @def.OrderBy('title', Model.OrderDirection.asc)
15
+ export class Article {
16
+ title = def.stringColumn()
17
+ }
18
+ }
19
+
20
+ testMigrations('update entity add order by', {
21
+ originalSchema: def.createModel(SchemaWithoutOrderBy),
22
+ updatedSchema: def.createModel(SchemaWithOrderBy),
23
+ diff: [
24
+ {
25
+ modification: 'updateEntityOrderBy',
26
+ entityName: 'Article',
27
+ orderBy: [{ path: ['title'], direction: 'asc' }],
28
+ },
29
+ ],
30
+ sql: SQL``,
31
+ })
32
+
33
+ testMigrations('update entity remove order by', {
34
+ originalSchema: def.createModel(SchemaWithOrderBy),
35
+ updatedSchema: def.createModel(SchemaWithoutOrderBy),
36
+ diff: [
37
+ {
38
+ modification: 'updateEntityOrderBy',
39
+ entityName: 'Article',
40
+ },
41
+ ],
42
+ sql: SQL``,
43
+ })
@@ -63,6 +63,28 @@ testMigrations('rename a field with a constraint', {
63
63
  noDiff: true,
64
64
  })
65
65
 
66
+ testMigrations('rename a field with one-has-one', {
67
+ originalSchema: new SchemaBuilder()
68
+ .entity('Author', e => e.oneHasOne('content', r => r.target('Content')))
69
+ .entity('Content', e => e.column('foo'))
70
+ .buildSchema(),
71
+ updatedSchema: new SchemaBuilder()
72
+ .entity('Author', e => e.oneHasOne('description', r => r.target('Content').joiningColumn('content_id')))
73
+ .entity('Content', e => e.column('foo'))
74
+ .buildSchema(),
75
+ diff: [
76
+ {
77
+ modification: 'updateFieldName',
78
+ entityName: 'Author',
79
+ fieldName: 'content',
80
+ newFieldName: 'description',
81
+ },
82
+ ],
83
+ sql: SQL`ALTER TABLE "author"
84
+ RENAME CONSTRAINT "unique_Author_content_b64856" TO "unique_Author_description_00f1ef";`,
85
+ noDiff: true,
86
+ })
87
+
66
88
  testMigrations('rename a relation', {
67
89
  originalSchema: new SchemaBuilder()
68
90
  .entity('Post', e => e.column('title').manyHasOne('user', r => r.target('Author').inversedBy('posts')))
@@ -26,5 +26,6 @@ testMigrations('update relation ondelete to cascade', {
26
26
  onDelete: Model.OnDelete.cascade,
27
27
  },
28
28
  ],
29
- sql: SQL``,
29
+ sql: SQL`ALTER TABLE "post" DROP CONSTRAINT "fk_post_category_id_820029";
30
+ ALTER TABLE "post" ADD CONSTRAINT "fk_post_category_id_820029" FOREIGN KEY ("category_id") REFERENCES "category"("id") ON DELETE NO ACTION DEFERRABLE INITIALLY IMMEDIATE;`,
30
31
  })
@@ -29,8 +29,8 @@ export function testDiffSchemas(
29
29
  updatedAcl: Acl.Schema = emptyAcl,
30
30
  ) {
31
31
  const actualDiff = schemaDiffer.diffSchemas(
32
- { ...emptySchema, model: originalModel, acl: originalAcl, validation: {} },
33
- { ...emptySchema, model: updatedModel, acl: updatedAcl, validation: {} },
32
+ { ...emptySchema, model: originalModel, acl: originalAcl },
33
+ { ...emptySchema, model: updatedModel, acl: updatedAcl },
34
34
  { skipRecreateValidation: true },
35
35
  )
36
36
  try {
@@ -41,7 +41,7 @@ export function testDiffSchemas(
41
41
  throw e
42
42
  }
43
43
  const { meta, ...schema } = schemaMigrator.applyModifications(
44
- { ...emptySchema, model: originalModel, acl: originalAcl, validation: {} },
44
+ { ...emptySchema, model: originalModel, acl: originalAcl },
45
45
  actualDiff,
46
46
  VERSION_LATEST,
47
47
  ) as SchemaWithMeta
@@ -49,7 +49,6 @@ export function testDiffSchemas(
49
49
  ...emptySchema,
50
50
  model: updatedModel,
51
51
  acl: updatedAcl,
52
- validation: {},
53
52
  })
54
53
  }
55
54
 
@@ -61,7 +60,7 @@ export function testApplyDiff(
61
60
  expectedAcl: Acl.Schema = emptyAcl,
62
61
  ) {
63
62
  const { meta, ...actualSchema } = schemaMigrator.applyModifications(
64
- { ...emptySchema, model: originalModel, acl: originalAcl, validation: {} },
63
+ { ...emptySchema, model: originalModel, acl: originalAcl },
65
64
  diff,
66
65
  VERSION_LATEST,
67
66
  ) as SchemaWithMeta
@@ -70,12 +69,11 @@ export function testApplyDiff(
70
69
  ...emptySchema,
71
70
  model: expectedModel,
72
71
  acl: expectedAcl,
73
- validation: {},
74
72
  })
75
73
  }
76
74
 
77
75
  export function testGenerateSql(originalSchema: Model.Schema, diff: Migration.Modification[], expectedSql: string) {
78
- let schema = { ...emptySchema, model: originalSchema, acl: emptyAcl, validation: {} }
76
+ let schema = { ...emptySchema, model: originalSchema, acl: emptyAcl }
79
77
  const builder = createMigrationBuilder()
80
78
  for (let { modification, ...data } of diff) {
81
79
  const modificationHandler = modificationFactory.create(modification, data, schema, { formatVersion: VERSION_LATEST, systemSchema: 'system' })
@@ -5,11 +5,7 @@
5
5
  "esModuleInterop": true
6
6
  },
7
7
  "references": [
8
- {
9
- "path": "../src"
10
- },
11
- {
12
- "path": "../../schema-definition/src"
13
- }
8
+ { "path": "../src" },
9
+ { "path": "../../schema-definition/src" }
14
10
  ]
15
11
  }
@@ -1,9 +0,0 @@
1
- export declare class MigrationVersionHelper {
2
- static prefixLength: number;
3
- static extractVersion(filename: string): string;
4
- static createVersion(name: string, increment?: number): [string, string];
5
- static extractName(filename: string): string;
6
- private static createTimePrefix;
7
- private static normalizeMigrationLabel;
8
- }
9
- //# sourceMappingURL=MigrationVersionHelper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MigrationVersionHelper.d.ts","sourceRoot":"","sources":["../../src/MigrationVersionHelper.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAsB;IAClC,OAAc,YAAY,SAA6B;WAEzC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;WAIxC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;WAMpE,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAInD,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAyB/B,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAGtC"}
@@ -1,45 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MigrationVersionHelper = void 0;
4
- class MigrationVersionHelper {
5
- static extractVersion(filename) {
6
- return filename.substring(0, this.prefixLength);
7
- }
8
- static createVersion(name, increment = 0) {
9
- const normalizedName = MigrationVersionHelper.normalizeMigrationLabel(name);
10
- const version = MigrationVersionHelper.createTimePrefix(increment);
11
- return [version, `${version}-${normalizedName}`];
12
- }
13
- static extractName(filename) {
14
- return filename.substring(0, filename.lastIndexOf('.'));
15
- }
16
- static createTimePrefix(increment) {
17
- const now = new Date();
18
- now.setSeconds(now.getSeconds() + increment);
19
- const year = now.getFullYear();
20
- const month = (now.getMonth() + 1).toString().padStart(2, '0');
21
- const day = now //
22
- .getDate()
23
- .toString()
24
- .padStart(2, '0');
25
- const hours = now //
26
- .getHours()
27
- .toString()
28
- .padStart(2, '0');
29
- const minutes = now //
30
- .getMinutes()
31
- .toString()
32
- .padStart(2, '0');
33
- const seconds = now //
34
- .getSeconds()
35
- .toString()
36
- .padStart(2, '0');
37
- return `${year}-${month}-${day}-${hours}${minutes}${seconds}`;
38
- }
39
- static normalizeMigrationLabel(name) {
40
- return name.toLowerCase().replace(/[^a-z0-9]+/g, '-');
41
- }
42
- }
43
- exports.MigrationVersionHelper = MigrationVersionHelper;
44
- MigrationVersionHelper.prefixLength = 'YYYY-MM-DD-HHIISS'.length;
45
- //# sourceMappingURL=MigrationVersionHelper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MigrationVersionHelper.js","sourceRoot":"","sources":["../../src/MigrationVersionHelper.ts"],"names":[],"mappings":";;;AAAA,MAAa,sBAAsB;IAG3B,MAAM,CAAC,cAAc,CAAC,QAAgB;QAC5C,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;IAChD,CAAC;IAEM,MAAM,CAAC,aAAa,CAAC,IAAY,EAAE,YAAoB,CAAC;QAC9D,MAAM,cAAc,GAAG,sBAAsB,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAA;QAC3E,MAAM,OAAO,GAAG,sBAAsB,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAA;QAClE,OAAO,CAAC,OAAO,EAAE,GAAG,OAAO,IAAI,cAAc,EAAE,CAAC,CAAA;IACjD,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,QAAgB;QACzC,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;IACxD,CAAC;IAEO,MAAM,CAAC,gBAAgB,CAAC,SAAiB;QAChD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;QACtB,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;QAC9B,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC9D,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE;aAChB,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAClB,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE;aAClB,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAClB,MAAM,OAAO,GAAG,GAAG,CAAC,EAAE;aACpB,UAAU,EAAE;aACZ,QAAQ,EAAE;aACV,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAClB,MAAM,OAAO,GAAG,GAAG,CAAC,EAAE;aACpB,UAAU,EAAE;aACZ,QAAQ,EAAE;aACV,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAElB,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE,CAAA;IAC9D,CAAC;IAEO,MAAM,CAAC,uBAAuB,CAAC,IAAY;QAClD,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAA;IACtD,CAAC;;AA5CF,wDA6CC;AA5Cc,mCAAY,GAAG,mBAAmB,CAAC,MAAM,CAAA"}
@@ -1,46 +0,0 @@
1
- export class MigrationVersionHelper {
2
- public static prefixLength = 'YYYY-MM-DD-HHIISS'.length
3
-
4
- public static extractVersion(filename: string): string {
5
- return filename.substring(0, this.prefixLength)
6
- }
7
-
8
- public static createVersion(name: string, increment: number = 0): [string, string] {
9
- const normalizedName = MigrationVersionHelper.normalizeMigrationLabel(name)
10
- const version = MigrationVersionHelper.createTimePrefix(increment)
11
- return [version, `${version}-${normalizedName}`]
12
- }
13
-
14
- public static extractName(filename: string): string {
15
- return filename.substring(0, filename.lastIndexOf('.'))
16
- }
17
-
18
- private static createTimePrefix(increment: number): string {
19
- const now = new Date()
20
- now.setSeconds(now.getSeconds() + increment)
21
- const year = now.getFullYear()
22
- const month = (now.getMonth() + 1).toString().padStart(2, '0')
23
- const day = now //
24
- .getDate()
25
- .toString()
26
- .padStart(2, '0')
27
- const hours = now //
28
- .getHours()
29
- .toString()
30
- .padStart(2, '0')
31
- const minutes = now //
32
- .getMinutes()
33
- .toString()
34
- .padStart(2, '0')
35
- const seconds = now //
36
- .getSeconds()
37
- .toString()
38
- .padStart(2, '0')
39
-
40
- return `${year}-${month}-${day}-${hours}${minutes}${seconds}`
41
- }
42
-
43
- private static normalizeMigrationLabel(name: string) {
44
- return name.toLowerCase().replace(/[^a-z0-9]+/g, '-')
45
- }
46
- }