@contember/schema-migrations 1.2.0-alpha.2 → 1.2.0-alpha.5

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 (67) hide show
  1. package/dist/src/SchemaDiffer.d.ts.map +1 -1
  2. package/dist/src/SchemaDiffer.js +3 -0
  3. package/dist/src/SchemaDiffer.js.map +1 -1
  4. package/dist/src/modifications/ModificationHandlerFactory.d.ts.map +1 -1
  5. package/dist/src/modifications/ModificationHandlerFactory.js +3 -0
  6. package/dist/src/modifications/ModificationHandlerFactory.js.map +1 -1
  7. package/dist/src/modifications/entities/CreateEntityModification.d.ts +2 -4
  8. package/dist/src/modifications/entities/CreateEntityModification.d.ts.map +1 -1
  9. package/dist/src/modifications/entities/CreateEntityModification.js +1 -0
  10. package/dist/src/modifications/entities/CreateEntityModification.js.map +1 -1
  11. package/dist/src/modifications/entities/CreateViewModification.d.ts +2 -4
  12. package/dist/src/modifications/entities/CreateViewModification.d.ts.map +1 -1
  13. package/dist/src/modifications/entities/CreateViewModification.js +1 -0
  14. package/dist/src/modifications/entities/CreateViewModification.js.map +1 -1
  15. package/dist/src/modifications/indexes/CreateIndexModification.d.ts +8 -0
  16. package/dist/src/modifications/indexes/CreateIndexModification.d.ts.map +1 -0
  17. package/dist/src/modifications/indexes/CreateIndexModification.js +72 -0
  18. package/dist/src/modifications/indexes/CreateIndexModification.js.map +1 -0
  19. package/dist/src/modifications/indexes/RemoveIndexModification.d.ts +7 -0
  20. package/dist/src/modifications/indexes/RemoveIndexModification.d.ts.map +1 -0
  21. package/dist/src/modifications/indexes/RemoveIndexModification.js +53 -0
  22. package/dist/src/modifications/indexes/RemoveIndexModification.js.map +1 -0
  23. package/dist/src/modifications/indexes/index.d.ts +3 -0
  24. package/dist/src/modifications/indexes/index.d.ts.map +1 -0
  25. package/dist/src/modifications/indexes/index.js +19 -0
  26. package/dist/src/modifications/indexes/index.js.map +1 -0
  27. package/dist/src/tsconfig.tsbuildinfo +1 -1
  28. package/dist/src/utils/PartialEntity.d.ts +5 -0
  29. package/dist/src/utils/PartialEntity.d.ts.map +1 -0
  30. package/dist/src/utils/PartialEntity.js +3 -0
  31. package/dist/src/utils/PartialEntity.js.map +1 -0
  32. package/dist/tests/cases/integration/createAndDropIndex.test.d.ts +2 -0
  33. package/dist/tests/cases/integration/createAndDropIndex.test.d.ts.map +1 -0
  34. package/dist/tests/cases/integration/createAndDropIndex.test.js +57 -0
  35. package/dist/tests/cases/integration/createAndDropIndex.test.js.map +1 -0
  36. package/dist/tests/cases/integration/createEntity.test.js +2 -0
  37. package/dist/tests/cases/integration/createEntity.test.js.map +1 -1
  38. package/dist/tests/cases/integration/createManyHasMany.test.js +1 -0
  39. package/dist/tests/cases/integration/createManyHasMany.test.js.map +1 -1
  40. package/dist/tests/cases/integration/createManyHasOne.test.js +1 -0
  41. package/dist/tests/cases/integration/createManyHasOne.test.js.map +1 -1
  42. package/dist/tests/cases/integration/createOneHasMany.test.js +1 -0
  43. package/dist/tests/cases/integration/createOneHasMany.test.js.map +1 -1
  44. package/dist/tests/cases/integration/createOneHasOne.test.js +2 -0
  45. package/dist/tests/cases/integration/createOneHasOne.test.js.map +1 -1
  46. package/dist/tests/cases/integration/createView.test.js +1 -0
  47. package/dist/tests/cases/integration/createView.test.js.map +1 -1
  48. package/dist/tests/cases/integration/updateView.test.js +9 -0
  49. package/dist/tests/cases/integration/updateView.test.js.map +1 -1
  50. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +7 -7
  52. package/src/SchemaDiffer.ts +3 -0
  53. package/src/modifications/ModificationHandlerFactory.ts +3 -0
  54. package/src/modifications/entities/CreateEntityModification.ts +3 -3
  55. package/src/modifications/entities/CreateViewModification.ts +3 -3
  56. package/src/modifications/indexes/CreateIndexModification.ts +82 -0
  57. package/src/modifications/indexes/RemoveIndexModification.ts +64 -0
  58. package/src/modifications/indexes/index.ts +2 -0
  59. package/src/utils/PartialEntity.ts +5 -0
  60. package/tests/cases/integration/createAndDropIndex.test.ts +44 -0
  61. package/tests/cases/integration/createEntity.test.ts +2 -0
  62. package/tests/cases/integration/createManyHasMany.test.ts +1 -0
  63. package/tests/cases/integration/createManyHasOne.test.ts +1 -0
  64. package/tests/cases/integration/createOneHasMany.test.ts +1 -0
  65. package/tests/cases/integration/createOneHasOne.test.ts +2 -0
  66. package/tests/cases/integration/createView.test.ts +1 -0
  67. package/tests/cases/integration/updateView.test.ts +9 -0
