@contember/engine-system-api 1.1.2 → 1.2.0-alpha.11
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.
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -9
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrations/2020-05-06-150000-composed-primary.d.ts +2 -1
- package/dist/src/migrations/2020-05-06-150000-composed-primary.d.ts.map +1 -1
- package/dist/src/migrations/2020-05-06-150000-composed-primary.js +1 -1
- package/dist/src/migrations/2020-05-06-150000-composed-primary.js.map +1 -1
- package/dist/src/migrations/2020-06-01-103000-event-trigger-perf.d.ts +2 -1
- package/dist/src/migrations/2020-06-01-103000-event-trigger-perf.d.ts.map +1 -1
- package/dist/src/migrations/2020-06-01-103000-event-trigger-perf.js +1 -1
- package/dist/src/migrations/2020-06-01-103000-event-trigger-perf.js.map +1 -1
- package/dist/src/migrations/2021-05-07-155800-event-log-rework.d.ts +2 -1
- package/dist/src/migrations/2021-05-07-155800-event-log-rework.d.ts.map +1 -1
- package/dist/src/migrations/2021-05-07-155800-event-log-rework.js +1 -1
- package/dist/src/migrations/2021-05-07-155800-event-log-rework.js.map +1 -1
- package/dist/src/migrations/2021-05-19-1232000-event-log-fix-constraint.d.ts +2 -1
- package/dist/src/migrations/2021-05-19-1232000-event-log-fix-constraint.d.ts.map +1 -1
- package/dist/src/migrations/2021-05-19-1232000-event-log-fix-constraint.js +1 -1
- package/dist/src/migrations/2021-05-19-1232000-event-log-fix-constraint.js.map +1 -1
- package/dist/src/migrations/runner.d.ts +2 -1
- package/dist/src/migrations/runner.d.ts.map +1 -1
- package/dist/src/migrations/runner.js.map +1 -1
- package/dist/src/migrations/types.d.ts +2 -1
- package/dist/src/migrations/types.d.ts.map +1 -1
- package/dist/src/model/ProjectInitializer.d.ts +3 -4
- package/dist/src/model/ProjectInitializer.d.ts.map +1 -1
- package/dist/src/model/ProjectInitializer.js +20 -20
- package/dist/src/model/ProjectInitializer.js.map +1 -1
- package/dist/src/model/authorization/AuthorizationActions.d.ts +2 -0
- package/dist/src/model/authorization/AuthorizationActions.d.ts.map +1 -1
- package/dist/src/model/database/DatabaseContext.d.ts +1 -0
- package/dist/src/model/database/DatabaseContext.d.ts.map +1 -1
- package/dist/src/model/database/DatabaseContext.js +1 -0
- package/dist/src/model/database/DatabaseContext.js.map +1 -1
- package/dist/src/model/helpers/modelHelpers.js +1 -1
- package/dist/src/model/helpers/modelHelpers.js.map +1 -1
- package/dist/src/model/migrations/ProjectMigrator.d.ts +4 -1
- package/dist/src/model/migrations/ProjectMigrator.d.ts.map +1 -1
- package/dist/src/model/migrations/ProjectMigrator.js +16 -9
- package/dist/src/model/migrations/ProjectMigrator.js.map +1 -1
- package/dist/src/resolvers/ResolverFactory.d.ts +1 -1
- package/dist/src/resolvers/ResolverFactory.d.ts.map +1 -1
- package/dist/src/resolvers/mutation/MigrateMutationResolver.d.ts.map +1 -1
- package/dist/src/resolvers/mutation/MigrateMutationResolver.js +7 -3
- package/dist/src/resolvers/mutation/MigrateMutationResolver.js.map +1 -1
- package/dist/src/schema/types.d.ts +126 -141
- package/dist/src/schema/types.d.ts.map +1 -1
- package/dist/src/schema/types.js +6 -6
- package/dist/src/schema/types.js.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/tests/cases/migrations/2020-05-06-150000-composed-primary.test.js +1 -0
- package/dist/tests/cases/migrations/2020-05-06-150000-composed-primary.test.js.map +1 -1
- package/dist/tests/cases/migrations/2020-06-01-103000-event-trigger-perf.test.js +1 -0
- package/dist/tests/cases/migrations/2020-06-01-103000-event-trigger-perf.test.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/graphql.codegen.yml +0 -2
- package/package.json +20 -20
- package/src/index.ts +11 -10
- package/src/migrations/2020-05-06-150000-composed-primary.ts +3 -2
- package/src/migrations/2020-06-01-103000-event-trigger-perf.ts +3 -2
- package/src/migrations/2021-05-07-155800-event-log-rework.ts +3 -2
- package/src/migrations/2021-05-19-1232000-event-log-fix-constraint.ts +3 -2
- package/src/migrations/runner.ts +2 -1
- package/src/migrations/types.ts +2 -1
- package/src/model/ProjectInitializer.ts +26 -33
- package/src/model/database/DatabaseContext.ts +3 -1
- package/src/model/helpers/modelHelpers.ts +1 -1
- package/src/model/migrations/ProjectMigrator.ts +22 -14
- package/src/resolvers/mutation/MigrateMutationResolver.ts +8 -3
- package/src/schema/types.ts +126 -148
- package/tests/cases/migrations/2020-05-06-150000-composed-primary.test.ts +1 -0
- package/tests/cases/migrations/2020-06-01-103000-event-trigger-perf.test.ts +1 -0
package/graphql.codegen.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/engine-system-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-alpha.11",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"typings": "dist/src/index.d.ts",
|
|
@@ -9,28 +9,28 @@
|
|
|
9
9
|
"test": "vitest"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@contember/authorization": "^1.
|
|
13
|
-
"@contember/database": "^1.
|
|
14
|
-
"@contember/database-migrations": "^1.
|
|
15
|
-
"@contember/dic": "^1.
|
|
16
|
-
"@contember/engine-common": "^1.
|
|
17
|
-
"@contember/graphql-utils": "^1.
|
|
18
|
-
"@contember/queryable": "^1.
|
|
19
|
-
"@contember/schema": "^1.
|
|
20
|
-
"@contember/schema-migrations": "^1.
|
|
21
|
-
"@contember/schema-utils": "^1.
|
|
22
|
-
"@graphql-tools/utils": "^
|
|
12
|
+
"@contember/authorization": "^1.2.0-alpha.11",
|
|
13
|
+
"@contember/database": "^1.2.0-alpha.11",
|
|
14
|
+
"@contember/database-migrations": "^1.2.0-alpha.11",
|
|
15
|
+
"@contember/dic": "^1.2.0-alpha.11",
|
|
16
|
+
"@contember/engine-common": "^1.2.0-alpha.11",
|
|
17
|
+
"@contember/graphql-utils": "^1.2.0-alpha.11",
|
|
18
|
+
"@contember/queryable": "^1.2.0-alpha.11",
|
|
19
|
+
"@contember/schema": "^1.2.0-alpha.11",
|
|
20
|
+
"@contember/schema-migrations": "^1.2.0-alpha.11",
|
|
21
|
+
"@contember/schema-utils": "^1.2.0-alpha.11",
|
|
22
|
+
"@graphql-tools/utils": "^8.6.13",
|
|
23
23
|
"graphql-tag": "^2.12.5"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@contember/engine-api-tester": "^1.
|
|
27
|
-
"@contember/schema-definition": "^1.
|
|
28
|
-
"@graphql-codegen/cli": "^
|
|
29
|
-
"@graphql-codegen/typescript": "^
|
|
30
|
-
"@graphql-codegen/typescript-operations": "^
|
|
31
|
-
"@graphql-codegen/typescript-resolvers": "^
|
|
32
|
-
"@types/node": "^
|
|
33
|
-
"graphql": "^
|
|
26
|
+
"@contember/engine-api-tester": "^1.2.0-alpha.11",
|
|
27
|
+
"@contember/schema-definition": "^1.2.0-alpha.11",
|
|
28
|
+
"@graphql-codegen/cli": "^2.6.2",
|
|
29
|
+
"@graphql-codegen/typescript": "^2.5.1",
|
|
30
|
+
"@graphql-codegen/typescript-operations": "^2.4.2",
|
|
31
|
+
"@graphql-codegen/typescript-resolvers": "^2.6.6",
|
|
32
|
+
"@types/node": "^18",
|
|
33
|
+
"graphql": "^16.5.0",
|
|
34
34
|
"pg": "^8.5.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -3,21 +3,22 @@ export { SchemaMigrator, MigrationsResolver } from '@contember/schema-migrations
|
|
|
3
3
|
export { typeDefs, devTypeDefs, Schema } from './schema'
|
|
4
4
|
|
|
5
5
|
export {
|
|
6
|
-
Identity,
|
|
7
6
|
DatabaseContext,
|
|
8
|
-
|
|
9
|
-
StageBySlugQuery,
|
|
10
|
-
unnamedIdentity,
|
|
11
|
-
SchemaVersionBuilder,
|
|
7
|
+
DatabaseContextFactory,
|
|
12
8
|
formatSchemaName,
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
getJunctionTables,
|
|
10
|
+
Identity,
|
|
15
11
|
LatestTransactionIdByStageQuery,
|
|
16
|
-
|
|
12
|
+
ProjectInitializer,
|
|
17
13
|
ProjectMigrator,
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
SchemaVersionBuilder,
|
|
15
|
+
setupSystemVariables,
|
|
20
16
|
Stage,
|
|
17
|
+
StageBySlugQuery,
|
|
18
|
+
StageCreator,
|
|
19
|
+
StagesQuery,
|
|
20
|
+
unnamedIdentity,
|
|
21
|
+
VersionedSchema,
|
|
21
22
|
} from './model'
|
|
22
23
|
export * from './SystemContainer'
|
|
23
24
|
export * from './resolvers'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { escapeValue, MigrationBuilder, Name } from '@contember/database-migrations'
|
|
2
2
|
import { SystemMigrationArgs } from './types'
|
|
3
3
|
import { getJunctionTables } from '../model'
|
|
4
|
+
import { MigrationArgs } from '@contember/database-migrations/dist/src/Migration'
|
|
4
5
|
|
|
5
6
|
const createEventTrigger = (builder: MigrationBuilder, tableName: Name, primaryColumns: string[]) => {
|
|
6
7
|
builder.createTrigger(tableName, 'log_event', {
|
|
@@ -56,8 +57,8 @@ const migrateEvents = (builder: MigrationBuilder, tableName: string, primaryKeys
|
|
|
56
57
|
`)
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
export default async function (builder: MigrationBuilder, args: SystemMigrationArgs) {
|
|
60
|
-
const schema = await args.schemaResolver()
|
|
60
|
+
export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
|
|
61
|
+
const schema = await args.schemaResolver(args.connection)
|
|
61
62
|
const tablesToMigrate = getJunctionTables(schema.model)
|
|
62
63
|
const schemas = args.project.stages.map(it => `stage_${it.slug}`)
|
|
63
64
|
for (const table of tablesToMigrate) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MigrationBuilder, Name } from '@contember/database-migrations'
|
|
2
2
|
import { SystemMigrationArgs } from './types'
|
|
3
3
|
import { getJunctionTables } from '../model'
|
|
4
|
+
import { MigrationArgs } from '@contember/database-migrations/dist/src/Migration'
|
|
4
5
|
|
|
5
6
|
const createEventStatementTrigger = (builder: MigrationBuilder, tableName: Name) => {
|
|
6
7
|
builder.createTrigger(tableName, 'log_event_statement', {
|
|
@@ -14,8 +15,8 @@ const createEventStatementTrigger = (builder: MigrationBuilder, tableName: Name)
|
|
|
14
15
|
})
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export default async function (builder: MigrationBuilder, args: SystemMigrationArgs) {
|
|
18
|
-
const schema = await args.schemaResolver()
|
|
18
|
+
export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
|
|
19
|
+
const schema = await args.schemaResolver(args.connection)
|
|
19
20
|
const junctionTables = getJunctionTables(schema.model)
|
|
20
21
|
const schemas = args.project.stages.map(it => `stage_${it.slug}`)
|
|
21
22
|
builder.sql(`CREATE OR REPLACE FUNCTION "trigger_event"() RETURNS TRIGGER AS $$
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MigrationBuilder, Name } from '@contember/database-migrations'
|
|
2
2
|
import { SystemMigrationArgs } from './types'
|
|
3
3
|
import { getJunctionTables } from '../model'
|
|
4
|
+
import { MigrationArgs } from '@contember/database-migrations/dist/src/Migration'
|
|
4
5
|
|
|
5
6
|
const createTrxEvent = (builder: MigrationBuilder, tableName: Name) => {
|
|
6
7
|
builder.createTrigger(tableName, 'log_event_trx', {
|
|
@@ -16,8 +17,8 @@ const createTrxEvent = (builder: MigrationBuilder, tableName: Name) => {
|
|
|
16
17
|
})
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
export default async function (builder: MigrationBuilder, args: SystemMigrationArgs) {
|
|
20
|
-
const schema = await args.schemaResolver()
|
|
20
|
+
export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
|
|
21
|
+
const schema = await args.schemaResolver(args.connection)
|
|
21
22
|
const junctionTables = getJunctionTables(schema.model)
|
|
22
23
|
const schemas = args.project.stages.map(it => `stage_${it.slug}`)
|
|
23
24
|
builder.sql(`LOCK TABLE event`)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MigrationBuilder, Name } from '@contember/database-migrations'
|
|
2
2
|
import { SystemMigrationArgs } from './types'
|
|
3
3
|
import { getJunctionTables } from '../model'
|
|
4
|
+
import { MigrationArgs } from '@contember/database-migrations'
|
|
4
5
|
|
|
5
6
|
const recreateTrigger = (builder: MigrationBuilder, tableName: Name) => {
|
|
6
7
|
builder.dropTrigger(tableName, 'log_event_trx', { ifExists: true })
|
|
@@ -19,8 +20,8 @@ const recreateTrigger = (builder: MigrationBuilder, tableName: Name) => {
|
|
|
19
20
|
})
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export default async function (builder: MigrationBuilder, args: SystemMigrationArgs) {
|
|
23
|
-
const schema = await args.schemaResolver()
|
|
23
|
+
export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
|
|
24
|
+
const schema = await args.schemaResolver(args.connection)
|
|
24
25
|
const junctionTables = getJunctionTables(schema.model)
|
|
25
26
|
const schemas = args.project.stages.map(it => `stage_${it.slug}`)
|
|
26
27
|
|
package/src/migrations/runner.ts
CHANGED
|
@@ -4,8 +4,9 @@ import composedPrimary from './2020-05-06-150000-composed-primary'
|
|
|
4
4
|
import eventTriggerPerf from './2020-06-01-103000-event-trigger-perf'
|
|
5
5
|
import eventLogRework from './2021-05-07-155800-event-log-rework'
|
|
6
6
|
import eventLogFixConstraint from './2021-05-19-1232000-event-log-fix-constraint'
|
|
7
|
+
import { SystemMigrationArgs } from './types'
|
|
7
8
|
|
|
8
|
-
export const getSystemMigrations = (): Promise<Migration[]> => {
|
|
9
|
+
export const getSystemMigrations = (): Promise<Migration<SystemMigrationArgs>[]> => {
|
|
9
10
|
return loadMigrations(process.env.CONTEMBER_SYSTEM_MIGRATIONS_DIR || __dirname, [
|
|
10
11
|
new Migration('2020-03-27-130000-project-migrations', projectMigrations),
|
|
11
12
|
new Migration('2020-05-06-150000-composed-primary', composedPrimary),
|
package/src/migrations/types.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Schema } from '@contember/schema'
|
|
2
2
|
import { ProjectConfig } from '../types'
|
|
3
|
+
import { Connection } from '@contember/database'
|
|
3
4
|
|
|
4
5
|
export interface SystemMigrationArgs {
|
|
5
|
-
schemaResolver: () => Promise<Schema>
|
|
6
|
+
schemaResolver: (connection: Connection.ConnectionLike) => Promise<Schema>
|
|
6
7
|
project: ProjectConfig
|
|
7
8
|
}
|
|
@@ -4,15 +4,13 @@ import { StageCreator } from './stages'
|
|
|
4
4
|
import { DatabaseContext, DatabaseContextFactory } from './database'
|
|
5
5
|
import { SystemDbMigrationsRunnerFactory } from '../SystemContainer'
|
|
6
6
|
import {
|
|
7
|
+
Client,
|
|
7
8
|
Connection,
|
|
8
9
|
createDatabaseIfNotExists,
|
|
9
|
-
|
|
10
|
+
DatabaseConfig,
|
|
10
11
|
retryTransaction,
|
|
11
|
-
SingleConnection,
|
|
12
12
|
} from '@contember/database'
|
|
13
13
|
import { Logger } from '@contember/engine-common'
|
|
14
|
-
import { Migration } from '@contember/schema-migrations'
|
|
15
|
-
import { StagesQuery } from './queries'
|
|
16
14
|
|
|
17
15
|
export class ProjectInitializer {
|
|
18
16
|
constructor(
|
|
@@ -24,45 +22,46 @@ export class ProjectInitializer {
|
|
|
24
22
|
|
|
25
23
|
public async initialize(
|
|
26
24
|
databaseContextFactory: DatabaseContextFactory,
|
|
27
|
-
project: ProjectConfig & { db?:
|
|
25
|
+
project: ProjectConfig & { db?: DatabaseConfig },
|
|
28
26
|
logger: Logger,
|
|
29
|
-
migrations?: Migration[],
|
|
30
27
|
) {
|
|
31
28
|
const dbContext = databaseContextFactory.create()
|
|
32
29
|
if (project.db) {
|
|
33
30
|
// todo: use dbContext
|
|
34
31
|
logger.group(`Executing system schema migration`)
|
|
35
32
|
await createDatabaseIfNotExists(project.db, logger.write.bind(logger))
|
|
36
|
-
const singleConnection =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.withClient(singleConnection.createClient(systemSchema, { module: 'system' }))
|
|
40
|
-
.create()
|
|
33
|
+
const singleConnection = Connection.createSingle(project.db)
|
|
34
|
+
await singleConnection.scope(async connection => {
|
|
35
|
+
const systemSchema = dbContext.client.schema
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
37
|
+
const schemaResolver = (connection: Connection.ConnectionLike) => {
|
|
38
|
+
const dbContextMigrations = databaseContextFactory
|
|
39
|
+
.withClient(new Client(connection, systemSchema, { module: 'system' }))
|
|
40
|
+
.create()
|
|
41
|
+
return this.schemaVersionBuilder.buildSchema(dbContextMigrations)
|
|
42
|
+
}
|
|
43
|
+
await this.systemDbMigrationsRunnerFactory(connection, systemSchema).migrate(
|
|
44
|
+
logger.write.bind(logger),
|
|
45
|
+
{
|
|
46
|
+
schemaResolver,
|
|
47
|
+
project,
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
})
|
|
50
51
|
await singleConnection.end()
|
|
51
52
|
logger.groupEnd()
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
await retryTransaction(() =>
|
|
54
55
|
dbContext.transaction(async trx => {
|
|
55
|
-
await this.initStages(trx, project, logger
|
|
56
|
+
await this.initStages(trx, project, logger)
|
|
56
57
|
}),
|
|
57
58
|
)
|
|
59
|
+
if (dbContext.client.connection instanceof Connection) {
|
|
60
|
+
await dbContext.client.connection.clearPool()
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
private async initStages(
|
|
61
|
-
db: DatabaseContext<Connection.TransactionLike>,
|
|
62
|
-
project: ProjectConfig,
|
|
63
|
-
logger: Logger,
|
|
64
|
-
migrations?: Migration[],
|
|
65
|
-
) {
|
|
64
|
+
private async initStages(db: DatabaseContext<Connection.TransactionLike>, project: ProjectConfig, logger: Logger) {
|
|
66
65
|
|
|
67
66
|
logger.group(`Creating stages`)
|
|
68
67
|
|
|
@@ -76,11 +75,5 @@ export class ProjectInitializer {
|
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
logger.groupEnd()
|
|
79
|
-
if (migrations) {
|
|
80
|
-
logger.group(`Executing project migrations`)
|
|
81
|
-
const stages = await db.queryHandler.fetch(new StagesQuery())
|
|
82
|
-
await this.projectMigrator.migrate(db, stages, migrations, logger.write.bind(logger))
|
|
83
|
-
logger.groupEnd()
|
|
84
|
-
}
|
|
85
78
|
}
|
|
86
79
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Client, Connection, DatabaseQueryable } from '@contember/database'
|
|
1
|
+
import { Client, Connection, DatabaseQueryable, withDatabaseAdvisoryLock } from '@contember/database'
|
|
2
2
|
import { QueryHandler } from '@contember/queryable'
|
|
3
3
|
import { UuidProvider } from '../../utils'
|
|
4
4
|
import { CommandBus } from '../commands'
|
|
@@ -7,6 +7,7 @@ export interface DatabaseContext<ConnectionType extends Connection.ConnectionLik
|
|
|
7
7
|
client: Client<ConnectionType>
|
|
8
8
|
queryHandler: QueryHandler<DatabaseQueryable>
|
|
9
9
|
transaction: <T>(cb: (db: DatabaseContext<Connection.TransactionLike>) => Promise<T> | T) => Promise<T>
|
|
10
|
+
locked: <T>(lock: number, cb: (db: DatabaseContext<Connection.ConnectionLike>) => Promise<T> | T) => Promise<T>
|
|
10
11
|
commandBus: CommandBus
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -34,4 +35,5 @@ const createDatabaseContext = <ConnectionType extends Connection.ConnectionLike
|
|
|
34
35
|
return cb(createDatabaseContext(client, providers))
|
|
35
36
|
}),
|
|
36
37
|
commandBus: new CommandBus(client, providers),
|
|
38
|
+
locked: (lock, cb) => client.locked(lock, client => cb(createDatabaseContext(client, providers))),
|
|
37
39
|
})
|
|
@@ -5,7 +5,7 @@ export const getJunctionTables = (model: Model.Schema): Model.JoiningTable[] =>
|
|
|
5
5
|
const tables: Model.JoiningTable[] = []
|
|
6
6
|
Object.values(model.entities).forEach(entity => {
|
|
7
7
|
acceptEveryFieldVisitor(model, entity, {
|
|
8
|
-
visitManyHasManyOwning: ({
|
|
8
|
+
visitManyHasManyOwning: ({ relation }) => {
|
|
9
9
|
tables.push(relation.joiningTable)
|
|
10
10
|
},
|
|
11
11
|
visitColumn: () => {},
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Migration, MigrationDescriber } from '@contember/schema-migrations'
|
|
1
|
+
import { calculateMigrationChecksum, Migration, MigrationDescriber } from '@contember/schema-migrations'
|
|
2
2
|
import { Client, QueryError, wrapIdentifier } from '@contember/database'
|
|
3
|
-
import { formatSchemaName } from '../helpers'
|
|
4
3
|
import { Schema } from '@contember/schema'
|
|
5
4
|
import { SaveMigrationCommand } from '../commands'
|
|
6
5
|
import { Stage } from '../dtos'
|
|
@@ -21,19 +20,20 @@ export class ProjectMigrator {
|
|
|
21
20
|
db: DatabaseContext,
|
|
22
21
|
stages: Stage[],
|
|
23
22
|
migrationsToExecute: readonly Migration[],
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
{ ignoreOrder = false, skipExecuted = false }: {
|
|
24
|
+
ignoreOrder?: boolean
|
|
25
|
+
skipExecuted?: boolean
|
|
26
|
+
},
|
|
26
27
|
) {
|
|
27
28
|
if (migrationsToExecute.length === 0) {
|
|
28
29
|
return
|
|
29
30
|
}
|
|
30
31
|
let { version, notNormalized, ...schema } = await this.schemaVersionBuilder.buildSchema(db)
|
|
31
|
-
await this.validateMigrations(db, schema, version, migrationsToExecute, ignoreOrder)
|
|
32
|
+
const validated = await this.validateMigrations(db, schema, version, migrationsToExecute, { ignoreOrder, skipExecuted })
|
|
32
33
|
|
|
33
|
-
const sorted = [...
|
|
34
|
+
const sorted = [...validated].sort((a, b) => a.version.localeCompare(b.version))
|
|
34
35
|
|
|
35
36
|
for (const migration of sorted) {
|
|
36
|
-
logger(`Executing migration ${migration.name}...`)
|
|
37
37
|
const formatVersion = migration.formatVersion
|
|
38
38
|
|
|
39
39
|
for (const modification of migration.modifications) {
|
|
@@ -48,10 +48,7 @@ export class ProjectMigrator {
|
|
|
48
48
|
)
|
|
49
49
|
}
|
|
50
50
|
await db.commandBus.execute(new SaveMigrationCommand(migration))
|
|
51
|
-
logger(`Done`)
|
|
52
51
|
}
|
|
53
|
-
|
|
54
|
-
logger(`Done`)
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
private async validateMigrations(
|
|
@@ -59,12 +56,21 @@ export class ProjectMigrator {
|
|
|
59
56
|
schema: Schema,
|
|
60
57
|
version: string,
|
|
61
58
|
migrationsToExecute: readonly Migration[],
|
|
62
|
-
ignoreOrder
|
|
63
|
-
|
|
59
|
+
{ ignoreOrder, skipExecuted }: {
|
|
60
|
+
ignoreOrder: boolean
|
|
61
|
+
skipExecuted: boolean
|
|
62
|
+
},
|
|
63
|
+
): Promise<readonly Migration[]> {
|
|
64
64
|
const executedMigrations = await this.executedMigrationsResolver.getMigrations(db)
|
|
65
|
+
const toExecute = []
|
|
65
66
|
for (const migration of migrationsToExecute) {
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
const executedMigration = executedMigrations.find(it => it.version === migration.version)
|
|
68
|
+
if (executedMigration) {
|
|
69
|
+
if (skipExecuted && executedMigration.checksum === calculateMigrationChecksum(migration)) {
|
|
70
|
+
continue
|
|
71
|
+
} else {
|
|
72
|
+
throw new AlreadyExecutedMigrationError(migration.version, `Migration is already executed`)
|
|
73
|
+
}
|
|
68
74
|
}
|
|
69
75
|
if (migration.version < version && !ignoreOrder) {
|
|
70
76
|
throw new MustFollowLatestMigrationError(migration.version, `Must follow latest executed migration ${version}`)
|
|
@@ -83,7 +89,9 @@ export class ProjectMigrator {
|
|
|
83
89
|
errors.map(it => it.path.join('.') + ': ' + it.message).join('\n'),
|
|
84
90
|
)
|
|
85
91
|
}
|
|
92
|
+
toExecute.push(migration)
|
|
86
93
|
}
|
|
94
|
+
return toExecute
|
|
87
95
|
}
|
|
88
96
|
|
|
89
97
|
private async applyModification(
|
|
@@ -5,6 +5,8 @@ import { MigrateResponse, MutationMigrateArgs } from '../../schema'
|
|
|
5
5
|
import { Migration } from '@contember/schema-migrations'
|
|
6
6
|
import { AuthorizationActions, MigrationError, ProjectMigrator, StagesQuery } from '../../model'
|
|
7
7
|
|
|
8
|
+
const pg_lock_id = 1597474138739147
|
|
9
|
+
|
|
8
10
|
export class MigrateMutationResolver implements MutationResolver<'migrate'> {
|
|
9
11
|
constructor(private readonly projectMigrator: ProjectMigrator) {}
|
|
10
12
|
|
|
@@ -26,13 +28,16 @@ export class MigrateMutationResolver implements MutationResolver<'migrate'> {
|
|
|
26
28
|
): Promise<MigrateResponse> {
|
|
27
29
|
const migrations = args.migrations as readonly Migration[]
|
|
28
30
|
|
|
29
|
-
return context.db.transaction(async trx => {
|
|
31
|
+
return context.db.locked(pg_lock_id, db => db.transaction(async trx => {
|
|
30
32
|
const stages = await trx.queryHandler.fetch(new StagesQuery())
|
|
31
33
|
for (const stage of stages) {
|
|
32
34
|
await context.requireAccess(AuthorizationActions.PROJECT_MIGRATE, stage.slug)
|
|
33
35
|
}
|
|
34
36
|
try {
|
|
35
|
-
await this.projectMigrator.migrate(trx, stages, migrations,
|
|
37
|
+
await this.projectMigrator.migrate(trx, stages, migrations, {
|
|
38
|
+
ignoreOrder: force,
|
|
39
|
+
skipExecuted: true,
|
|
40
|
+
})
|
|
36
41
|
} catch (e) {
|
|
37
42
|
if (e instanceof MigrationError) {
|
|
38
43
|
await trx.client.connection.rollback()
|
|
@@ -54,6 +59,6 @@ export class MigrateMutationResolver implements MutationResolver<'migrate'> {
|
|
|
54
59
|
ok: true,
|
|
55
60
|
errors: [],
|
|
56
61
|
}
|
|
57
|
-
})
|
|
62
|
+
}))
|
|
58
63
|
}
|
|
59
64
|
}
|