@contember/engine-system-api 1.3.6 → 1.4.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 (82) hide show
  1. package/dist/src/SystemContainer.d.ts +3 -2
  2. package/dist/src/SystemContainer.d.ts.map +1 -1
  3. package/dist/src/SystemContainer.js +2 -1
  4. package/dist/src/SystemContainer.js.map +1 -1
  5. package/dist/src/bin/runMigrations.js +2 -5
  6. package/dist/src/bin/runMigrations.js.map +1 -1
  7. package/dist/src/index.d.ts +1 -1
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +1 -2
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/migrations/2022-10-03-110000-table-on-delete.js +2 -2
  12. package/dist/src/migrations/2022-10-03-110000-table-on-delete.js.map +1 -1
  13. package/dist/src/migrations/2023-09-11-174000-fix-on-delete.d.ts.map +1 -1
  14. package/dist/src/migrations/2023-09-11-174000-fix-on-delete.js +10 -13
  15. package/dist/src/migrations/2023-09-11-174000-fix-on-delete.js.map +1 -1
  16. package/dist/src/migrations/2023-10-19-173000-fix-unique.d.ts.map +1 -1
  17. package/dist/src/migrations/2023-10-19-173000-fix-unique.js +1 -1
  18. package/dist/src/migrations/2023-10-19-173000-fix-unique.js.map +1 -1
  19. package/dist/src/migrations/runner.d.ts +2 -3
  20. package/dist/src/migrations/runner.d.ts.map +1 -1
  21. package/dist/src/migrations/runner.js +1 -1
  22. package/dist/src/migrations/runner.js.map +1 -1
  23. package/dist/src/migrations/types.d.ts +2 -3
  24. package/dist/src/migrations/types.d.ts.map +1 -1
  25. package/dist/src/model/ProjectInitializer.d.ts +3 -3
  26. package/dist/src/model/ProjectInitializer.d.ts.map +1 -1
  27. package/dist/src/model/ProjectInitializer.js +3 -3
  28. package/dist/src/model/ProjectInitializer.js.map +1 -1
  29. package/dist/src/model/database/DatabaseContext.d.ts +2 -3
  30. package/dist/src/model/database/DatabaseContext.d.ts.map +1 -1
  31. package/dist/src/model/database/DatabaseContext.js +2 -3
  32. package/dist/src/model/database/DatabaseContext.js.map +1 -1
  33. package/dist/src/model/metadata/SchemaDatabaseMetadataResolverStore.d.ts +4 -5
  34. package/dist/src/model/metadata/SchemaDatabaseMetadataResolverStore.d.ts.map +1 -1
  35. package/dist/src/model/metadata/SchemaDatabaseMetadataResolverStore.js +1 -1
  36. package/dist/src/model/metadata/SchemaDatabaseMetadataResolverStore.js.map +1 -1
  37. package/dist/src/model/metadata/index.d.ts +0 -2
  38. package/dist/src/model/metadata/index.d.ts.map +1 -1
  39. package/dist/src/model/metadata/index.js +0 -4
  40. package/dist/src/model/metadata/index.js.map +1 -1
  41. package/dist/src/tsconfig.tsbuildinfo +1 -1
  42. package/dist/tests/cases/migrations/2020-05-06-150000-composed-primary.test.js +2 -2
  43. package/dist/tests/cases/migrations/2020-05-06-150000-composed-primary.test.js.map +1 -1
  44. package/dist/tests/cases/migrations/2020-06-01-103000-event-trigger-perf.test.js +2 -2
  45. package/dist/tests/cases/migrations/2020-06-01-103000-event-trigger-perf.test.js.map +1 -1
  46. package/dist/tests/cases/migrations/2022-10-03-110000-table-on-delete.test.js +15 -1
  47. package/dist/tests/cases/migrations/2022-10-03-110000-table-on-delete.test.js.map +1 -1
  48. package/dist/tests/cases/migrations/2023-09-11-174000-fix-on-delete.test.d.ts +2 -0
  49. package/dist/tests/cases/migrations/2023-09-11-174000-fix-on-delete.test.d.ts.map +1 -0
  50. package/dist/tests/cases/migrations/2023-09-11-174000-fix-on-delete.test.js +97 -0
  51. package/dist/tests/cases/migrations/2023-09-11-174000-fix-on-delete.test.js.map +1 -0
  52. package/dist/tests/cases/migrations/2023-10-19-173000-fix-unique.test.js +12 -11
  53. package/dist/tests/cases/migrations/2023-10-19-173000-fix-unique.test.js.map +1 -1
  54. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  55. package/package.json +14 -14
  56. package/src/SystemContainer.ts +3 -2
  57. package/src/bin/runMigrations.ts +4 -9
  58. package/src/index.ts +0 -1
  59. package/src/migrations/2022-10-03-110000-table-on-delete.ts +5 -5
  60. package/src/migrations/2023-09-11-174000-fix-on-delete.ts +13 -16
  61. package/src/migrations/2023-10-19-173000-fix-unique.ts +3 -4
  62. package/src/migrations/runner.ts +3 -4
  63. package/src/migrations/types.ts +2 -3
  64. package/src/model/ProjectInitializer.ts +3 -3
  65. package/src/model/database/DatabaseContext.ts +2 -3
  66. package/src/model/metadata/SchemaDatabaseMetadataResolverStore.ts +6 -7
  67. package/src/model/metadata/index.ts +0 -2
  68. package/tests/cases/migrations/2020-05-06-150000-composed-primary.test.ts +2 -2
  69. package/tests/cases/migrations/2020-06-01-103000-event-trigger-perf.test.ts +2 -2
  70. package/tests/cases/migrations/2022-10-03-110000-table-on-delete.test.ts +16 -2
  71. package/tests/cases/migrations/2023-09-11-174000-fix-on-delete.test.ts +106 -0
  72. package/tests/cases/migrations/2023-10-19-173000-fix-unique.test.ts +12 -12
  73. package/dist/src/model/metadata/ResolvedDatabaseMetadata.d.ts +0 -14
  74. package/dist/src/model/metadata/ResolvedDatabaseMetadata.d.ts.map +0 -1
  75. package/dist/src/model/metadata/ResolvedDatabaseMetadata.js +0 -49
  76. package/dist/src/model/metadata/ResolvedDatabaseMetadata.js.map +0 -1
  77. package/dist/src/model/metadata/SchemaDatabaseMetadataResolver.d.ts +0 -8
  78. package/dist/src/model/metadata/SchemaDatabaseMetadataResolver.d.ts.map +0 -1
  79. package/dist/src/model/metadata/SchemaDatabaseMetadataResolver.js +0 -98
  80. package/dist/src/model/metadata/SchemaDatabaseMetadataResolver.js.map +0 -1
  81. package/src/model/metadata/ResolvedDatabaseMetadata.ts +0 -62
  82. package/src/model/metadata/SchemaDatabaseMetadataResolver.ts +0 -140