@@ -0,0 +1,82 @@
1
+ import { MigrationBuilder } from '@contember/database-migrations'
2
+ import { Model, Schema } from '@contember/schema'
3
+ import { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'
4
+ import { ModificationHandlerStatic } from '../ModificationHandler'
5
+ import { acceptFieldVisitor } from '@contember/schema-utils'
6
+
7
+ export const CreateIndexModification: ModificationHandlerStatic<CreateIndexModificationData> = class {
8
+ static id = 'createIndex'
9
+
10
+ constructor(private readonly data: CreateIndexModificationData, private readonly schema: Schema) {}
11
+
12
+ public createSql(builder: MigrationBuilder): void {
13
+ const entity = this.schema.model.entities[this.data.entityName]
14
+ if (entity.view) {
15
+ return
16
+ }
17
+ const fields = this.data.index.fields
18
+ const columns = fields.map(fieldName => {
19
+ return acceptFieldVisitor(this.schema.model, entity, fieldName, {
20
+ visitColumn: ({}, column) => {
21
+ return column.columnName
22
+ },
23
+ visitManyHasOne: ({}, relation) => {
24
+ return relation.joiningColumn.columnName
25
+ },
26
+ visitOneHasOneOwning: ({}, relation) => {
27
+ return relation.joiningColumn.columnName
28
+ },
29
+ visitOneHasMany: () => {
30
+ throw new Error(`Cannot create index on 1:m relation in ${entity.name}.${fieldName}`)
31
+ },
32
+ visitOneHasOneInverse: () => {
33
+ throw new Error(`Cannot create index on 1:1 inverse relation in ${entity.name}.${fieldName}`)
34
+ },
35
+ visitManyHasManyOwning: () => {
36
+ throw new Error(`Cannot create index on m:m relation in ${entity.name}.${fieldName}`)
37
+ },
38
+ visitManyHasManyInverse: () => {
39
+ throw new Error(`Cannot create index on m:m inverse relation in ${entity.name}.${fieldName}`)
40
+ },
41
+ })
42
+ })
43
+ builder.addIndex(entity.tableName, [...columns], {
44
+ name: this.data.index.name,
45
+ })
46
+ }
47
+
48
+ public getSchemaUpdater(): SchemaUpdater {
49
+ return updateModel(
50
+ updateEntity(this.data.entityName, ({ entity }) => ({
51
+ ...entity,
52
+ indexes: {
53
+ ...entity.indexes,
54
+ [this.data.index.name]: this.data.index,
55
+ },
56
+ })),
57
+ )
58
+ }
59
+
60
+ describe() {
61
+ return {
62
+ message: `Create index(${this.data.index.fields.join(', ')}) on entity ${this.data.entityName}`,
63
+ }
64
+ }
65
+
66
+ static createModification(data: CreateIndexModificationData) {
67
+ return { modification: this.id, ...data }
68
+ }
69
+
70
+ static createDiff(originalSchema: Schema, updatedSchema: Schema) {
71
+ return Object.values(updatedSchema.model.entities).flatMap(entity =>
72
+ Object.values(entity.indexes)
73
+ .filter(it => !originalSchema.model.entities[entity.name].indexes[it.name])
74
+ .map(index => CreateIndexModification.createModification({ entityName: entity.name, index })),
75
+ )
76
+ }
77
+ }
78
+
79
+ export interface CreateIndexModificationData {
80
+ entityName: string
81
+ index: Model.Index
82
+ }
@@ -0,0 +1,64 @@
1
+ import { MigrationBuilder } from '@contember/database-migrations'
2
+ import { Schema } from '@contember/schema'
3
+ import { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'
4
+ import { ModificationHandlerStatic } from '../ModificationHandler'
5
+ import deepEqual from 'fast-deep-equal'
6
+
7
+ export const RemoveIndexModification: ModificationHandlerStatic<RemoveIndexModificationData> = class {
8
+ static id = 'removeIndex'
9
+ constructor(private readonly data: RemoveIndexModificationData, private readonly schema: Schema) {}
10
+
11
+ public createSql(builder: MigrationBuilder): void {
12
+ const entity = this.schema.model.entities[this.data.entityName]
13
+ if (entity.view) {
14
+ return
15
+ }
16
+ builder.dropIndex(entity.tableName, [], {
17
+ name: this.data.indexName,
18
+ })
19
+ }
20
+
21
+ public getSchemaUpdater(): SchemaUpdater {
22
+ return updateModel(
23
+ updateEntity(this.data.entityName, ({ entity }) => {
24
+ const { [this.data.indexName]: removed, ...indexes } = entity.indexes
25
+ return {
26
+ ...entity,
27
+ indexes,
28
+ }
29
+ }),
30
+ )
31
+ }
32
+
33
+ describe() {
34
+ const fields = this.schema.model.entities[this.data.entityName].indexes[this.data.indexName].fields
35
+ return { message: `Remove index (${fields.join(', ')}) on entity ${this.data.entityName}` }
36
+ }
37
+
38
+ static createModification(data: RemoveIndexModificationData) {
39
+ return { modification: this.id, ...data }
40
+ }
41
+
42
+ static createDiff(originalSchema: Schema, updatedSchema: Schema) {
43
+ return Object.values(originalSchema.model.entities).flatMap(entity =>
44
+ Object.values(entity.indexes)
45
+ .filter(
46
+ it =>
47
+ updatedSchema.model.entities[entity.name] &&
48
+ (!updatedSchema.model.entities[entity.name].indexes[it.name] ||
49
+ !deepEqual(it.fields, updatedSchema.model.entities[entity.name].indexes[it.name].fields)),
50
+ )
51
+ .map(index =>
52
+ RemoveIndexModification.createModification({
53
+ entityName: entity.name,
54
+ indexName: index.name,
55
+ }),
56
+ ),
57
+ )
58
+ }
59
+ }
60
+
61
+ export interface RemoveIndexModificationData {
62
+ entityName: string
63
+ indexName: string
64
+ }
@@ -0,0 +1,2 @@
1
+ export * from './CreateIndexModification'
2
+ export * from './RemoveIndexModification'
@@ -0,0 +1,5 @@
1
+ import { Model } from '@contember/schema'
2
+
3
+ type SomePartial<E, K extends keyof E> = Omit<E, K> & Partial<Pick<E, K>>
4
+
5
+ export type PartialEntity = SomePartial<Model.Entity, 'eventLog' | 'indexes'>
@@ -0,0 +1,44 @@
1
+ import { testMigrations } from '../../src/tests'
2
+ import { SQL } from '../../src/tags'
3
+ import { SchemaDefinition as def } from '@contember/schema-definition'
4
+
5
+ namespace SchemaWithoutIndex {
6
+ export class Article {
7
+ title = def.stringColumn()
8
+ }
9
+ }
10
+
11
+ namespace SchemaWithIndex {
12
+ @def.Index('title')
13
+ export class Article {
14
+ title = def.stringColumn()
15
+ }
16
+ }
17
+
18
+
19
+ testMigrations('create index', {
20
+ originalSchema: def.createModel(SchemaWithoutIndex),
21
+ updatedSchema: def.createModel(SchemaWithIndex),
22
+ diff: [
23
+ {
24
+ modification: 'createIndex',
25
+ entityName: 'Article',
26
+ index: { name: 'idx_Article_title_2dc66a', fields: ['title'] },
27
+ },
28
+ ],
29
+ sql: SQL`CREATE INDEX "idx_Article_title_2dc66a" ON "article" ("title");`,
30
+ })
31
+
32
+
33
+ testMigrations('drop index', {
34
+ originalSchema: def.createModel(SchemaWithIndex),
35
+ updatedSchema: def.createModel(SchemaWithoutIndex),
36
+ diff: [
37
+ {
38
+ modification: 'removeIndex',
39
+ entityName: 'Article',
40
+ indexName: 'idx_Article_title_2dc66a',
41
+ },
42
+ ],
43
+ sql: SQL`DROP INDEX "idx_Article_title_2dc66a";`,
44
+ })
@@ -35,6 +35,7 @@ testMigrations('create a table (no relations, unique on column)', {
35
35
  eventLog: {
36
36
  enabled: true,
37
37
  },
38
+ indexes: {},
38
39
  },
39
40
  },
40
41
  {
@@ -141,6 +142,7 @@ testMigrations('create a view', {
141
142
  eventLog: {
142
143
  enabled: true,
143
144
  },
145
+ indexes: {},
144
146
  },
145
147
  },
146
148
  ],
@@ -34,6 +34,7 @@ testMigrations('create many has many relation (post with categories)', {
34
34
  eventLog: {
35
35
  enabled: true,
36
36
  },
37
+ indexes: {},
37
38
  },
38
39
  },
39
40
  {
@@ -36,6 +36,7 @@ testMigrations('create many has one relation (post with author)', {
36
36
  eventLog: {
37
37
  enabled: true,
38
38
  },
39
+ indexes: {},
39
40
  },
40
41
  },
41
42
  {
@@ -37,6 +37,7 @@ testMigrations('create one has many relation (post with locales)', {
37
37
  eventLog: {
38
38
  enabled: true,
39
39
  },
40
+ indexes: {},
40
41
  },
41
42
  },
42
43
  {
@@ -34,6 +34,7 @@ testMigrations('create one has one relation (site with settings)', {
34
34
  eventLog: {
35
35
  enabled: true,
36
36
  },
37
+ indexes: {},
37
38
  },
38
39
  },
39
40
  {
@@ -56,6 +57,7 @@ testMigrations('create one has one relation (site with settings)', {
56
57
  eventLog: {
57
58
  enabled: true,
58
59
  },
60
+ indexes: {},
59
61
  },
60
62
  },
61
63
  {
@@ -68,6 +68,7 @@ testMigrations('create view', {
68
68
  eventLog: {
69
69
  enabled: true,
70
70
  },
71
+ indexes: {},
71
72
  },
72
73
  },
73
74
  {
@@ -83,6 +83,7 @@ testMigrations('update a view 1', {
83
83
  eventLog: {
84
84
  enabled: true,
85
85
  },
86
+ indexes: {},
86
87
  },
87
88
  },
88
89
  {
@@ -118,6 +119,7 @@ testMigrations('update a view 1', {
118
119
  eventLog: {
119
120
  enabled: true,
120
121
  },
122
+ indexes: {},
121
123
  },
122
124
  },
123
125
  {
@@ -153,6 +155,7 @@ testMigrations('update a view 1', {
153
155
  eventLog: {
154
156
  enabled: true,
155
157
  },
158
+ indexes: {},
156
159
  },
157
160
  },
158
161
  ],
@@ -227,6 +230,7 @@ testMigrations('update a view 2', {
227
230
  eventLog: {
228
231
  enabled: true,
229
232
  },
233
+ indexes: {},
230
234
  },
231
235
  },
232
236
  {
@@ -262,6 +266,7 @@ testMigrations('update a view 2', {
262
266
  eventLog: {
263
267
  enabled: true,
264
268
  },
269
+ indexes: {},
265
270
  },
266
271
  },
267
272
  ],
@@ -331,6 +336,7 @@ testMigrations('update a view 3', {
331
336
  eventLog: {
332
337
  enabled: true,
333
338
  },
339
+ indexes: {},
334
340
  },
335
341
  },
336
342
  ],
@@ -402,6 +408,7 @@ testMigrations('update a view 4', {
402
408
  eventLog: {
403
409
  enabled: true,
404
410
  },
411
+ indexes: {},
405
412
  },
406
413
  },
407
414
  {
@@ -437,6 +444,7 @@ testMigrations('update a view 4', {
437
444
  eventLog: {
438
445
  enabled: true,
439
446
  },
447
+ indexes: {},
440
448
  },
441
449
  },
442
450
  {
@@ -472,6 +480,7 @@ testMigrations('update a view 4', {
472
480
  eventLog: {
473
481
  enabled: true,
474
482
  },
483
+ indexes: {},
475
484
  },
476
485
  },
477
486
  ],