@contember/engine-system-api 2.1.0-alpha.1 → 2.1.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.
- package/dist/development/src/migrations/2025-03-14-110000-fix-missing-index.cjs +60 -0
- package/dist/development/src/migrations/2025-03-14-110000-fix-missing-index.cjs.map +1 -0
- package/dist/development/src/migrations/2025-03-14-110000-fix-missing-index.js +61 -0
- package/dist/development/src/migrations/2025-03-14-110000-fix-missing-index.js.map +1 -0
- package/dist/development/src/migrations/runner.cjs +3 -1
- package/dist/development/src/migrations/runner.cjs.map +1 -1
- package/dist/development/src/migrations/runner.js +3 -1
- package/dist/development/src/migrations/runner.js.map +1 -1
- package/dist/development/src/model/queries/events/LatestTransactionIdByStageQuery.cjs +1 -5
- package/dist/development/src/model/queries/events/LatestTransactionIdByStageQuery.cjs.map +1 -1
- package/dist/development/src/model/queries/events/LatestTransactionIdByStageQuery.js +1 -5
- package/dist/development/src/model/queries/events/LatestTransactionIdByStageQuery.js.map +1 -1
- package/dist/production/src/migrations/2025-03-14-110000-fix-missing-index.cjs +60 -0
- package/dist/production/src/migrations/2025-03-14-110000-fix-missing-index.cjs.map +1 -0
- package/dist/production/src/migrations/2025-03-14-110000-fix-missing-index.js +61 -0
- package/dist/production/src/migrations/2025-03-14-110000-fix-missing-index.js.map +1 -0
- package/dist/production/src/migrations/runner.cjs +3 -1
- package/dist/production/src/migrations/runner.cjs.map +1 -1
- package/dist/production/src/migrations/runner.js +3 -1
- package/dist/production/src/migrations/runner.js.map +1 -1
- package/dist/production/src/model/queries/events/LatestTransactionIdByStageQuery.cjs +1 -5
- package/dist/production/src/model/queries/events/LatestTransactionIdByStageQuery.cjs.map +1 -1
- package/dist/production/src/model/queries/events/LatestTransactionIdByStageQuery.js +1 -5
- package/dist/production/src/model/queries/events/LatestTransactionIdByStageQuery.js.map +1 -1
- package/dist/tests/cases/migrations/2025-03-14-110000-fix-missing-index.test.d.ts +2 -0
- package/dist/tests/cases/migrations/2025-03-14-110000-fix-missing-index.test.d.ts.map +1 -0
- package/dist/tests/src/uuid.d.ts.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/migrations/2025-03-14-110000-fix-missing-index.d.ts +4 -0
- package/dist/types/migrations/2025-03-14-110000-fix-missing-index.d.ts.map +1 -0
- package/dist/types/migrations/runner.d.ts.map +1 -1
- package/dist/types/migrations/snapshot-factory.d.ts.map +1 -1
- package/dist/types/model/events/EventResponseHelper.d.ts.map +1 -1
- package/dist/types/model/events/identityUtils.d.ts.map +1 -1
- package/dist/types/model/helpers/modelHelpers.d.ts.map +1 -1
- package/dist/types/model/queries/events/EventQueryHelpers.d.ts.map +1 -1
- package/dist/types/model/queries/events/LatestTransactionIdByStageQuery.d.ts +2 -2
- package/dist/types/model/queries/events/LatestTransactionIdByStageQuery.d.ts.map +1 -1
- package/dist/types/model/queries/migrations/ExecutedMigrationsQueryHelper.d.ts.map +1 -1
- package/dist/types/resolvers/types/OldValuesHelpers.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/utils/batchQuery.d.ts.map +1 -1
- package/dist/types/utils/tuple.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/migrations/2025-03-14-110000-fix-missing-index.ts +68 -0
- package/src/migrations/runner.ts +2 -0
- package/src/model/queries/events/LatestTransactionIdByStageQuery.ts +3 -7
- package/tests/cases/migrations/2025-03-14-110000-fix-missing-index.test.ts +62 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchQuery.d.ts","sourceRoot":"","sources":["../../../src/utils/batchQuery.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEhE,eAAO,MAAM,iBAAiB,GAAI,GAAG,EAAE,MAAM,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"batchQuery.d.ts","sourceRoot":"","sources":["../../../src/utils/batchQuery.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEhE,eAAO,MAAM,iBAAiB,GAAI,GAAG,EAAE,MAAM,EAAE,IAAI,EAClD,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,EAC9C,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,KACzC,UAAU,CAAC,GAAG,EAAE,IAAI,CAiBtB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tuple.d.ts","sourceRoot":"","sources":["../../../src/utils/tuple.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"tuple.d.ts","sourceRoot":"","sources":["../../../src/utils/tuple.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,GAAG,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAW,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/engine-system-api",
|
|
3
|
-
"version": "2.1.0-alpha.
|
|
3
|
+
"version": "2.1.0-alpha.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/production/index.js",
|
|
6
6
|
"typings": "./dist/types/index.d.ts",
|
|
@@ -23,22 +23,22 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@contember/authorization": "2.1.0-alpha.
|
|
27
|
-
"@contember/database": "2.1.0-alpha.
|
|
28
|
-
"@contember/database-migrations": "2.1.0-alpha.
|
|
29
|
-
"@contember/dic": "2.1.0-alpha.
|
|
30
|
-
"@contember/graphql-utils": "2.1.0-alpha.
|
|
31
|
-
"@contember/logger": "2.1.0-alpha.
|
|
32
|
-
"@contember/queryable": "2.1.0-alpha.
|
|
33
|
-
"@contember/schema": "2.1.0-alpha.
|
|
34
|
-
"@contember/schema-migrations": "2.1.0-alpha.
|
|
35
|
-
"@contember/schema-utils": "2.1.0-alpha.
|
|
26
|
+
"@contember/authorization": "2.1.0-alpha.2",
|
|
27
|
+
"@contember/database": "2.1.0-alpha.2",
|
|
28
|
+
"@contember/database-migrations": "2.1.0-alpha.2",
|
|
29
|
+
"@contember/dic": "2.1.0-alpha.2",
|
|
30
|
+
"@contember/graphql-utils": "2.1.0-alpha.2",
|
|
31
|
+
"@contember/logger": "2.1.0-alpha.2",
|
|
32
|
+
"@contember/queryable": "2.1.0-alpha.2",
|
|
33
|
+
"@contember/schema": "2.1.0-alpha.2",
|
|
34
|
+
"@contember/schema-migrations": "2.1.0-alpha.2",
|
|
35
|
+
"@contember/schema-utils": "2.1.0-alpha.2",
|
|
36
36
|
"@graphql-tools/utils": "^10.5.5",
|
|
37
37
|
"graphql-tag": "^2.12.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@contember/schema-definition": "2.1.0-alpha.
|
|
41
|
-
"@types/node": "^20.
|
|
40
|
+
"@contember/schema-definition": "2.1.0-alpha.2",
|
|
41
|
+
"@types/node": "^20.17.22",
|
|
42
42
|
"graphql": "^16.9.0",
|
|
43
43
|
"pg": "^8.12.0"
|
|
44
44
|
},
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { MigrationArgs, MigrationBuilder } from '@contember/database-migrations'
|
|
2
|
+
import { DatabaseMetadata } from '@contember/database'
|
|
3
|
+
import { SystemMigrationArgs } from './types'
|
|
4
|
+
import { wrapIdentifier } from '@contember/database'
|
|
5
|
+
import { Model } from '@contember/schema'
|
|
6
|
+
import { acceptFieldVisitor } from '@contember/schema-utils'
|
|
7
|
+
|
|
8
|
+
export default async function (builder: MigrationBuilder, args: MigrationArgs<SystemMigrationArgs>) {
|
|
9
|
+
const schema = (await args.schemaResolver(args.connection)).schema
|
|
10
|
+
const stages = (await args.connection.query<{schema: string}>('SELECT schema FROM stage')).rows
|
|
11
|
+
const metadataByStage: Record<string, DatabaseMetadata> = {}
|
|
12
|
+
|
|
13
|
+
for (const entity of Object.values(schema.model.entities)) {
|
|
14
|
+
if (entity.indexes.length === 0) {
|
|
15
|
+
continue
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
for (const stage of stages) {
|
|
19
|
+
const databaseMetadata = metadataByStage[stage.schema] ??= await args.databaseMetadataResolver(args.connection, stage.schema)
|
|
20
|
+
|
|
21
|
+
for (const index of entity.indexes) {
|
|
22
|
+
const columns = getIndexColumns({
|
|
23
|
+
entity,
|
|
24
|
+
fields: index.fields,
|
|
25
|
+
model: schema.model,
|
|
26
|
+
})
|
|
27
|
+
const indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns }).getNames()
|
|
28
|
+
if (indexNames.length > 0) {
|
|
29
|
+
continue
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const tableNameId = wrapIdentifier(entity.tableName)
|
|
33
|
+
const columnNameIds = columns.map(wrapIdentifier)
|
|
34
|
+
|
|
35
|
+
builder.sql(`CREATE INDEX ON ${wrapIdentifier(stage.schema)}.${tableNameId} (${columnNameIds.join(', ')})`)
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const getIndexColumns = ({ entity, fields, model }: { fields: readonly string[]; model: Model.Schema; entity: Model.Entity }) => {
|
|
43
|
+
return fields.map(fieldName => {
|
|
44
|
+
return acceptFieldVisitor(model, entity, fieldName, {
|
|
45
|
+
visitColumn: ({ column }) => {
|
|
46
|
+
return column.columnName
|
|
47
|
+
},
|
|
48
|
+
visitManyHasOne: ({ relation }) => {
|
|
49
|
+
return relation.joiningColumn.columnName
|
|
50
|
+
},
|
|
51
|
+
visitOneHasOneOwning: ({ relation }) => {
|
|
52
|
+
return relation.joiningColumn.columnName
|
|
53
|
+
},
|
|
54
|
+
visitOneHasMany: () => {
|
|
55
|
+
throw new Error(`Cannot create index on 1:m relation in ${entity.name}.${fieldName}`)
|
|
56
|
+
},
|
|
57
|
+
visitOneHasOneInverse: () => {
|
|
58
|
+
throw new Error(`Cannot create index on 1:1 inverse relation in ${entity.name}.${fieldName}`)
|
|
59
|
+
},
|
|
60
|
+
visitManyHasManyOwning: () => {
|
|
61
|
+
throw new Error(`Cannot create index on m:m relation in ${entity.name}.${fieldName}`)
|
|
62
|
+
},
|
|
63
|
+
visitManyHasManyInverse: () => {
|
|
64
|
+
throw new Error(`Cannot create index on m:m inverse relation in ${entity.name}.${fieldName}`)
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
}
|
package/src/migrations/runner.ts
CHANGED
|
@@ -29,6 +29,7 @@ import _20240628150000migrationsdropsequence from './2024-06-28-150000-migration
|
|
|
29
29
|
import _20240628153000schema from './2024-06-28-153000-schema'
|
|
30
30
|
import _20240628153001schemainit from './2024-06-28-153001-schema-init'
|
|
31
31
|
import _20240729150000eventdataindex from './2024-07-29-150000-event-data-index'
|
|
32
|
+
import _20250314110000fixmissingindex from './2025-03-14-110000-fix-missing-index'
|
|
32
33
|
import snapshot from './snapshot'
|
|
33
34
|
|
|
34
35
|
import { Connection, createDatabaseIfNotExists, DatabaseConfig, DatabaseMetadataResolver } from '@contember/database'
|
|
@@ -62,6 +63,7 @@ const migrations = {
|
|
|
62
63
|
'2024-06-28-153000-schema': _20240628153000schema,
|
|
63
64
|
'2024-06-28-153001-schema-init': _20240628153001schemainit,
|
|
64
65
|
'2024-07-29-150000-event-data-index': _20240729150000eventdataindex,
|
|
66
|
+
'2025-03-14-110000-fix-missing-index': _20250314110000fixmissingindex,
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { DatabaseQuery, DatabaseQueryable, SelectBuilder } from '@contember/database'
|
|
2
|
-
import { ImplementationException } from '../../../utils'
|
|
3
2
|
|
|
4
|
-
export class LatestTransactionIdByStageQuery extends DatabaseQuery<string> {
|
|
3
|
+
export class LatestTransactionIdByStageQuery extends DatabaseQuery<string | null> {
|
|
5
4
|
constructor(private readonly stageId: string) {
|
|
6
5
|
super()
|
|
7
6
|
}
|
|
8
7
|
|
|
9
|
-
async fetch(queryable: DatabaseQueryable): Promise<string> {
|
|
8
|
+
async fetch(queryable: DatabaseQueryable): Promise<string | null> {
|
|
10
9
|
const rows = await SelectBuilder.create<{ transaction_id: string }>()
|
|
11
10
|
.from('stage_transaction')
|
|
12
11
|
.select('transaction_id')
|
|
@@ -15,9 +14,6 @@ export class LatestTransactionIdByStageQuery extends DatabaseQuery<string> {
|
|
|
15
14
|
.limit(1)
|
|
16
15
|
.getResult(queryable.db)
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
throw new ImplementationException()
|
|
20
|
-
}
|
|
21
|
-
return rows[0].transaction_id
|
|
17
|
+
return rows.length === 0 ? null : rows[0].transaction_id
|
|
22
18
|
}
|
|
23
19
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import migration from '../../../src/migrations/2025-03-14-110000-fix-missing-index'
|
|
2
|
+
import { createMigrationBuilder } from '@contember/database-migrations'
|
|
3
|
+
import { expect, test } from 'bun:test'
|
|
4
|
+
import { c, createSchema } from '@contember/schema-definition'
|
|
5
|
+
import { createConnectionMock } from '@contember/database-tester'
|
|
6
|
+
import { createDatabaseMetadata } from '@contember/database'
|
|
7
|
+
|
|
8
|
+
namespace IndexModel {
|
|
9
|
+
|
|
10
|
+
@c.Index('colA', 'colB')
|
|
11
|
+
@c.Index('colB', 'colC')
|
|
12
|
+
export class Foo {
|
|
13
|
+
colA = c.stringColumn()
|
|
14
|
+
colB = c.stringColumn()
|
|
15
|
+
colC = c.stringColumn()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test('unique fix test', async () => {
|
|
21
|
+
const builder = createMigrationBuilder()
|
|
22
|
+
const connection = createConnectionMock([{
|
|
23
|
+
sql: 'select schema from stage',
|
|
24
|
+
response: { rows: [{ schema: 'stage_live' }] },
|
|
25
|
+
}])
|
|
26
|
+
await migration(builder, {
|
|
27
|
+
connection: connection,
|
|
28
|
+
databaseMetadataResolver: () => Promise.resolve(createDatabaseMetadata({
|
|
29
|
+
foreignKeys: [],
|
|
30
|
+
indexes: [
|
|
31
|
+
{ indexName: 'valid1', tableName: 'foo', columnNames: ['col_a', 'col_b'], unique: false },
|
|
32
|
+
],
|
|
33
|
+
uniqueConstraints: [],
|
|
34
|
+
})),
|
|
35
|
+
schemaResolver: () => Promise.resolve({
|
|
36
|
+
schema: createSchema(IndexModel),
|
|
37
|
+
meta: {
|
|
38
|
+
id: 1,
|
|
39
|
+
version: '2024-06-28-153001',
|
|
40
|
+
checksum: '_checksum_',
|
|
41
|
+
updatedAt: new Date(),
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
project: {
|
|
45
|
+
slug: 'test',
|
|
46
|
+
stages: [
|
|
47
|
+
{
|
|
48
|
+
slug: 'prod',
|
|
49
|
+
name: 'prod',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
systemSchema: 'system',
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
expect(
|
|
56
|
+
builder.getSql(),
|
|
57
|
+
).toEqual(
|
|
58
|
+
`CREATE INDEX ON "stage_live"."foo" ("col_b", "col_c");
|
|
59
|
+
`,
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
|