@@ -1,49 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ResolvedDatabaseMetadata = void 0;
4
- const stringArrayEquals = (colA, colB) => {
5
- if (colA.length !== colB.length) {
6
- return false;
7
- }
8
- const a = [...colA].sort();
9
- const b = [...colB].sort();
10
- return a.every((it, index) => it === b[index]);
11
- };
12
- class ResolvedDatabaseMetadata {
13
- constructor(foreignKeys, uniqueConstraints, indexes) {
14
- this.foreignKeys = foreignKeys;
15
- this.uniqueConstraints = uniqueConstraints;
16
- this.indexes = indexes;
17
- }
18
- getAllUniqueConstraints() {
19
- return this.uniqueConstraints;
20
- }
21
- getUniqueConstraint(tableName, constraintName) {
22
- var _a;
23
- return (_a = this.uniqueConstraints.find(it => it.tableName === tableName && it.constraintName === constraintName)) !== null && _a !== void 0 ? _a : null;
24
- }
25
- getForeignKeyConstraint(tableName, constraintName) {
26
- var _a;
27
- return (_a = this.foreignKeys.find(it => it.fromTable === tableName && it.constraintName === constraintName)) !== null && _a !== void 0 ? _a : null;
28
- }
29
- getForeignKeyConstraintNames({ fromTable, fromColumn, toTable, toColumn }) {
30
- return this.foreignKeys
31
- .filter(it => it.fromTable === fromTable
32
- && it.toTable === toTable
33
- && it.fromColumn === fromColumn
34
- && it.toColumn === toColumn)
35
- .map(it => it.constraintName);
36
- }
37
- getUniqueConstraintNames({ tableName, columnNames }) {
38
- return this.uniqueConstraints
39
- .filter(it => it.tableName === tableName && stringArrayEquals(columnNames, it.columnNames))
40
- .map(it => it.constraintName);
41
- }
42
- getIndexNames({ tableName, columnNames }) {
43
- return this.indexes
44
- .filter(it => it.tableName === tableName && stringArrayEquals(columnNames, it.columnNames))
45
- .map(it => it.indexName);
46
- }
47
- }
48
- exports.ResolvedDatabaseMetadata = ResolvedDatabaseMetadata;
49
- //# sourceMappingURL=ResolvedDatabaseMetadata.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ResolvedDatabaseMetadata.js","sourceRoot":"","sources":["../../../../src/model/metadata/ResolvedDatabaseMetadata.ts"],"names":[],"mappings":";;;AAUA,MAAM,iBAAiB,GAAG,CAAC,IAAc,EAAE,IAAc,EAAE,EAAE;IAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE;QAChC,OAAO,KAAK,CAAA;KACZ;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1B,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;AAC/C,CAAC,CAAA;AAED,MAAa,wBAAwB;IACpC,YACkB,WAA2C,EAC3C,iBAA6C,EAC7C,OAAwB;QAFxB,gBAAW,GAAX,WAAW,CAAgC;QAC3C,sBAAiB,GAAjB,iBAAiB,CAA4B;QAC7C,YAAO,GAAP,OAAO,CAAiB;IAE1C,CAAC;IAED,uBAAuB;QACtB,OAAO,IAAI,CAAC,iBAAiB,CAAA;IAC9B,CAAC;IAED,mBAAmB,CAAC,SAAiB,EAAE,cAAsB;;QAC5D,OAAO,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,CAAC,cAAc,KAAK,cAAc,CAAC,mCAAI,IAAI,CAAA;IACrH,CAAC;IAED,uBAAuB,CAAC,SAAiB,EAAE,cAAsB;;QAChE,OAAO,MAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,CAAC,cAAc,KAAK,cAAc,CAAC,mCAAI,IAAI,CAAA;IAC/G,CAAC;IAED,4BAA4B,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAmC;QACzG,OAAO,IAAI,CAAC,WAAW;aACrB,MAAM,CAAC,EAAE,CAAC,EAAE,CACZ,EAAE,CAAC,SAAS,KAAK,SAAS;eACvB,EAAE,CAAC,OAAO,KAAK,OAAO;eACtB,EAAE,CAAC,UAAU,KAAK,UAAU;eAC5B,EAAE,CAAC,QAAQ,KAAK,QAAQ,CAC3B;aACA,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAA;IAC/B,CAAC;IAED,wBAAwB,CAAC,EAAE,SAAS,EAAE,WAAW,EAA+B;QAC/E,OAAO,IAAI,CAAC,iBAAiB;aAC3B,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,IAAI,iBAAiB,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;aAC1F,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAA;IAC/B,CAAC;IAED,aAAa,CAAC,EAAE,SAAS,EAAE,WAAW,EAAoB;QACzD,OAAO,IAAI,CAAC,OAAO;aACjB,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,IAAI,iBAAiB,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;aAC1F,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;IAC1B,CAAC;CACD;AA1CD,4DA0CC"}
@@ -1,8 +0,0 @@
1
- import { SchemaDatabaseMetadata } from '@contember/schema-utils';
2
- import { DatabaseContext } from '../database';
3
- export declare class SchemaDatabaseMetadataResolver {
4
- resolveMetadata(db: DatabaseContext, contentSchema: string): Promise<SchemaDatabaseMetadata>;
5
- private fetchConstraints;
6
- private fetchIndexes;
7
- }
8
- //# sourceMappingURL=SchemaDatabaseMetadataResolver.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SchemaDatabaseMetadataResolver.d.ts","sourceRoot":"","sources":["../../../../src/model/metadata/SchemaDatabaseMetadataResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,sBAAsB,EAGtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAI7C,qBAAa,8BAA8B;IACpC,eAAe,CAAC,EAAE,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;YAmCpF,gBAAgB;YAgChB,YAAY;CAsB1B"}
@@ -1,98 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SchemaDatabaseMetadataResolver = void 0;
4
- const schema_utils_1 = require("@contember/schema-utils");
5
- const ResolvedDatabaseMetadata_1 = require("./ResolvedDatabaseMetadata");
6
- class SchemaDatabaseMetadataResolver {
7
- async resolveMetadata(db, contentSchema) {
8
- const constraintRows = await this.fetchConstraints(db.client, contentSchema);
9
- const indexRows = await this.fetchIndexes(db.client, contentSchema);
10
- const fkConstraints = constraintRows
11
- .filter((it) => it.type === ConstraintTypes.foreignKey)
12
- .map((it) => {
13
- var _a;
14
- return ({
15
- constraintName: it.constraint_name,
16
- fromColumn: it.columns[0],
17
- toColumn: it.target_columns[0],
18
- fromTable: it.table_name,
19
- toTable: it.target_table,
20
- deleteAction: (_a = it.delete_action) !== null && _a !== void 0 ? _a : schema_utils_1.ForeignKeyDeleteAction.noaction,
21
- });
22
- });
23
- const uniqueConstraints = constraintRows
24
- .filter((it) => it.type === ConstraintTypes.unique)
25
- .map((it) => ({
26
- constraintName: it.constraint_name,
27
- tableName: it.table_name,
28
- columnNames: it.columns,
29
- }));
30
- const indexes = indexRows
31
- .map((it) => ({
32
- indexName: it.index_name,
33
- tableName: it.table_name,
34
- columnNames: it.columns,
35
- }));
36
- return new ResolvedDatabaseMetadata_1.ResolvedDatabaseMetadata(fkConstraints, uniqueConstraints, indexes);
37
- }
38
- async fetchConstraints(connection, schema) {
39
- return (await connection.query(`
40
- SELECT
41
- MAX(pg_constraint.conname) AS constraint_name,
42
- MAX(pg_class.relname) AS table_name,
43
- JSONB_AGG(DISTINCT pg_attribute.attname) AS columns,
44
- MAX(pg_constraint.contype) AS type,
45
- MAX(pg_constraint_table.relname) AS target_table,
46
- JSONB_AGG(DISTINCT pg_attribute_target.attname)
47
- FILTER ( WHERE pg_attribute_target.attname IS NOT NULL) AS target_columns,
48
- BOOL_OR(condeferrable),
49
- BOOL_OR(condeferred),
50
- MAX(confdeltype) AS delete_action
51
- FROM pg_constraint
52
- JOIN pg_class
53
- ON pg_constraint.conrelid = pg_class.oid
54
- JOIN pg_namespace
55
- ON pg_class.relnamespace = pg_namespace.oid
56
- JOIN pg_attribute
57
- ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = ANY (pg_constraint.conkey)
58
- LEFT JOIN pg_attribute pg_attribute_target
59
- ON pg_constraint.confrelid = pg_attribute_target.attrelid AND
60
- pg_attribute_target.attnum = ANY (pg_constraint.confkey)
61
- LEFT JOIN pg_class pg_constraint_table
62
- ON pg_constraint_table.oid = pg_constraint.confrelid
63
- WHERE pg_namespace.nspname = ?
64
- AND pg_constraint.contype = ANY (ARRAY ['f', 'u'])
65
- GROUP BY pg_constraint.oid
66
- `, [schema]))
67
- .rows;
68
- }
69
- async fetchIndexes(connection, schema) {
70
- return (await connection.query(`
71
- SELECT
72
- MAX(idx_class.relname) AS index_name,
73
- MAX(table_class.relname) AS table_name,
74
- JSONB_AGG(DISTINCT pg_attribute.attname) AS columns
75
- FROM pg_index
76
- JOIN pg_class AS table_class
77
- ON pg_index.indrelid = table_class.oid
78
- JOIN pg_class AS idx_class
79
- ON pg_index.indexrelid = idx_class.oid
80
- JOIN pg_namespace
81
- ON table_class.relnamespace = pg_namespace.oid
82
- JOIN pg_attribute
83
- ON pg_attribute.attrelid = table_class.oid AND pg_attribute.attnum = ANY (pg_index.indkey)
84
- WHERE pg_namespace.nspname = ?
85
- AND indisprimary = FALSE
86
- AND indisunique = FALSE
87
- GROUP BY pg_index.indexrelid
88
- `, [schema]))
89
- .rows;
90
- }
91
- }
92
- exports.SchemaDatabaseMetadataResolver = SchemaDatabaseMetadataResolver;
93
- var ConstraintTypes;
94
- (function (ConstraintTypes) {
95
- ConstraintTypes["foreignKey"] = "f";
96
- ConstraintTypes["unique"] = "u";
97
- })(ConstraintTypes || (ConstraintTypes = {}));
98
- //# sourceMappingURL=SchemaDatabaseMetadataResolver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SchemaDatabaseMetadataResolver.js","sourceRoot":"","sources":["../../../../src/model/metadata/SchemaDatabaseMetadataResolver.ts"],"names":[],"mappings":";;;AAAA,0DAMgC;AAGhC,yEAAqE;AAErE,MAAa,8BAA8B;IAC1C,KAAK,CAAC,eAAe,CAAC,EAAmB,EAAE,aAAqB;QAC/D,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;QAC5E,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;QAEnE,MAAM,aAAa,GAAG,cAAc;aAClC,MAAM,CAAC,CAAC,EAAE,EAAkC,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,eAAe,CAAC,UAAU,CAAC;aACtF,GAAG,CAAC,CAAC,EAAE,EAAgC,EAAE;;YAAC,OAAA,CAAC;gBAC3C,cAAc,EAAE,EAAE,CAAC,eAAe;gBAClC,UAAU,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;gBACzB,QAAQ,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;gBAC9B,SAAS,EAAE,EAAE,CAAC,UAAU;gBACxB,OAAO,EAAE,EAAE,CAAC,YAAY;gBACxB,YAAY,EAAE,MAAA,EAAE,CAAC,aAAa,mCAAI,qCAAsB,CAAC,QAAQ;aACjE,CAAC,CAAA;SAAA,CAAC,CAAA;QACJ,MAAM,iBAAiB,GAAG,cAAc;aACtC,MAAM,CAAC,CAAC,EAAE,EAA8B,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,eAAe,CAAC,MAAM,CAAC;aAC9E,GAAG,CAAC,CAAC,EAAE,EAA4B,EAAE,CAAC,CAAC;YACvC,cAAc,EAAE,EAAE,CAAC,eAAe;YAClC,SAAS,EAAE,EAAE,CAAC,UAAU;YACxB,WAAW,EAAE,EAAE,CAAC,OAAO;SACvB,CAAC,CAAC,CAAA;QACJ,MAAM,OAAO,GAAG,SAAS;aACvB,GAAG,CAAC,CAAC,EAAE,EAAiB,EAAE,CAAC,CAAC;YAC5B,SAAS,EAAE,EAAE,CAAC,UAAU;YACxB,SAAS,EAAE,EAAE,CAAC,UAAU;YACxB,WAAW,EAAE,EAAE,CAAC,OAAO;SACvB,CAAC,CAAC,CAAA;QAEJ,OAAO,IAAI,mDAAwB,CAClC,aAAa,EACb,iBAAiB,EACjB,OAAO,CACP,CAAA;IACF,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,UAAgC,EAAE,MAAc;QAC9E,OAAO,CAAC,MAAM,UAAU,CAAC,KAAK,CAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2B9C,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;aACX,IAAI,CAAA;IACP,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,UAAgC,EAAE,MAAc;QAC1E,OAAO,CAAC,MAAM,UAAU,CAAC,KAAK,CAAW;;;;;;;;;;;;;;;;;;GAkBxC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;aACX,IAAI,CAAA;IACP,CAAC;CACD;AA1FD,wEA0FC;AAED,IAAK,eAGJ;AAHD,WAAK,eAAe;IACnB,mCAAgB,CAAA;IAChB,+BAAY,CAAA;AACb,CAAC,EAHI,eAAe,KAAf,eAAe,QAGnB"}
@@ -1,62 +0,0 @@
1
- import {
2
- ForeignKeyConstraintMetadata,
3
- GetForeignKeyConstraintNameArgs,
4
- GetIndexNameArgs,
5
- GetUniqueConstraintNameArgs,
6
- IndexMetadata,
7
- SchemaDatabaseMetadata,
8
- UniqueConstraintMetadata,
9
- } from '@contember/schema-utils'
10
-
11
- const stringArrayEquals = (colA: string[], colB: string[]) => {
12
- if (colA.length !== colB.length) {
13
- return false
14
- }
15
- const a = [...colA].sort()
16
- const b = [...colB].sort()
17
- return a.every((it, index) => it === b[index])
18
- }
19
-
20
- export class ResolvedDatabaseMetadata implements SchemaDatabaseMetadata {
21
- constructor(
22
- private readonly foreignKeys: ForeignKeyConstraintMetadata[],
23
- private readonly uniqueConstraints: UniqueConstraintMetadata[],
24
- private readonly indexes: IndexMetadata[],
25
- ) {
26
- }
27
-
28
- getAllUniqueConstraints(): UniqueConstraintMetadata[] {
29
- return this.uniqueConstraints
30
- }
31
-
32
- getUniqueConstraint(tableName: string, constraintName: string): UniqueConstraintMetadata | null {
33
- return this.uniqueConstraints.find(it => it.tableName === tableName && it.constraintName === constraintName) ?? null
34
- }
35
-
36
- getForeignKeyConstraint(tableName: string, constraintName: string): ForeignKeyConstraintMetadata | null {
37
- return this.foreignKeys.find(it => it.fromTable === tableName && it.constraintName === constraintName) ?? null
38
- }
39
-
40
- getForeignKeyConstraintNames({ fromTable, fromColumn, toTable, toColumn }: GetForeignKeyConstraintNameArgs): string[] {
41
- return this.foreignKeys
42
- .filter(it =>
43
- it.fromTable === fromTable
44
- && it.toTable === toTable
45
- && it.fromColumn === fromColumn
46
- && it.toColumn === toColumn,
47
- )
48
- .map(it => it.constraintName)
49
- }
50
-
51
- getUniqueConstraintNames({ tableName, columnNames }: GetUniqueConstraintNameArgs): string[] {
52
- return this.uniqueConstraints
53
- .filter(it => it.tableName === tableName && stringArrayEquals(columnNames, it.columnNames))
54
- .map(it => it.constraintName)
55
- }
56
-
57
- getIndexNames({ tableName, columnNames }: GetIndexNameArgs): string[] {
58
- return this.indexes
59
- .filter(it => it.tableName === tableName && stringArrayEquals(columnNames, it.columnNames))
60
- .map(it => it.indexName)
61
- }
62
- }
@@ -1,140 +0,0 @@
1
- import {
2
- ForeignKeyConstraintMetadata,
3
- IndexMetadata,
4
- SchemaDatabaseMetadata,
5
- UniqueConstraintMetadata,
6
- ForeignKeyDeleteAction,
7
- } from '@contember/schema-utils'
8
- import { DatabaseContext } from '../database'
9
- import { Connection } from '@contember/database'
10
- import { ResolvedDatabaseMetadata } from './ResolvedDatabaseMetadata'
11
-
12
- export class SchemaDatabaseMetadataResolver {
13
- async resolveMetadata(db: DatabaseContext, contentSchema: string): Promise<SchemaDatabaseMetadata> {
14
- const constraintRows = await this.fetchConstraints(db.client, contentSchema)
15
- const indexRows = await this.fetchIndexes(db.client, contentSchema)
16
-
17
- const fkConstraints = constraintRows
18
- .filter((it): it is ForeignKeyConstraintsRow => it.type === ConstraintTypes.foreignKey)
19
- .map((it): ForeignKeyConstraintMetadata => ({
20
- constraintName: it.constraint_name,
21
- fromColumn: it.columns[0],
22
- toColumn: it.target_columns[0],
23
- fromTable: it.table_name,
24
- toTable: it.target_table,
25
- deleteAction: it.delete_action ?? ForeignKeyDeleteAction.noaction,
26
- }))
27
- const uniqueConstraints = constraintRows
28
- .filter((it): it is UniqueConstraintsRow => it.type === ConstraintTypes.unique)
29
- .map((it): UniqueConstraintMetadata => ({
30
- constraintName: it.constraint_name,
31
- tableName: it.table_name,
32
- columnNames: it.columns,
33
- }))
34
- const indexes = indexRows
35
- .map((it): IndexMetadata => ({
36
- indexName: it.index_name,
37
- tableName: it.table_name,
38
- columnNames: it.columns,
39
- }))
40
-
41
- return new ResolvedDatabaseMetadata(
42
- fkConstraints,
43
- uniqueConstraints,
44
- indexes,
45
- )
46
- }
47
-
48
- private async fetchConstraints(connection: Connection.Queryable, schema: string): Promise<ConstraintsRow[]> {
49
- return (await connection.query<ConstraintsRow>(`
50
- SELECT
51
- MAX(pg_constraint.conname) AS constraint_name,
52
- MAX(pg_class.relname) AS table_name,
53
- JSONB_AGG(DISTINCT pg_attribute.attname) AS columns,
54
- MAX(pg_constraint.contype) AS type,
55
- MAX(pg_constraint_table.relname) AS target_table,
56
- JSONB_AGG(DISTINCT pg_attribute_target.attname)
57
- FILTER ( WHERE pg_attribute_target.attname IS NOT NULL) AS target_columns,
58
- BOOL_OR(condeferrable),
59
- BOOL_OR(condeferred),
60
- MAX(confdeltype) AS delete_action
61
- FROM pg_constraint
62
- JOIN pg_class
63
- ON pg_constraint.conrelid = pg_class.oid
64
- JOIN pg_namespace
65
- ON pg_class.relnamespace = pg_namespace.oid
66
- JOIN pg_attribute
67
- ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = ANY (pg_constraint.conkey)
68
- LEFT JOIN pg_attribute pg_attribute_target
69
- ON pg_constraint.confrelid = pg_attribute_target.attrelid AND
70
- pg_attribute_target.attnum = ANY (pg_constraint.confkey)
71
- LEFT JOIN pg_class pg_constraint_table
72
- ON pg_constraint_table.oid = pg_constraint.confrelid
73
- WHERE pg_namespace.nspname = ?
74
- AND pg_constraint.contype = ANY (ARRAY ['f', 'u'])
75
- GROUP BY pg_constraint.oid
76
- `, [schema]))
77
- .rows
78
- }
79
-
80
- private async fetchIndexes(connection: Connection.Queryable, schema: string): Promise<IndexRow[]> {
81
- return (await connection.query<IndexRow>(`
82
- SELECT
83
- MAX(idx_class.relname) AS index_name,
84
- MAX(table_class.relname) AS table_name,
85
- JSONB_AGG(DISTINCT pg_attribute.attname) AS columns
86
- FROM pg_index
87
- JOIN pg_class AS table_class
88
- ON pg_index.indrelid = table_class.oid
89
- JOIN pg_class AS idx_class
90
- ON pg_index.indexrelid = idx_class.oid
91
- JOIN pg_namespace
92
- ON table_class.relnamespace = pg_namespace.oid
93
- JOIN pg_attribute
94
- ON pg_attribute.attrelid = table_class.oid AND pg_attribute.attnum = ANY (pg_index.indkey)
95
- WHERE pg_namespace.nspname = ?
96
- AND indisprimary = FALSE
97
- AND indisunique = FALSE
98
- GROUP BY pg_index.indexrelid
99
- `, [schema]))
100
- .rows
101
- }
102
- }
103
-
104
- enum ConstraintTypes {
105
- foreignKey = 'f',
106
- unique = 'u',
107
- }
108
-
109
- type ConstraintsRow =
110
- | ForeignKeyConstraintsRow
111
- | UniqueConstraintsRow
112
-
113
- type ForeignKeyConstraintsRow = {
114
- constraint_name: string
115
- table_name: string
116
- columns: string[]
117
- target_table: string
118
- target_columns: string[]
119
- type: ConstraintTypes.foreignKey
120
- deferrable: boolean
121
- deferred: boolean
122
- delete_action: ForeignKeyDeleteAction | null
123
- }
124
- type UniqueConstraintsRow = {
125
- constraint_name: string
126
- table_name: string
127
- columns: string[]
128
- target_table: null
129
- target_columns: null
130
- type: ConstraintTypes.unique
131
- deferrable: boolean
132
- deferred: boolean
133
- }
134
-
135
- type IndexRow = {
136
- index_name: string
137
- table_name: string
138
- columns: string[]
139
- }
140
-