@contember/engine-system-api 1.3.4 → 1.4.0-alpha.1

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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-system-api",
3
- "version": "1.3.4",
3
+ "version": "1.4.0-alpha.1",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -13,22 +13,22 @@
13
13
  "test": "vitest --dir ./tests/cases"
14
14
  },
15
15
  "dependencies": {
16
- "@contember/authorization": "1.3.4",
17
- "@contember/database": "1.3.4",
18
- "@contember/database-migrations": "1.3.4",
19
- "@contember/dic": "1.3.4",
20
- "@contember/graphql-utils": "1.3.4",
21
- "@contember/logger": "1.3.4",
22
- "@contember/queryable": "1.3.4",
23
- "@contember/schema": "1.3.4",
24
- "@contember/schema-migrations": "1.3.4",
25
- "@contember/schema-utils": "1.3.4",
26
- "@graphql-tools/utils": "^8.6.13",
16
+ "@contember/authorization": "1.4.0-alpha.1",
17
+ "@contember/database": "1.4.0-alpha.1",
18
+ "@contember/database-migrations": "1.4.0-alpha.1",
19
+ "@contember/dic": "1.4.0-alpha.1",
20
+ "@contember/graphql-utils": "1.4.0-alpha.1",
21
+ "@contember/logger": "1.4.0-alpha.1",
22
+ "@contember/queryable": "1.4.0-alpha.1",
23
+ "@contember/schema": "1.4.0-alpha.1",
24
+ "@contember/schema-migrations": "1.4.0-alpha.1",
25
+ "@contember/schema-utils": "1.4.0-alpha.1",
26
+ "@graphql-tools/utils": "^10.0.7",
27
27
  "graphql-tag": "^2.12.5"
28
28
  },
29
29
  "devDependencies": {
30
- "@contember/engine-api-tester": "1.3.4",
31
- "@contember/schema-definition": "1.3.4",
30
+ "@contember/engine-api-tester": "1.4.0-alpha.1",
31
+ "@contember/schema-definition": "1.4.0-alpha.1",
32
32
  "@graphql-codegen/cli": "^2.6.2",
33
33
  "@graphql-codegen/typescript": "^2.5.1",
34
34
  "@graphql-codegen/typescript-operations": "^2.4.2",
@@ -14,7 +14,7 @@ import {
14
14
  MigrationsDatabaseMetadataResolverStoreFactory,
15
15
  PermissionsFactory,
16
16
  ProjectMigrator,
17
- ProjectTruncateExecutor, SchemaDatabaseMetadataResolver,
17
+ ProjectTruncateExecutor,
18
18
  SchemaVersionBuilder,
19
19
  } from './model'
20
20
  import { UuidProvider } from './utils'
@@ -29,6 +29,7 @@ import {
29
29
  TruncateMutationResolver,
30
30
  } from './resolvers'
31
31
  import { EventOldValuesResolver } from './resolvers/types'
32
+ import { DatabaseMetadataResolver } from '@contember/database'
32
33
 
33
34
  export interface SystemContainer {
34
35
  systemResolversFactory: ResolverFactory
@@ -81,7 +82,7 @@ export class SystemContainerFactory {
81
82
  .addService('migrationDescriber', ({ modificationHandlerFactory }) =>
82
83
  new MigrationDescriber(modificationHandlerFactory))
83
84
  .addService('databaseMetadataResolver', () =>
84
- new SchemaDatabaseMetadataResolver())
85
+ new DatabaseMetadataResolver())
85
86
  .addService('migrationsDatabaseMetadataResolverStoreFactory', ({ databaseMetadataResolver }) =>
86
87
  new MigrationsDatabaseMetadataResolverStoreFactory(databaseMetadataResolver))
87
88
  .addService('projectMigrator', ({ migrationDescriber, schemaVersionBuilder, executedMigrationsResolver, migrationsDatabaseMetadataResolverStoreFactory }) =>
@@ -1,12 +1,9 @@
1
1
  import { SystemMigrationsRunner } from '../migrations'
2
2
  import { DatabaseContextFactory, emptyVersionedSchema, SchemaVersionBuilder } from '../model'
3
- import { Connection } from '@contember/database'
3
+ import { Connection, DatabaseMetadataResolver, emptyDatabaseMetadata } from '@contember/database'
4
4
  import { createLogger, PrettyPrintLoggerHandler } from '@contember/logger'
5
5
 
6
6
 
7
- import { SchemaDatabaseMetadataResolver } from '../model/metadata/SchemaDatabaseMetadataResolver'
8
- import { dummySchemaDatabaseMetadata } from '@contember/schema-utils';
9
-
10
7
  (async () => {
11
8
  const dbConfig = {
12
9
  database: process.env.PGDATABASE as string,
@@ -15,10 +12,8 @@ import { dummySchemaDatabaseMetadata } from '@contember/schema-utils';
15
12
  user: process.env.PGUSER as string,
16
13
  port: process.env.PGPORT ? Number(process.env.PGPORT) : 5432,
17
14
  }
18
- // eslint-disable-next-line no-console
19
- const connection = Connection.createSingle(dbConfig, err => console.error(err))
20
15
  const migrationsRunner = new SystemMigrationsRunner(
21
- new DatabaseContextFactory('system', connection, {
16
+ new DatabaseContextFactory('system', {
22
17
  uuid: () => {
23
18
  throw new Error()
24
19
  },
@@ -30,8 +25,8 @@ import { dummySchemaDatabaseMetadata } from '@contember/schema-utils';
30
25
  } as unknown as SchemaVersionBuilder,
31
26
  {},
32
27
  {
33
- resolveMetadata: () => Promise.resolve(dummySchemaDatabaseMetadata),
34
- } as unknown as SchemaDatabaseMetadataResolver,
28
+ resolveMetadata: () => Promise.resolve(emptyDatabaseMetadata),
29
+ } as unknown as DatabaseMetadataResolver,
35
30
  )
36
31
  // eslint-disable-next-line no-console
37
32
  await migrationsRunner.run(createLogger(new PrettyPrintLoggerHandler(process.stderr)))
package/src/index.ts CHANGED
@@ -12,7 +12,6 @@ export {
12
12
  LatestTransactionIdByStageQuery,
13
13
  ProjectInitializer,
14
14
  ProjectMigrator,
15
- SchemaDatabaseMetadataResolver,
16
15
  SchemaVersionBuilder,
17
16
  Stage,
18
17
  StageBySlugQuery,
@@ -1,13 +1,13 @@
1
1
  import { MigrationArgs, MigrationBuilder } from '@contember/database-migrations'
2
- import { wrapIdentifier } from '@contember/database'
2
+ import { DatabaseMetadata, wrapIdentifier } from '@contember/database'
3
3
  import { SystemMigrationArgs } from './types'
4
- import { acceptFieldVisitor, SchemaDatabaseMetadata } from '@contember/schema-utils'
4
+ import { acceptFieldVisitor } from '@contember/schema-utils'
5
5
  import { Model } from '@contember/schema'
6
6
 
7
7
  export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
8
8
  const schema = await args.schemaResolver(args.connection)
9
9
  const stages = (await args.connection.query<{schema: string}>('SELECT schema FROM stage')).rows
10
- const metadataByStage: Record<string, SchemaDatabaseMetadata> = {}
10
+ const metadataByStage: Record<string, DatabaseMetadata> = {}
11
11
 
12
12
  for (const entity of Object.values(schema.model.entities)) {
13
13
  for (const field of Object.values(entity.fields)) {
@@ -40,12 +40,12 @@ export default async function (builder: MigrationBuilder, args: MigrationArgs<Sy
40
40
  for (const stage of stages) {
41
41
  const databaseMetadata = metadataByStage[stage.schema] ??= await args.databaseMetadataResolver(args.connection, stage.schema)
42
42
 
43
- const fkNames = databaseMetadata.getForeignKeyConstraintNames({
43
+ const fkNames = databaseMetadata.foreignKeys.filter({
44
44
  fromTable: entity.tableName,
45
45
  fromColumn: relation.joiningColumn.columnName,
46
46
  toTable: targetEntity.tableName,
47
47
  toColumn: targetEntity.primaryColumn,
48
- })
48
+ }).getNames()
49
49
  for (const name of fkNames) {
50
50
  builder.sql(`ALTER TABLE ${wrapIdentifier(stage.schema)}.${wrapIdentifier(entity.tableName)} DROP CONSTRAINT ${wrapIdentifier(name)}`)
51
51
  }
@@ -1,13 +1,13 @@
1
1
  import { MigrationArgs, MigrationBuilder } from '@contember/database-migrations'
2
- import { wrapIdentifier } from '@contember/database'
2
+ import { DatabaseMetadata, ForeignKeyDeleteAction, wrapIdentifier } from '@contember/database'
3
3
  import { SystemMigrationArgs } from './types'
4
- import { acceptFieldVisitor, ForeignKeyDeleteAction, SchemaDatabaseMetadata } from '@contember/schema-utils'
4
+ import { acceptFieldVisitor } from '@contember/schema-utils'
5
5
  import { Model } from '@contember/schema'
6
6
 
7
7
  export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
8
8
  const schema = await args.schemaResolver(args.connection)
9
9
  const stages = (await args.connection.query<{schema: string}>('SELECT schema FROM stage')).rows
10
- const metadataByStage: Record<string, SchemaDatabaseMetadata> = {}
10
+ const metadataByStage: Record<string, DatabaseMetadata> = {}
11
11
 
12
12
  for (const entity of Object.values(schema.model.entities)) {
13
13
  for (const field of Object.values(entity.fields)) {
@@ -37,28 +37,25 @@ export default async function (builder: MigrationBuilder, args: MigrationArgs<Sy
37
37
  for (const stage of stages) {
38
38
  const databaseMetadata = metadataByStage[stage.schema] ??= await args.databaseMetadataResolver(args.connection, stage.schema)
39
39
 
40
- const fkNames = databaseMetadata.getForeignKeyConstraintNames({
40
+ const fks = databaseMetadata.foreignKeys.filter({
41
41
  fromTable: entity.tableName,
42
42
  fromColumn: relation.joiningColumn.columnName,
43
43
  toTable: targetEntity.tableName,
44
44
  toColumn: targetEntity.primaryColumn,
45
- })
45
+ }).toArray()
46
46
 
47
- if (fkNames.every(it => {
48
- const constraint = databaseMetadata.getForeignKeyConstraint(entity.tableName, it)
49
- const dbConstraintFlag = ({
50
- [Model.OnDelete.setNull]: ForeignKeyDeleteAction.setnull,
51
- [Model.OnDelete.cascade]: ForeignKeyDeleteAction.cascade,
52
- [Model.OnDelete.restrict]: ForeignKeyDeleteAction.restrict,
53
- } as const)[relation.joiningColumn.onDelete]
47
+ const dbConstraintFlag = ({
48
+ [Model.OnDelete.setNull]: ForeignKeyDeleteAction.setnull,
49
+ [Model.OnDelete.cascade]: ForeignKeyDeleteAction.cascade,
50
+ [Model.OnDelete.restrict]: ForeignKeyDeleteAction.restrict,
51
+ } as const)[relation.joiningColumn.onDelete]
54
52
 
55
- return constraint && constraint.deleteAction === dbConstraintFlag
56
- })) {
53
+ if (fks.every(it => it.deleteAction === dbConstraintFlag)) {
57
54
  continue
58
55
  }
59
56
 
60
- for (const name of fkNames) {
61
- builder.sql(`ALTER TABLE ${wrapIdentifier(stage.schema)}.${wrapIdentifier(entity.tableName)} DROP CONSTRAINT ${wrapIdentifier(name)}`)
57
+ for (const fk of fks) {
58
+ builder.sql(`ALTER TABLE ${wrapIdentifier(stage.schema)}.${wrapIdentifier(entity.tableName)} DROP CONSTRAINT ${wrapIdentifier(fk.constraintName)}`)
62
59
  }
63
60
 
64
61
  const onDelete = ({
@@ -1,13 +1,12 @@
1
1
  import { MigrationArgs, MigrationBuilder } from '@contember/database-migrations'
2
- import { wrapIdentifier } from '@contember/database'
2
+ import { DatabaseMetadata, wrapIdentifier } from '@contember/database'
3
3
  import { SystemMigrationArgs } from './types'
4
- import { acceptEveryFieldVisitor, SchemaDatabaseMetadata } from '@contember/schema-utils'
5
4
  import { getUniqueConstraintColumns } from '@contember/schema-migrations'
6
5
 
7
6
  export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
8
7
  const schema = await args.schemaResolver(args.connection)
9
8
  const stages = (await args.connection.query<{schema: string}>('SELECT schema FROM stage')).rows
10
- const metadataByStage: Record<string, SchemaDatabaseMetadata> = {}
9
+ const metadataByStage: Record<string, DatabaseMetadata> = {}
11
10
 
12
11
  for (const entity of Object.values(schema.model.entities)) {
13
12
  if (entity.view) {
@@ -29,7 +28,7 @@ export default async function (builder: MigrationBuilder, args: MigrationArgs<Sy
29
28
  for (const stage of stages) {
30
29
  const databaseMetadata = metadataByStage[stage.schema] ??= await args.databaseMetadataResolver(args.connection, stage.schema)
31
30
 
32
- const existingUniqueConstraints = databaseMetadata.getAllUniqueConstraints().filter(it => it.tableName === entity.tableName)
31
+ const existingUniqueConstraints = databaseMetadata.uniqueConstraints.filter({ tableName: entity.tableName }).toArray()
33
32
  for (const constraint of existingUniqueConstraints) {
34
33
  if (constraint.columnNames.length === 1 || expectedUnique.some(it => stringArrayEquals(it, constraint.columnNames))) {
35
34
  continue
@@ -21,13 +21,12 @@ import _20230911174000fixondelete from './2023-09-11-174000-fix-on-delete'
21
21
  import _20231019173000fixunique from './2023-10-19-173000-fix-unique'
22
22
  import snapshot from './snapshot'
23
23
 
24
- import { Client, Connection, createDatabaseIfNotExists, DatabaseConfig } from '@contember/database'
24
+ import { Client, Connection, createDatabaseIfNotExists, DatabaseConfig, DatabaseMetadataResolver } from '@contember/database'
25
25
  import { DatabaseContextFactory, SchemaVersionBuilder } from '../model'
26
26
  import { ProjectConfig } from '../types'
27
27
  import { Logger } from '@contember/logger'
28
28
  import { GroupMigrationsResolver } from '@contember/database-migrations'
29
29
  import { SnapshotMigrationResolver } from '@contember/database-migrations'
30
- import { SchemaDatabaseMetadataResolver } from '../model/metadata/SchemaDatabaseMetadataResolver'
31
30
 
32
31
  const migrations = {
33
32
  '2018-08-04-102200-init': _20180804102200init,
@@ -60,7 +59,7 @@ export class SystemMigrationsRunner {
60
59
  private readonly schema: string,
61
60
  private readonly schemaVersionBuilder: SchemaVersionBuilder,
62
61
  private readonly migrationGroups: Record<string, MigrationGroup<unknown>>,
63
- private readonly databaseMetadataResolver: SchemaDatabaseMetadataResolver,
62
+ private readonly databaseMetadataResolver: DatabaseMetadataResolver,
64
63
  ) {
65
64
  }
66
65
  async run(logger: Logger) {
@@ -91,7 +90,7 @@ export class SystemMigrationsRunner {
91
90
  schemaResolver,
92
91
  databaseMetadataResolver: (connection: Connection.ConnectionLike, schema: string) => {
93
92
  const dbContextMigrations = this.databaseContextFactory.create(connection)
94
- return this.databaseMetadataResolver.resolveMetadata(dbContextMigrations, schema)
93
+ return this.databaseMetadataResolver.resolveMetadata(dbContextMigrations.client, schema)
95
94
  },
96
95
 
97
96
  })
@@ -1,10 +1,9 @@
1
1
  import { Schema } from '@contember/schema'
2
2
  import { ProjectConfig } from '../types'
3
- import { Connection } from '@contember/database'
4
- import { SchemaDatabaseMetadata } from '@contember/schema-utils'
3
+ import { Connection, DatabaseMetadata } from '@contember/database'
5
4
 
6
5
  export interface SystemMigrationArgs {
7
6
  schemaResolver: (connection: Connection.ConnectionLike) => Promise<Schema>
8
- databaseMetadataResolver: (connection: Connection.ConnectionLike, schema: string) => Promise<SchemaDatabaseMetadata>
7
+ databaseMetadataResolver: (connection: Connection.ConnectionLike, schema: string) => Promise<DatabaseMetadata>
9
8
  project: ProjectConfig
10
9
  }
@@ -1,6 +1,6 @@
1
1
  import { ProjectConfig } from '../types'
2
2
  import { StageCreator } from './stages'
3
- import { DatabaseContext, DatabaseContextFactory } from './database'
3
+ import { DatabaseContext } from './database'
4
4
  import { Connection, retryTransaction } from '@contember/database'
5
5
  import { FingerCrossedLoggerHandler, Logger } from '@contember/logger'
6
6
  import { SystemMigrationsRunner } from '../migrations'
@@ -9,7 +9,7 @@ export class ProjectInitializer {
9
9
  constructor(
10
10
  private readonly stageCreator: StageCreator,
11
11
  private readonly migrationsRunner: SystemMigrationsRunner,
12
- private readonly databaseContextFactory: DatabaseContextFactory,
12
+ private readonly databaseContext: DatabaseContext,
13
13
  private readonly project: ProjectConfig,
14
14
  ) {}
15
15
 
@@ -17,7 +17,7 @@ export class ProjectInitializer {
17
17
  return await logger.scope(async initLogger => {
18
18
  initLogger.debug('Executing system schema migrations')
19
19
  await this.migrationsRunner.run(initLogger)
20
- const dbContext = this.databaseContextFactory.create()
20
+ const dbContext = this.databaseContext
21
21
  await retryTransaction(
22
22
  () => dbContext.transaction(async trx => {
23
23
  await this.initStages(trx, logger)
@@ -15,12 +15,11 @@ export interface DatabaseContext<ConnectionType extends Connection.ConnectionLik
15
15
  export class DatabaseContextFactory {
16
16
  constructor(
17
17
  public readonly schemaName: string,
18
- private readonly connection: Connection,
19
18
  private readonly providers: UuidProvider,
20
19
  ) {}
21
20
 
22
- public create(connection?: Connection.ConnectionLike): DatabaseContext {
23
- const client = new Client(connection ?? this.connection, this.schemaName, { module: 'system' })
21
+ public create(connection: Connection.ConnectionLike): DatabaseContext {
22
+ const client = new Client(connection, this.schemaName, { module: 'system' })
24
23
  return createDatabaseContext(client, this.providers)
25
24
  }
26
25
  }
@@ -1,24 +1,23 @@
1
- import { SchemaDatabaseMetadata } from '@contember/schema-utils'
2
- import { SchemaDatabaseMetadataResolver } from './SchemaDatabaseMetadataResolver'
3
1
  import { DatabaseContext } from '../database'
2
+ import { DatabaseMetadata, DatabaseMetadataResolver } from '@contember/database'
4
3
 
5
4
  export class SchemaDatabaseMetadataResolverStore {
6
5
 
7
- private cache: Map<string, SchemaDatabaseMetadata> = new Map()
6
+ private cache: Map<string, DatabaseMetadata> = new Map()
8
7
 
9
8
  constructor(
10
- private resolver: SchemaDatabaseMetadataResolver,
9
+ private resolver: DatabaseMetadataResolver,
11
10
  private db: DatabaseContext,
12
11
  ) {
13
12
  }
14
13
 
15
- public async getMetadata(schema: string): Promise<SchemaDatabaseMetadata> {
14
+ public async getMetadata(schema: string): Promise<DatabaseMetadata> {
16
15
  const cached = this.cache.get(schema)
17
16
  if (cached) {
18
17
  return cached
19
18
  }
20
19
 
21
- const newValue = await this.resolver.resolveMetadata(this.db, schema)
20
+ const newValue = await this.resolver.resolveMetadata(this.db.client, schema)
22
21
  this.cache.set(schema, newValue)
23
22
  return newValue
24
23
  }
@@ -31,7 +30,7 @@ export class SchemaDatabaseMetadataResolverStore {
31
30
 
32
31
  export class MigrationsDatabaseMetadataResolverStoreFactory {
33
32
  constructor(
34
- private resolver: SchemaDatabaseMetadataResolver,
33
+ private resolver: DatabaseMetadataResolver,
35
34
  ) {
36
35
  }
37
36
 
@@ -1,3 +1 @@
1
- export * from './SchemaDatabaseMetadataResolver'
2
1
  export * from './SchemaDatabaseMetadataResolverStore'
3
- export { ResolvedDatabaseMetadata } from './ResolvedDatabaseMetadata'
@@ -1,15 +1,15 @@
1
+ import { emptyDatabaseMetadata } from '@contember/database'
1
2
  import migration from '../../../src/migrations/2020-05-06-150000-composed-primary'
2
3
  import { createMigrationBuilder } from '@contember/database-migrations'
3
4
  import { sampleProject } from '@contember/engine-api-tester'
4
5
  import { test, assert } from 'vitest'
5
- import { dummySchemaDatabaseMetadata } from '@contember/schema-utils'
6
6
 
7
7
  test('many-has-many-primary migration sql', async () => {
8
8
  const builder = createMigrationBuilder()
9
9
  await migration(builder, {
10
10
  connection: undefined as any,
11
11
  schemaResolver: () => Promise.resolve(sampleProject),
12
- databaseMetadataResolver: () => Promise.resolve(dummySchemaDatabaseMetadata),
12
+ databaseMetadataResolver: () => Promise.resolve(emptyDatabaseMetadata),
13
13
  project: {
14
14
  slug: 'test',
15
15
  stages: [
@@ -2,7 +2,7 @@ import migration from '../../../src/migrations/2020-06-01-103000-event-trigger-p
2
2
  import { createMigrationBuilder } from '@contember/database-migrations'
3
3
  import { sampleProject } from '@contember/engine-api-tester'
4
4
  import { test, assert } from 'vitest'
5
- import { dummySchemaDatabaseMetadata } from '@contember/schema-utils'
5
+ import { emptyDatabaseMetadata } from '@contember/database'
6
6
 
7
7
 
8
8
  test('event-trigger-performance sql', async () => {
@@ -10,7 +10,7 @@ test('event-trigger-performance sql', async () => {
10
10
  await migration(builder, {
11
11
  connection: undefined as any,
12
12
  schemaResolver: () => Promise.resolve(sampleProject),
13
- databaseMetadataResolver: () => Promise.resolve(dummySchemaDatabaseMetadata),
13
+ databaseMetadataResolver: () => Promise.resolve(emptyDatabaseMetadata),
14
14
  project: {
15
15
  slug: 'test',
16
16
  stages: [
@@ -2,9 +2,10 @@ import migration from '../../../src/migrations/2022-10-03-110000-table-on-delete
2
2
  import { createMigrationBuilder } from '@contember/database-migrations'
3
3
  import { assert, test } from 'vitest'
4
4
  import { SchemaBuilder } from '@contember/schema-definition'
5
- import { dummySchemaDatabaseMetadata, emptySchema } from '@contember/schema-utils'
5
+ import { emptySchema } from '@contember/schema-utils'
6
6
  import { Model } from '@contember/schema'
7
7
  import { createConnectionMock } from '@contember/database-tester'
8
+ import { ForeignKeyDeleteAction, createDatabaseMetadata, emptyDatabaseMetadata } from '@contember/database'
8
9
 
9
10
 
10
11
  test('table-on-delete test', async () => {
@@ -15,7 +16,20 @@ test('table-on-delete test', async () => {
15
16
  }])
16
17
  await migration(builder, {
17
18
  connection: connection,
18
- databaseMetadataResolver: () => Promise.resolve(dummySchemaDatabaseMetadata),
19
+ databaseMetadataResolver: () => Promise.resolve(createDatabaseMetadata({
20
+ indexes: [],
21
+ uniqueConstraints: [],
22
+ foreignKeys: [{
23
+ constraintName: 'fk_post_author_id_author_id',
24
+ fromColumn: 'author_id',
25
+ fromTable: 'post',
26
+ toColumn: 'id',
27
+ toTable: 'author',
28
+ deleteAction: ForeignKeyDeleteAction.restrict,
29
+ deferrable: false,
30
+ deferred: false,
31
+ }],
32
+ })),
19
33
  schemaResolver: () => Promise.resolve(({ ...emptySchema, model: new SchemaBuilder()
20
34
  .entity('Post', entity =>
21
35
  entity.manyHasOne('author', relation => relation.target('Author').onDelete(Model.OnDelete.setNull)),
@@ -0,0 +1,106 @@
1
+ import migration from '../../../src/migrations/2023-09-11-174000-fix-on-delete'
2
+ import { createMigrationBuilder } from '@contember/database-migrations'
3
+ import { assert, test } from 'vitest'
4
+ import { SchemaBuilder } from '@contember/schema-definition'
5
+ import { emptySchema } from '@contember/schema-utils'
6
+ import { Model } from '@contember/schema'
7
+ import { createConnectionMock } from '@contember/database-tester'
8
+ import { ForeignKeyDeleteAction, createDatabaseMetadata, emptyDatabaseMetadata } from '@contember/database'
9
+
10
+
11
+ test('table-on-delete test', async () => {
12
+ const builder = createMigrationBuilder()
13
+ const connection = createConnectionMock([{
14
+ sql: 'select schema from stage',
15
+ response: { rows: [{ schema: 'stage_live' }] },
16
+ }])
17
+ await migration(builder, {
18
+ connection: connection,
19
+ databaseMetadataResolver: () => Promise.resolve(createDatabaseMetadata({
20
+ indexes: [],
21
+ uniqueConstraints: [],
22
+ foreignKeys: [{
23
+ constraintName: 'fk_post_author_id_author_id',
24
+ fromColumn: 'author_id',
25
+ fromTable: 'post',
26
+ toColumn: 'id',
27
+ toTable: 'author',
28
+ deleteAction: ForeignKeyDeleteAction.cascade,
29
+ deferrable: false,
30
+ deferred: false,
31
+ }],
32
+ })),
33
+ schemaResolver: () => Promise.resolve(({ ...emptySchema, model: new SchemaBuilder()
34
+ .entity('Post', entity =>
35
+ entity.manyHasOne('author', relation => relation.target('Author').onDelete(Model.OnDelete.setNull)),
36
+ )
37
+ .entity('Author', entity => entity)
38
+ .buildSchema() })),
39
+ project: {
40
+ slug: 'test',
41
+ stages: [
42
+ {
43
+ slug: 'prod',
44
+ name: 'prod',
45
+ },
46
+ ],
47
+ },
48
+ })
49
+ assert.equal(
50
+ builder.getSql(),
51
+ `ALTER TABLE "stage_live"."post" DROP CONSTRAINT "fk_post_author_id_author_id";
52
+ ALTER TABLE "stage_live"."post"
53
+ ADD FOREIGN KEY ("author_id")
54
+ REFERENCES "stage_live"."author" ("id") ON DELETE SET NULL DEFERRABLE INITIALLY IMMEDIATE
55
+ ;
56
+ `,
57
+ )
58
+ })
59
+
60
+
61
+ test('table-on-delete test valid', async () => {
62
+ const builder = createMigrationBuilder()
63
+ const connection = createConnectionMock([{
64
+ sql: 'select schema from stage',
65
+ response: { rows: [{ schema: 'stage_live' }] },
66
+ }])
67
+ await migration(builder, {
68
+ connection: connection,
69
+ databaseMetadataResolver: () => Promise.resolve(createDatabaseMetadata({
70
+ indexes: [],
71
+ uniqueConstraints: [],
72
+ foreignKeys: [{
73
+ constraintName: 'fk_post_author_id_author_id',
74
+ fromColumn: 'author_id',
75
+ fromTable: 'post',
76
+ toColumn: 'id',
77
+ toTable: 'author',
78
+ deleteAction: ForeignKeyDeleteAction.setnull,
79
+ deferred: false,
80
+ deferrable: false,
81
+ }],
82
+ })),
83
+ schemaResolver: () => Promise.resolve(({
84
+ ...emptySchema, model: new SchemaBuilder()
85
+ .entity('Post', entity =>
86
+ entity.manyHasOne('author', relation => relation.target('Author').onDelete(Model.OnDelete.setNull)),
87
+ )
88
+ .entity('Author', entity => entity)
89
+ .buildSchema(),
90
+ })),
91
+ project: {
92
+ slug: 'test',
93
+ stages: [
94
+ {
95
+ slug: 'prod',
96
+ name: 'prod',
97
+ },
98
+ ],
99
+ },
100
+ })
101
+ assert.equal(
102
+ builder.getSql(),
103
+ `\n`,
104
+ )
105
+ })
106
+
@@ -2,8 +2,8 @@ import migration from '../../../src/migrations/2023-10-19-173000-fix-unique'
2
2
  import { createMigrationBuilder } from '@contember/database-migrations'
3
3
  import { assert, test } from 'vitest'
4
4
  import { c, createSchema } from '@contember/schema-definition'
5
- import { dummySchemaDatabaseMetadata } from '@contember/schema-utils'
6
5
  import { createConnectionMock } from '@contember/database-tester'
6
+ import { createDatabaseMetadata } from '@contember/database'
7
7
 
8
8
  namespace UniqueModel {
9
9
 
@@ -32,19 +32,19 @@ test('unique fix test', async () => {
32
32
  }])
33
33
  await migration(builder, {
34
34
  connection: connection,
35
- databaseMetadataResolver: () => Promise.resolve({
36
- ...dummySchemaDatabaseMetadata,
37
- getAllUniqueConstraints: () => [
38
- { constraintName: 'valid1', tableName: 'foo', columnNames: ['col_a', 'col_b'] },
39
- { constraintName: 'valid2', tableName: 'foo', columnNames: ['col_b', 'many_has_one_bar_id'] },
40
- { constraintName: 'valid3', tableName: 'foo', columnNames: ['single_col_unique'] },
41
- { constraintName: 'valid4', tableName: 'foo', columnNames: ['has_one_bar_id'] },
42
-
43
- { constraintName: 'invalid1', tableName: 'foo', columnNames: ['col_a', 'col_c'] },
44
- { constraintName: 'invalid2', tableName: 'foo', columnNames: ['col_c', 'many_has_one_bar_id'] },
35
+ databaseMetadataResolver: () => Promise.resolve(createDatabaseMetadata({
36
+ foreignKeys: [],
37
+ indexes: [],
38
+ uniqueConstraints: [
39
+ { constraintName: 'valid1', tableName: 'foo', columnNames: ['col_a', 'col_b'], deferrable: false, deferred: false },
40
+ { constraintName: 'valid2', tableName: 'foo', columnNames: ['col_b', 'many_has_one_bar_id'], deferrable: false, deferred: false },
41
+ { constraintName: 'valid3', tableName: 'foo', columnNames: ['single_col_unique'], deferrable: false, deferred: false },
42
+ { constraintName: 'valid4', tableName: 'foo', columnNames: ['has_one_bar_id'], deferrable: false, deferred: false },
43
+ { constraintName: 'invalid1', tableName: 'foo', columnNames: ['col_a', 'col_c'], deferrable: false, deferred: false },
44
+ { constraintName: 'invalid2', tableName: 'foo', columnNames: ['col_c', 'many_has_one_bar_id'], deferrable: false, deferred: false },
45
45
 
46
46
  ],
47
- }),
47
+ })),
48
48
  schemaResolver: () => Promise.resolve(createSchema(UniqueModel)),
49
49
  project: {
50
50
  slug: 'test',
@@ -1,14 +0,0 @@
1
- import { ForeignKeyConstraintMetadata, GetForeignKeyConstraintNameArgs, GetIndexNameArgs, GetUniqueConstraintNameArgs, IndexMetadata, SchemaDatabaseMetadata, UniqueConstraintMetadata } from '@contember/schema-utils';
2
- export declare class ResolvedDatabaseMetadata implements SchemaDatabaseMetadata {
3
- private readonly foreignKeys;
4
- private readonly uniqueConstraints;
5
- private readonly indexes;
6
- constructor(foreignKeys: ForeignKeyConstraintMetadata[], uniqueConstraints: UniqueConstraintMetadata[], indexes: IndexMetadata[]);
7
- getAllUniqueConstraints(): UniqueConstraintMetadata[];
8
- getUniqueConstraint(tableName: string, constraintName: string): UniqueConstraintMetadata | null;
9
- getForeignKeyConstraint(tableName: string, constraintName: string): ForeignKeyConstraintMetadata | null;
10
- getForeignKeyConstraintNames({ fromTable, fromColumn, toTable, toColumn }: GetForeignKeyConstraintNameArgs): string[];
11
- getUniqueConstraintNames({ tableName, columnNames }: GetUniqueConstraintNameArgs): string[];
12
- getIndexNames({ tableName, columnNames }: GetIndexNameArgs): string[];
13
- }
14
- //# sourceMappingURL=ResolvedDatabaseMetadata.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ResolvedDatabaseMetadata.d.ts","sourceRoot":"","sources":["../../../../src/model/metadata/ResolvedDatabaseMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,4BAA4B,EAC5B,+BAA+B,EAC/B,gBAAgB,EAChB,2BAA2B,EAC3B,aAAa,EACb,sBAAsB,EACtB,wBAAwB,EACxB,MAAM,yBAAyB,CAAA;AAWhC,qBAAa,wBAAyB,YAAW,sBAAsB;IAErE,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,WAAW,EAAE,4BAA4B,EAAE,EAC3C,iBAAiB,EAAE,wBAAwB,EAAE,EAC7C,OAAO,EAAE,aAAa,EAAE;IAI1C,uBAAuB,IAAI,wBAAwB,EAAE;IAIrD,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,wBAAwB,GAAG,IAAI;IAI/F,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,4BAA4B,GAAG,IAAI;IAIvG,4BAA4B,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,+BAA+B,GAAG,MAAM,EAAE;IAWrH,wBAAwB,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,2BAA2B,GAAG,MAAM,EAAE;IAM3F,aAAa,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,gBAAgB,GAAG,MAAM,EAAE;CAKrE"}