@prisma-next/target-postgres 0.13.0-dev.3 → 0.13.0-dev.30
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/{codec-ids-CTikp1if.mjs → codec-ids-BvytN2P8.mjs} +3 -3
- package/dist/codec-ids-BvytN2P8.mjs.map +1 -0
- package/dist/{codec-ids-B1vOchLE.d.mts → codec-ids-CnXu9Qy3.d.mts} +3 -3
- package/dist/codec-ids-CnXu9Qy3.d.mts.map +1 -0
- package/dist/codec-ids.d.mts +2 -2
- package/dist/codec-ids.mjs +2 -2
- package/dist/{codec-types-CnFiNML4.d.mts → codec-types-DHCkwPKE.d.mts} +3 -3
- package/dist/{codec-types-CnFiNML4.d.mts.map → codec-types-DHCkwPKE.d.mts.map} +1 -1
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs-CBpEv4s5.d.mts → codecs--0A5_4Bq.d.mts} +26 -23
- package/dist/codecs--0A5_4Bq.d.mts.map +1 -0
- package/dist/codecs.d.mts +2 -2
- package/dist/codecs.mjs +28 -35
- package/dist/codecs.mjs.map +1 -1
- package/dist/contract-free.d.mts +17 -2
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +3 -3
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +21 -27
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-D25tLeYU.mjs → data-transform-BOWpliq8.mjs} +9 -17
- package/dist/data-transform-BOWpliq8.mjs.map +1 -0
- package/dist/{data-transform-DGOqcLrf.d.mts → data-transform-DDgWdB5o.d.mts} +2 -2
- package/dist/data-transform-DDgWdB5o.d.mts.map +1 -0
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +1 -1
- package/dist/{ddl-77SyXgFt.mjs → ddl-DY2R_Yqz.mjs} +18 -3
- package/dist/ddl-DY2R_Yqz.mjs.map +1 -0
- package/dist/ddl.d.mts +2 -2
- package/dist/ddl.mjs +2 -2
- package/dist/{descriptor-meta-DKmj-IMN.mjs → descriptor-meta-BKma_hQ5.mjs} +2 -2
- package/dist/{descriptor-meta-DKmj-IMN.mjs.map → descriptor-meta-BKma_hQ5.mjs.map} +1 -1
- package/dist/descriptor-meta-runtime-e5f2tscJ.mjs +131 -0
- package/dist/descriptor-meta-runtime-e5f2tscJ.mjs.map +1 -0
- package/dist/{issue-planner-Br0pt1Ea.mjs → issue-planner-DsjB7xDj.mjs} +48 -252
- package/dist/issue-planner-DsjB7xDj.mjs.map +1 -0
- package/dist/issue-planner.d.mts +8 -11
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +4 -15
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +4 -4
- package/dist/{nodes-DZk2JZG3.mjs → nodes-Bbhs2rwj.mjs} +31 -2
- package/dist/nodes-Bbhs2rwj.mjs.map +1 -0
- package/dist/{nodes-779hmCfL.d.mts → nodes-pLeLgdis.d.mts} +30 -3
- package/dist/nodes-pLeLgdis.d.mts.map +1 -0
- package/dist/{op-factory-call-DMA86_2D.d.mts → op-factory-call-CdtMyrlU.d.mts} +12 -56
- package/dist/op-factory-call-CdtMyrlU.d.mts.map +1 -0
- package/dist/{op-factory-call-D2aAUhmS.mjs → op-factory-call-CjR846f7.mjs} +70 -198
- package/dist/op-factory-call-CjR846f7.mjs.map +1 -0
- package/dist/op-factory-call.d.mts +2 -2
- package/dist/op-factory-call.mjs +2 -2
- package/dist/pack.d.mts +36 -15
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-CAYPJObw.mjs → planner-_FOL4I21.mjs} +25 -45
- package/dist/planner-_FOL4I21.mjs.map +1 -0
- package/dist/{planner-ddl-builders-Cw2n2llW.mjs → planner-ddl-builders-B2wOwLqI.mjs} +2 -2
- package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +4 -4
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-identity-values-BIpa5p2I.mjs → planner-identity-values-CJPha2Sz.mjs} +3 -9
- package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -0
- package/dist/planner-identity-values.d.mts +1 -1
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +1 -1
- package/dist/{planner-produced-postgres-migration-NSEhWL0L.mjs → planner-produced-postgres-migration-BmCpyWLJ.mjs} +6 -4
- package/dist/planner-produced-postgres-migration-BmCpyWLJ.mjs.map +1 -0
- package/dist/{planner-produced-postgres-migration-B4EDvLdz.d.mts → planner-produced-postgres-migration-wLhnJMMA.d.mts} +5 -6
- package/dist/planner-produced-postgres-migration-wLhnJMMA.d.mts.map +1 -0
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-sql-checks-DAdhnI2c.mjs → planner-sql-checks-CJJtPfDH.mjs} +3 -3
- package/dist/planner-sql-checks-CJJtPfDH.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts +2 -2
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/{planner-type-resolution-836DExFN.mjs → planner-type-resolution-Bt2f_q-F.mjs} +1 -6
- package/dist/planner-type-resolution-Bt2f_q-F.mjs.map +1 -0
- package/dist/planner.d.mts +4 -4
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{postgres-contract-serializer-DYTyXjPf.mjs → postgres-contract-serializer-CyAe8ZFv.mjs} +27 -37
- package/dist/postgres-contract-serializer-CyAe8ZFv.mjs.map +1 -0
- package/dist/{postgres-migration-DZ_gLUOW.d.mts → postgres-migration-DLXL0GBf.d.mts} +10 -5
- package/dist/postgres-migration-DLXL0GBf.d.mts.map +1 -0
- package/dist/{postgres-migration-COore9Mz.mjs → postgres-migration-dG-J0aI8.mjs} +7 -3
- package/dist/postgres-migration-dG-J0aI8.mjs.map +1 -0
- package/dist/{postgres-schema-BuxCxbvB.mjs → postgres-schema-CTKYiTHu.mjs} +30 -13
- package/dist/postgres-schema-CTKYiTHu.mjs.map +1 -0
- package/dist/{render-ops-BpjstrKQ.mjs → render-ops-BREh1kHe.mjs} +10 -5
- package/dist/render-ops-BREh1kHe.mjs.map +1 -0
- package/dist/render-ops.d.mts +2 -2
- package/dist/render-ops.d.mts.map +1 -1
- package/dist/render-ops.mjs +1 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/{shared-DarONYBZ.d.mts → shared-jcsbXxiW.d.mts} +2 -20
- package/dist/shared-jcsbXxiW.d.mts.map +1 -0
- package/dist/types.d.mts +8 -13
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -3
- package/package.json +17 -18
- package/src/contract-free/ddl.ts +28 -1
- package/src/core/authoring.ts +43 -44
- package/src/core/codec-helpers.ts +0 -17
- package/src/core/codec-ids.ts +1 -1
- package/src/core/codec-type-map.ts +2 -2
- package/src/core/codecs.ts +43 -48
- package/src/core/ddl/nodes.ts +59 -1
- package/src/core/migrations/control-policy.ts +17 -47
- package/src/core/migrations/issue-planner.ts +34 -70
- package/src/core/migrations/op-factory-call.ts +89 -142
- package/src/core/migrations/operations/data-transform.ts +15 -18
- package/src/core/migrations/planner-ddl-builders.ts +3 -4
- package/src/core/migrations/planner-identity-values.ts +4 -28
- package/src/core/migrations/planner-produced-postgres-migration.ts +15 -7
- package/src/core/migrations/planner-recipes.ts +2 -6
- package/src/core/migrations/planner-sql-checks.ts +2 -6
- package/src/core/migrations/planner-strategies.ts +51 -376
- package/src/core/migrations/planner-type-resolution.ts +2 -20
- package/src/core/migrations/planner.ts +6 -6
- package/src/core/migrations/postgres-migration.ts +19 -4
- package/src/core/migrations/render-ops.ts +26 -13
- package/src/core/migrations/runner.ts +26 -20
- package/src/core/postgres-contract-serializer.ts +32 -54
- package/src/core/postgres-enum-type-schema.ts +17 -0
- package/src/core/postgres-schema.ts +56 -34
- package/src/exports/codecs.ts +2 -2
- package/src/exports/contract-free.ts +1 -1
- package/src/exports/control.ts +0 -22
- package/src/exports/ddl.ts +4 -0
- package/src/exports/migration.ts +0 -7
- package/src/exports/op-factory-call.ts +0 -4
- package/src/exports/types.ts +0 -1
- package/dist/codec-ids-B1vOchLE.d.mts.map +0 -1
- package/dist/codec-ids-CTikp1if.mjs.map +0 -1
- package/dist/codecs-CBpEv4s5.d.mts.map +0 -1
- package/dist/data-transform-D25tLeYU.mjs.map +0 -1
- package/dist/data-transform-DGOqcLrf.d.mts.map +0 -1
- package/dist/ddl-77SyXgFt.mjs.map +0 -1
- package/dist/descriptor-meta-runtime-My8_s4cs.mjs +0 -130
- package/dist/descriptor-meta-runtime-My8_s4cs.mjs.map +0 -1
- package/dist/enum-planning-BCyvlFHk.mjs +0 -0
- package/dist/enum-planning-BCyvlFHk.mjs.map +0 -1
- package/dist/enum-planning.d.mts +0 -86
- package/dist/enum-planning.d.mts.map +0 -1
- package/dist/enum-planning.mjs +0 -2
- package/dist/issue-planner-Br0pt1Ea.mjs.map +0 -1
- package/dist/nodes-779hmCfL.d.mts.map +0 -1
- package/dist/nodes-DZk2JZG3.mjs.map +0 -1
- package/dist/op-factory-call-D2aAUhmS.mjs.map +0 -1
- package/dist/op-factory-call-DMA86_2D.d.mts.map +0 -1
- package/dist/planner-CAYPJObw.mjs.map +0 -1
- package/dist/planner-ddl-builders-Cw2n2llW.mjs.map +0 -1
- package/dist/planner-identity-values-BIpa5p2I.mjs.map +0 -1
- package/dist/planner-produced-postgres-migration-B4EDvLdz.d.mts.map +0 -1
- package/dist/planner-produced-postgres-migration-NSEhWL0L.mjs.map +0 -1
- package/dist/planner-sql-checks-DAdhnI2c.mjs.map +0 -1
- package/dist/planner-type-resolution-836DExFN.mjs.map +0 -1
- package/dist/postgres-contract-serializer-DYTyXjPf.mjs.map +0 -1
- package/dist/postgres-enum-type-BVn63a89.d.mts +0 -72
- package/dist/postgres-enum-type-BVn63a89.d.mts.map +0 -1
- package/dist/postgres-enum-type-DPKqCBem.mjs +0 -62
- package/dist/postgres-enum-type-DPKqCBem.mjs.map +0 -1
- package/dist/postgres-migration-COore9Mz.mjs.map +0 -1
- package/dist/postgres-migration-DZ_gLUOW.d.mts.map +0 -1
- package/dist/postgres-schema-BuxCxbvB.mjs.map +0 -1
- package/dist/render-ops-BpjstrKQ.mjs.map +0 -1
- package/dist/shared-DarONYBZ.d.mts.map +0 -1
- package/src/core/migrations/enum-planning.ts +0 -213
- package/src/core/migrations/operations/enums.ts +0 -114
- package/src/core/postgres-enum-type.ts +0 -89
- package/src/exports/enum-planning.ts +0 -11
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* through `mapIssueToCall` for the default case.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { Contract } from '@prisma-next/contract/types';
|
|
11
|
+
import type { Contract, JsonValue } from '@prisma-next/contract/types';
|
|
12
12
|
import type {
|
|
13
13
|
CodecControlHooks,
|
|
14
14
|
MigrationOperationPolicy,
|
|
@@ -19,26 +19,24 @@ import { arraysEqual } from '@prisma-next/family-sql/schema-verify';
|
|
|
19
19
|
import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
|
|
20
20
|
import type { SchemaIssue } from '@prisma-next/framework-components/control';
|
|
21
21
|
import type {
|
|
22
|
-
PostgresEnumStorageEntry,
|
|
23
22
|
SqlStorage,
|
|
24
23
|
StorageColumn,
|
|
25
24
|
StorageTable,
|
|
26
25
|
StorageTypeInstance,
|
|
27
26
|
} from '@prisma-next/sql-contract/types';
|
|
28
|
-
import type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';
|
|
27
|
+
import type { CodecRef, DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';
|
|
29
28
|
import * as contractFree from '@prisma-next/sql-relational-core/contract-free';
|
|
30
29
|
import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
30
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
31
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
31
32
|
import type { Result } from '@prisma-next/utils/result';
|
|
32
33
|
import { notOk, ok } from '@prisma-next/utils/result';
|
|
33
|
-
import { PostgresEnumType } from '../postgres-enum-type';
|
|
34
|
-
import { isPostgresSchema } from '../postgres-schema';
|
|
35
34
|
import {
|
|
36
35
|
AddColumnCall,
|
|
37
36
|
AddForeignKeyCall,
|
|
38
37
|
AddPrimaryKeyCall,
|
|
39
38
|
AddUniqueCall,
|
|
40
39
|
AlterColumnTypeCall,
|
|
41
|
-
CreateEnumTypeCall,
|
|
42
40
|
CreateIndexCall,
|
|
43
41
|
CreateSchemaCall,
|
|
44
42
|
CreateTableCall,
|
|
@@ -54,7 +52,7 @@ import {
|
|
|
54
52
|
SetDefaultCall,
|
|
55
53
|
SetNotNullCall,
|
|
56
54
|
} from './op-factory-call';
|
|
57
|
-
import type {
|
|
55
|
+
import type { ForeignKeySpec } from './operations/shared';
|
|
58
56
|
import { buildColumnDefaultSql, buildColumnTypeSql } from './planner-ddl-builders';
|
|
59
57
|
import { buildExpectedFormatType } from './planner-sql-checks';
|
|
60
58
|
import {
|
|
@@ -65,22 +63,10 @@ import {
|
|
|
65
63
|
type StrategyContext,
|
|
66
64
|
tableAt,
|
|
67
65
|
} from './planner-strategies';
|
|
66
|
+
import { resolveColumnTypeMetadata } from './planner-type-resolution';
|
|
68
67
|
|
|
69
68
|
export type { CallMigrationStrategy, StrategyContext };
|
|
70
69
|
|
|
71
|
-
/**
|
|
72
|
-
* Finds a type entry by explicit namespace coordinate. Reads the named
|
|
73
|
-
* namespace's `enum` slot directly — never scans other namespaces.
|
|
74
|
-
*/
|
|
75
|
-
function locateNamespaceTypeInStorage(
|
|
76
|
-
storage: SqlStorage,
|
|
77
|
-
namespaceId: string,
|
|
78
|
-
typeName: string,
|
|
79
|
-
): unknown {
|
|
80
|
-
const ns = storage.namespaces[namespaceId];
|
|
81
|
-
return isPostgresSchema(ns) ? ns.entries.type[typeName] : undefined;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
70
|
// ============================================================================
|
|
85
71
|
// Issue kind ordering (dependency order)
|
|
86
72
|
// ============================================================================
|
|
@@ -165,7 +151,7 @@ export interface IssuePlannerOptions {
|
|
|
165
151
|
readonly fromContract: Contract<SqlStorage> | null;
|
|
166
152
|
readonly schemaName: string;
|
|
167
153
|
readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;
|
|
168
|
-
readonly storageTypes: Readonly<Record<string, StorageTypeInstance
|
|
154
|
+
readonly storageTypes: Readonly<Record<string, StorageTypeInstance>>;
|
|
169
155
|
/**
|
|
170
156
|
* Current database schema IR. Strategies read this to detect whether a
|
|
171
157
|
* structure already exists (e.g. `buildSchemaLookupMap` for shared-temp-
|
|
@@ -192,31 +178,35 @@ export interface IssuePlannerValue {
|
|
|
192
178
|
readonly calls: readonly PostgresOpFactoryCall[];
|
|
193
179
|
}
|
|
194
180
|
|
|
195
|
-
function toColumnSpec(
|
|
196
|
-
name: string,
|
|
197
|
-
column: StorageColumn,
|
|
198
|
-
codecHooks: ReadonlyMap<string, CodecControlHooks>,
|
|
199
|
-
storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,
|
|
200
|
-
): ColumnSpec {
|
|
201
|
-
return {
|
|
202
|
-
name,
|
|
203
|
-
typeSql: buildColumnTypeSql(column, codecHooks, storageTypes),
|
|
204
|
-
defaultSql: buildColumnDefaultSql(column.default, column),
|
|
205
|
-
nullable: column.nullable,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
181
|
function toDdlColumn(
|
|
210
182
|
name: string,
|
|
211
183
|
column: StorageColumn,
|
|
212
184
|
codecHooks: ReadonlyMap<string, CodecControlHooks>,
|
|
213
|
-
storageTypes: Readonly<Record<string, StorageTypeInstance
|
|
185
|
+
storageTypes: Readonly<Record<string, StorageTypeInstance>>,
|
|
214
186
|
): DdlColumn {
|
|
215
187
|
const typeSql = buildColumnTypeSql(column, codecHooks, storageTypes);
|
|
216
188
|
const ddlDefault = postgresDefaultToDdlColumnDefault(column.default);
|
|
189
|
+
const resolved = resolveColumnTypeMetadata(
|
|
190
|
+
column,
|
|
191
|
+
storageTypes as Record<string, StorageTypeInstance>,
|
|
192
|
+
);
|
|
193
|
+
const codecRef: CodecRef | undefined = resolved.codecId
|
|
194
|
+
? {
|
|
195
|
+
codecId: resolved.codecId,
|
|
196
|
+
...(resolved.typeParams !== undefined
|
|
197
|
+
? {
|
|
198
|
+
typeParams: blindCast<
|
|
199
|
+
JsonValue,
|
|
200
|
+
'resolved.typeParams is JsonValue-shaped storage metadata; the narrowed (non-undefined) value lands in CodecRef.typeParams which is JsonValue'
|
|
201
|
+
>(resolved.typeParams),
|
|
202
|
+
}
|
|
203
|
+
: {}),
|
|
204
|
+
}
|
|
205
|
+
: undefined;
|
|
217
206
|
return contractFree.col(name, typeSql, {
|
|
218
207
|
...(!column.nullable ? { notNull: true } : {}),
|
|
219
|
-
...(
|
|
208
|
+
...ifDefined('default', ddlDefault),
|
|
209
|
+
...ifDefined('codecRef', codecRef),
|
|
220
210
|
});
|
|
221
211
|
}
|
|
222
212
|
|
|
@@ -342,7 +332,7 @@ function mapIssueToCall(
|
|
|
342
332
|
new AddColumnCall(
|
|
343
333
|
tableSchema(issue),
|
|
344
334
|
issue.table,
|
|
345
|
-
|
|
335
|
+
toDdlColumn(issue.column, column, codecHooks, storageTypes),
|
|
346
336
|
),
|
|
347
337
|
]);
|
|
348
338
|
}
|
|
@@ -475,10 +465,7 @@ function mapIssueToCall(
|
|
|
475
465
|
),
|
|
476
466
|
);
|
|
477
467
|
const hooksMap = codecHooks as Map<string, CodecControlHooks>;
|
|
478
|
-
const typesMap = storageTypes as Record<
|
|
479
|
-
string,
|
|
480
|
-
StorageTypeInstance | PostgresEnumStorageEntry
|
|
481
|
-
>;
|
|
468
|
+
const typesMap = storageTypes as Record<string, StorageTypeInstance>;
|
|
482
469
|
const qualifiedTargetType = buildColumnTypeSql(column, hooksMap, typesMap, false);
|
|
483
470
|
const formatTypeExpected = buildExpectedFormatType(column, hooksMap, typesMap);
|
|
484
471
|
return ok([
|
|
@@ -666,14 +653,7 @@ function mapIssueToCall(
|
|
|
666
653
|
case 'type_missing': {
|
|
667
654
|
if (!issue.typeName)
|
|
668
655
|
return notOk(issueConflict('unsupportedOperation', 'Type missing issue has no typeName'));
|
|
669
|
-
|
|
670
|
-
// Check types first; fall back to the namespace-keyed enum slot using the
|
|
671
|
-
// issue's namespace coordinate (populated by the verifier for enum-related
|
|
672
|
-
// issues per the BaseSchemaIssue.namespaceId contract).
|
|
673
|
-
const namespaceId = resolveNamespaceIdForIssue(issue);
|
|
674
|
-
const typeInstance: unknown =
|
|
675
|
-
ctx.toContract.storage.types?.[issue.typeName] ??
|
|
676
|
-
locateNamespaceTypeInStorage(ctx.toContract.storage, namespaceId, issue.typeName);
|
|
656
|
+
const typeInstance = ctx.toContract.storage.types?.[issue.typeName];
|
|
677
657
|
if (!typeInstance) {
|
|
678
658
|
return notOk(
|
|
679
659
|
issueConflict(
|
|
@@ -682,22 +662,10 @@ function mapIssueToCall(
|
|
|
682
662
|
),
|
|
683
663
|
);
|
|
684
664
|
}
|
|
685
|
-
if (typeInstance instanceof PostgresEnumType) {
|
|
686
|
-
const ddlSchema = resolveDdlSchemaForNamespace(ctx, namespaceId);
|
|
687
|
-
return ok([
|
|
688
|
-
new CreateEnumTypeCall(
|
|
689
|
-
ddlSchema,
|
|
690
|
-
issue.typeName,
|
|
691
|
-
typeInstance.values,
|
|
692
|
-
typeInstance.nativeType,
|
|
693
|
-
),
|
|
694
|
-
]);
|
|
695
|
-
}
|
|
696
|
-
const codecInstance = typeInstance as StorageTypeInstance;
|
|
697
665
|
return notOk(
|
|
698
666
|
issueConflict(
|
|
699
667
|
'unsupportedOperation',
|
|
700
|
-
`Type "${issue.typeName}" uses codec "${
|
|
668
|
+
`Type "${issue.typeName}" uses codec "${typeInstance.codecId}" — only value-set types are supported`,
|
|
701
669
|
),
|
|
702
670
|
);
|
|
703
671
|
}
|
|
@@ -744,10 +712,6 @@ function classifyCall(call: PostgresOpFactoryCall): CallCategory {
|
|
|
744
712
|
switch (call.factoryName) {
|
|
745
713
|
case 'createExtension':
|
|
746
714
|
case 'createSchema':
|
|
747
|
-
case 'createEnumType':
|
|
748
|
-
case 'addEnumValues':
|
|
749
|
-
case 'dropEnumType':
|
|
750
|
-
case 'renameType':
|
|
751
715
|
return 'dep';
|
|
752
716
|
case 'dropTable':
|
|
753
717
|
case 'dropColumn':
|
|
@@ -971,10 +935,10 @@ export function planIssues(
|
|
|
971
935
|
return notOk(conflicts);
|
|
972
936
|
}
|
|
973
937
|
|
|
974
|
-
// Recipe strategies (`
|
|
975
|
-
// `
|
|
938
|
+
// Recipe strategies (`notNullBackfillCallStrategy`,
|
|
939
|
+
// `nullableTighteningCallStrategy`, etc.) emit a cohesive sequence that must
|
|
976
940
|
// stay contiguous. They are inserted at a single pattern slot. Non-recipe
|
|
977
|
-
// pattern strategies (`
|
|
941
|
+
// pattern strategies (`checkConstraintPlanCallStrategy`,
|
|
978
942
|
// `storageTypePlanCallStrategy`, `notNullAddColumnCallStrategy`) produce
|
|
979
943
|
// individually classifiable calls that slot into DDL buckets alongside
|
|
980
944
|
// default-mapped calls.
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
import { errorUnfilledPlaceholder } from '@prisma-next/errors/migration';
|
|
24
24
|
import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';
|
|
25
|
-
import type { Lowerer } from '@prisma-next/family-sql/control-adapter';
|
|
25
|
+
import type { ExecuteRequestLowerer, Lowerer } from '@prisma-next/family-sql/control-adapter';
|
|
26
26
|
import type {
|
|
27
27
|
OpFactoryCall as FrameworkOpFactoryCall,
|
|
28
28
|
MigrationOperationClass,
|
|
@@ -36,11 +36,11 @@ import type {
|
|
|
36
36
|
import { FunctionColumnDefault, LiteralColumnDefault } from '@prisma-next/sql-relational-core/ast';
|
|
37
37
|
import { type ImportRequirement, jsonToTsSource, TsExpression } from '@prisma-next/ts-render';
|
|
38
38
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
39
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
39
40
|
import * as contractFreeDdl from '../../contract-free/ddl';
|
|
40
41
|
import { escapeLiteral, quoteIdentifier } from '../sql-utils';
|
|
41
42
|
import type { PostgresColumnDefault } from '../types';
|
|
42
43
|
import {
|
|
43
|
-
addColumn,
|
|
44
44
|
alterColumnType,
|
|
45
45
|
dropColumn,
|
|
46
46
|
dropDefault,
|
|
@@ -57,12 +57,11 @@ import {
|
|
|
57
57
|
dropConstraint,
|
|
58
58
|
} from './operations/constraints';
|
|
59
59
|
import { createExtension } from './operations/dependencies';
|
|
60
|
-
import { addEnumValues, createEnumType, dropEnumType, renameType } from './operations/enums';
|
|
61
60
|
import { createIndex, dropIndex } from './operations/indexes';
|
|
62
|
-
import type {
|
|
61
|
+
import type { ForeignKeySpec } from './operations/shared';
|
|
63
62
|
import { step, targetDetails } from './operations/shared';
|
|
64
63
|
import { dropTable } from './operations/tables';
|
|
65
|
-
import { toRegclassLiteral } from './planner-sql-checks';
|
|
64
|
+
import { columnExistsCheck, toRegclassLiteral } from './planner-sql-checks';
|
|
66
65
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
67
66
|
|
|
68
67
|
type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
|
|
@@ -81,11 +80,15 @@ type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
|
|
|
81
80
|
// transitive package on disk.
|
|
82
81
|
const POSTGRES_MIGRATION_FACADE = '@prisma-next/postgres/migration';
|
|
83
82
|
|
|
83
|
+
function boundSchema(schemaName: string): string | undefined {
|
|
84
|
+
return schemaName === UNBOUND_NAMESPACE_ID ? undefined : schemaName;
|
|
85
|
+
}
|
|
86
|
+
|
|
84
87
|
abstract class PostgresOpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {
|
|
85
88
|
abstract readonly factoryName: string;
|
|
86
89
|
abstract readonly operationClass: MigrationOperationClass;
|
|
87
90
|
abstract readonly label: string;
|
|
88
|
-
abstract toOp(lowerer?: Lowerer): Op
|
|
91
|
+
abstract toOp(lowerer?: Lowerer): Op | Promise<Op>;
|
|
89
92
|
|
|
90
93
|
importRequirements(): readonly ImportRequirement[] {
|
|
91
94
|
return [{ moduleSpecifier: POSTGRES_MIGRATION_FACADE, symbol: this.factoryName }];
|
|
@@ -213,19 +216,19 @@ export class CreateTableCall extends PostgresOpFactoryCallNode {
|
|
|
213
216
|
this.freeze();
|
|
214
217
|
}
|
|
215
218
|
|
|
216
|
-
toOp(lowerer?:
|
|
219
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
217
220
|
if (lowerer === undefined) {
|
|
218
221
|
throw new Error(
|
|
219
222
|
`CreateTableCall.toOp: a DDL lowerer is required on the Postgres planner path (table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
220
223
|
);
|
|
221
224
|
}
|
|
222
225
|
const ddlNode = contractFreeDdl.createTable({
|
|
223
|
-
...(
|
|
226
|
+
...ifDefined('schema', boundSchema(this.schemaName)),
|
|
224
227
|
table: this.tableName,
|
|
225
228
|
columns: this.columns,
|
|
226
|
-
...(
|
|
229
|
+
...ifDefined('constraints', this.constraints),
|
|
227
230
|
});
|
|
228
|
-
const
|
|
231
|
+
const statement = await lowerer.lowerToExecuteRequest(ddlNode);
|
|
229
232
|
const schemaName = this.schemaName;
|
|
230
233
|
const tableName = this.tableName;
|
|
231
234
|
return {
|
|
@@ -240,7 +243,13 @@ export class CreateTableCall extends PostgresOpFactoryCallNode {
|
|
|
240
243
|
`SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NULL`,
|
|
241
244
|
),
|
|
242
245
|
],
|
|
243
|
-
execute: [
|
|
246
|
+
execute: [
|
|
247
|
+
{
|
|
248
|
+
description: `create table "${tableName}"`,
|
|
249
|
+
sql: statement.sql,
|
|
250
|
+
params: statement.params ?? [],
|
|
251
|
+
},
|
|
252
|
+
],
|
|
244
253
|
postcheck: [
|
|
245
254
|
step(
|
|
246
255
|
`verify table "${tableName}" exists`,
|
|
@@ -315,10 +324,10 @@ export class AddColumnCall extends PostgresOpFactoryCallNode {
|
|
|
315
324
|
readonly operationClass = 'additive' as const;
|
|
316
325
|
readonly schemaName: string;
|
|
317
326
|
readonly tableName: string;
|
|
318
|
-
readonly column:
|
|
327
|
+
readonly column: DdlColumn;
|
|
319
328
|
readonly label: string;
|
|
320
329
|
|
|
321
|
-
constructor(schemaName: string, tableName: string, column:
|
|
330
|
+
constructor(schemaName: string, tableName: string, column: DdlColumn) {
|
|
322
331
|
super();
|
|
323
332
|
this.schemaName = schemaName;
|
|
324
333
|
this.tableName = tableName;
|
|
@@ -327,12 +336,65 @@ export class AddColumnCall extends PostgresOpFactoryCallNode {
|
|
|
327
336
|
this.freeze();
|
|
328
337
|
}
|
|
329
338
|
|
|
330
|
-
toOp(): Op {
|
|
331
|
-
|
|
339
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
340
|
+
if (lowerer === undefined) {
|
|
341
|
+
throw new Error(
|
|
342
|
+
`AddColumnCall.toOp: a DDL lowerer is required on the Postgres planner path (column "${this.column.name}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
const ddlNode = contractFreeDdl.alterTable({
|
|
346
|
+
...ifDefined('schema', boundSchema(this.schemaName)),
|
|
347
|
+
table: this.tableName,
|
|
348
|
+
actions: [contractFreeDdl.addColumnAction(this.column)],
|
|
349
|
+
});
|
|
350
|
+
const statement = await lowerer.lowerToExecuteRequest(ddlNode);
|
|
351
|
+
const schemaName = this.schemaName;
|
|
352
|
+
const tableName = this.tableName;
|
|
353
|
+
const columnName = this.column.name;
|
|
354
|
+
return {
|
|
355
|
+
id: `column.${tableName}.${columnName}`,
|
|
356
|
+
label: `Add column "${columnName}" to "${tableName}"`,
|
|
357
|
+
operationClass: 'additive',
|
|
358
|
+
target: targetDetails('column', columnName, schemaName, tableName),
|
|
359
|
+
precheck: [
|
|
360
|
+
step(
|
|
361
|
+
`ensure column "${columnName}" is missing`,
|
|
362
|
+
columnExistsCheck({
|
|
363
|
+
schema: schemaName,
|
|
364
|
+
table: tableName,
|
|
365
|
+
column: columnName,
|
|
366
|
+
exists: false,
|
|
367
|
+
}),
|
|
368
|
+
),
|
|
369
|
+
],
|
|
370
|
+
execute: [step(`add column "${columnName}"`, statement.sql)],
|
|
371
|
+
postcheck: [
|
|
372
|
+
step(
|
|
373
|
+
`verify column "${columnName}" exists`,
|
|
374
|
+
columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),
|
|
375
|
+
),
|
|
376
|
+
],
|
|
377
|
+
};
|
|
332
378
|
}
|
|
333
379
|
|
|
334
380
|
renderTypeScript(): string {
|
|
335
|
-
|
|
381
|
+
const opts: string[] = [];
|
|
382
|
+
if (this.schemaName !== UNBOUND_NAMESPACE_ID) {
|
|
383
|
+
opts.push(`schema: ${jsonToTsSource(this.schemaName)}`);
|
|
384
|
+
}
|
|
385
|
+
opts.push(`table: ${jsonToTsSource(this.tableName)}`);
|
|
386
|
+
opts.push(`column: ${renderDdlColumnAsTsCall(this.column)}`);
|
|
387
|
+
return `this.addColumn({ ${opts.join(', ')} })`;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
override importRequirements(): readonly ImportRequirement[] {
|
|
391
|
+
const req: ImportRequirement[] = [
|
|
392
|
+
{ moduleSpecifier: POSTGRES_MIGRATION_FACADE, symbol: 'col' },
|
|
393
|
+
];
|
|
394
|
+
for (const sym of defaultImportSymbols([this.column])) {
|
|
395
|
+
req.push({ moduleSpecifier: POSTGRES_MIGRATION_FACADE, symbol: sym });
|
|
396
|
+
}
|
|
397
|
+
return req;
|
|
336
398
|
}
|
|
337
399
|
}
|
|
338
400
|
|
|
@@ -746,8 +808,8 @@ export class CreateIndexCall extends PostgresOpFactoryCallNode {
|
|
|
746
808
|
readonly tableName: string;
|
|
747
809
|
readonly indexName: string;
|
|
748
810
|
readonly columns: readonly string[];
|
|
749
|
-
// Named indexType (not typeName)
|
|
750
|
-
//
|
|
811
|
+
// Named indexType (not typeName): `locationForCall` in issue-planner.ts reads
|
|
812
|
+
// a call's `typeName` as a CREATE TYPE target location, which an index is not.
|
|
751
813
|
readonly indexType: string | undefined;
|
|
752
814
|
readonly options: Record<string, unknown> | undefined;
|
|
753
815
|
readonly label: string;
|
|
@@ -820,123 +882,6 @@ export class DropIndexCall extends PostgresOpFactoryCallNode {
|
|
|
820
882
|
}
|
|
821
883
|
}
|
|
822
884
|
|
|
823
|
-
// ============================================================================
|
|
824
|
-
// Enum types
|
|
825
|
-
// ============================================================================
|
|
826
|
-
|
|
827
|
-
export class CreateEnumTypeCall extends PostgresOpFactoryCallNode {
|
|
828
|
-
readonly factoryName = 'createEnumType' as const;
|
|
829
|
-
readonly operationClass = 'additive' as const;
|
|
830
|
-
readonly schemaName: string;
|
|
831
|
-
readonly typeName: string;
|
|
832
|
-
readonly nativeType: string;
|
|
833
|
-
readonly values: readonly string[];
|
|
834
|
-
readonly label: string;
|
|
835
|
-
|
|
836
|
-
constructor(
|
|
837
|
-
schemaName: string,
|
|
838
|
-
typeName: string,
|
|
839
|
-
values: readonly string[],
|
|
840
|
-
nativeType: string = typeName,
|
|
841
|
-
) {
|
|
842
|
-
super();
|
|
843
|
-
this.schemaName = schemaName;
|
|
844
|
-
this.typeName = typeName;
|
|
845
|
-
this.nativeType = nativeType;
|
|
846
|
-
this.values = values;
|
|
847
|
-
this.label = `Create enum type "${typeName}"`;
|
|
848
|
-
this.freeze();
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
toOp(): Op {
|
|
852
|
-
return createEnumType(this.schemaName, this.typeName, this.values, this.nativeType);
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
renderTypeScript(): string {
|
|
856
|
-
const nativeArg =
|
|
857
|
-
this.nativeType === this.typeName ? '' : `, ${jsonToTsSource(this.nativeType)}`;
|
|
858
|
-
return `createEnumType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.typeName)}, ${jsonToTsSource(this.values)}${nativeArg})`;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
export class AddEnumValuesCall extends PostgresOpFactoryCallNode {
|
|
863
|
-
readonly factoryName = 'addEnumValues' as const;
|
|
864
|
-
readonly operationClass = 'additive' as const;
|
|
865
|
-
readonly schemaName: string;
|
|
866
|
-
readonly typeName: string;
|
|
867
|
-
readonly nativeType: string;
|
|
868
|
-
readonly values: readonly string[];
|
|
869
|
-
readonly label: string;
|
|
870
|
-
|
|
871
|
-
constructor(schemaName: string, typeName: string, nativeType: string, values: readonly string[]) {
|
|
872
|
-
super();
|
|
873
|
-
this.schemaName = schemaName;
|
|
874
|
-
this.typeName = typeName;
|
|
875
|
-
this.nativeType = nativeType;
|
|
876
|
-
this.values = values;
|
|
877
|
-
this.label = `Add values to enum type "${typeName}": ${values.join(', ')}`;
|
|
878
|
-
this.freeze();
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
toOp(): Op {
|
|
882
|
-
return addEnumValues(this.schemaName, this.typeName, this.nativeType, this.values);
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
renderTypeScript(): string {
|
|
886
|
-
return `addEnumValues(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.typeName)}, ${jsonToTsSource(this.nativeType)}, ${jsonToTsSource(this.values)})`;
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
export class DropEnumTypeCall extends PostgresOpFactoryCallNode {
|
|
891
|
-
readonly factoryName = 'dropEnumType' as const;
|
|
892
|
-
readonly operationClass = 'destructive' as const;
|
|
893
|
-
readonly schemaName: string;
|
|
894
|
-
readonly typeName: string;
|
|
895
|
-
readonly label: string;
|
|
896
|
-
|
|
897
|
-
constructor(schemaName: string, typeName: string) {
|
|
898
|
-
super();
|
|
899
|
-
this.schemaName = schemaName;
|
|
900
|
-
this.typeName = typeName;
|
|
901
|
-
this.label = `Drop enum type "${typeName}"`;
|
|
902
|
-
this.freeze();
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
toOp(): Op {
|
|
906
|
-
return dropEnumType(this.schemaName, this.typeName);
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
renderTypeScript(): string {
|
|
910
|
-
return `dropEnumType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.typeName)})`;
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
export class RenameTypeCall extends PostgresOpFactoryCallNode {
|
|
915
|
-
readonly factoryName = 'renameType' as const;
|
|
916
|
-
readonly operationClass = 'destructive' as const;
|
|
917
|
-
readonly schemaName: string;
|
|
918
|
-
readonly fromName: string;
|
|
919
|
-
readonly toName: string;
|
|
920
|
-
readonly label: string;
|
|
921
|
-
|
|
922
|
-
constructor(schemaName: string, fromName: string, toName: string) {
|
|
923
|
-
super();
|
|
924
|
-
this.schemaName = schemaName;
|
|
925
|
-
this.fromName = fromName;
|
|
926
|
-
this.toName = toName;
|
|
927
|
-
this.label = `Rename type "${fromName}" to "${toName}"`;
|
|
928
|
-
this.freeze();
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
toOp(): Op {
|
|
932
|
-
return renameType(this.schemaName, this.fromName, this.toName);
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
renderTypeScript(): string {
|
|
936
|
-
return `renameType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.fromName)}, ${jsonToTsSource(this.toName)})`;
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
|
|
940
885
|
// ============================================================================
|
|
941
886
|
// Raw SQL
|
|
942
887
|
// ============================================================================
|
|
@@ -1016,14 +961,14 @@ export class CreateSchemaCall extends PostgresOpFactoryCallNode {
|
|
|
1016
961
|
this.freeze();
|
|
1017
962
|
}
|
|
1018
963
|
|
|
1019
|
-
toOp(lowerer?:
|
|
964
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1020
965
|
if (lowerer === undefined) {
|
|
1021
966
|
throw new Error(
|
|
1022
967
|
`CreateSchemaCall.toOp: a DDL lowerer is required on the Postgres planner path (schema "${this.schemaName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1023
968
|
);
|
|
1024
969
|
}
|
|
1025
970
|
const ddlNode = contractFreeDdl.createSchema({ schema: this.schemaName, ifNotExists: true });
|
|
1026
|
-
const
|
|
971
|
+
const statement = await lowerer.lowerToExecuteRequest(ddlNode);
|
|
1027
972
|
const schemaName = this.schemaName;
|
|
1028
973
|
return {
|
|
1029
974
|
id: `schema.${schemaName}`,
|
|
@@ -1031,7 +976,13 @@ export class CreateSchemaCall extends PostgresOpFactoryCallNode {
|
|
|
1031
976
|
operationClass: 'additive',
|
|
1032
977
|
target: { id: 'postgres' },
|
|
1033
978
|
precheck: [],
|
|
1034
|
-
execute: [
|
|
979
|
+
execute: [
|
|
980
|
+
{
|
|
981
|
+
description: `Create schema "${schemaName}"`,
|
|
982
|
+
sql: statement.sql,
|
|
983
|
+
params: statement.params ?? [],
|
|
984
|
+
},
|
|
985
|
+
],
|
|
1035
986
|
postcheck: [],
|
|
1036
987
|
};
|
|
1037
988
|
}
|
|
@@ -1121,10 +1072,6 @@ export type PostgresOpFactoryCall =
|
|
|
1121
1072
|
| CreateIndexCall
|
|
1122
1073
|
| DropIndexCall
|
|
1123
1074
|
| DropConstraintCall
|
|
1124
|
-
| CreateEnumTypeCall
|
|
1125
|
-
| AddEnumValuesCall
|
|
1126
|
-
| DropEnumTypeCall
|
|
1127
|
-
| RenameTypeCall
|
|
1128
1075
|
| RawSqlCall
|
|
1129
1076
|
| CreateExtensionCall
|
|
1130
1077
|
| CreateSchemaCall
|
|
@@ -61,8 +61,8 @@ import type {
|
|
|
61
61
|
SqlMigrationPlanOperationStep,
|
|
62
62
|
} from '@prisma-next/family-sql/control';
|
|
63
63
|
import type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';
|
|
64
|
-
import type { SerializedQueryPlan } from '@prisma-next/framework-components/control';
|
|
65
64
|
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
65
|
+
import type { SqlExecuteRequest } from '@prisma-next/sql-relational-core/ast';
|
|
66
66
|
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
67
67
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
68
68
|
import type { PostgresPlanTargetDetails } from '../planner-target-details';
|
|
@@ -96,25 +96,29 @@ export interface DataTransformOptions {
|
|
|
96
96
|
readonly run: DataTransformClosure | readonly DataTransformClosure[];
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
export function dataTransform<TContract extends Contract<SqlStorage>>(
|
|
99
|
+
export async function dataTransform<TContract extends Contract<SqlStorage>>(
|
|
100
100
|
contract: TContract,
|
|
101
101
|
name: string,
|
|
102
102
|
options: DataTransformOptions,
|
|
103
103
|
adapter: SqlControlAdapter<'postgres'>,
|
|
104
|
-
): SqlMigrationPlanOperation<PostgresPlanTargetDetails
|
|
104
|
+
): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
105
105
|
const runClosures: readonly DataTransformClosure[] = Array.isArray(options.run)
|
|
106
106
|
? options.run
|
|
107
107
|
: [options.run as DataTransformClosure];
|
|
108
108
|
|
|
109
|
-
const checkPlan = options.check
|
|
110
|
-
|
|
109
|
+
const checkPlan = options.check
|
|
110
|
+
? await invokeAndLower(options.check, contract, adapter, name)
|
|
111
|
+
: null;
|
|
112
|
+
const runPlans = await Promise.all(
|
|
113
|
+
runClosures.map((closure) => invokeAndLower(closure, contract, adapter, name)),
|
|
114
|
+
);
|
|
111
115
|
|
|
112
116
|
const precheck: readonly SqlMigrationPlanOperationStep[] = checkPlan
|
|
113
117
|
? [
|
|
114
118
|
{
|
|
115
119
|
description: `Check ${name} has work to do`,
|
|
116
120
|
sql: `SELECT EXISTS (${checkPlan.sql}) AS ok`,
|
|
117
|
-
params: checkPlan.params,
|
|
121
|
+
params: checkPlan.params ?? [],
|
|
118
122
|
},
|
|
119
123
|
]
|
|
120
124
|
: [];
|
|
@@ -122,7 +126,7 @@ export function dataTransform<TContract extends Contract<SqlStorage>>(
|
|
|
122
126
|
const execute: readonly SqlMigrationPlanOperationStep[] = runPlans.map((plan) => ({
|
|
123
127
|
description: `Run ${name}`,
|
|
124
128
|
sql: plan.sql,
|
|
125
|
-
params: plan.params,
|
|
129
|
+
params: plan.params ?? [],
|
|
126
130
|
}));
|
|
127
131
|
|
|
128
132
|
const postcheck: readonly SqlMigrationPlanOperationStep[] = checkPlan
|
|
@@ -130,7 +134,7 @@ export function dataTransform<TContract extends Contract<SqlStorage>>(
|
|
|
130
134
|
{
|
|
131
135
|
description: `Verify ${name} resolved all violations`,
|
|
132
136
|
sql: `SELECT NOT EXISTS (${checkPlan.sql}) AS ok`,
|
|
133
|
-
params: checkPlan.params,
|
|
137
|
+
params: checkPlan.params ?? [],
|
|
134
138
|
},
|
|
135
139
|
]
|
|
136
140
|
: [];
|
|
@@ -147,23 +151,16 @@ export function dataTransform<TContract extends Contract<SqlStorage>>(
|
|
|
147
151
|
};
|
|
148
152
|
}
|
|
149
153
|
|
|
150
|
-
function invokeAndLower(
|
|
154
|
+
async function invokeAndLower(
|
|
151
155
|
closure: DataTransformClosure,
|
|
152
156
|
contract: Contract<SqlStorage>,
|
|
153
157
|
adapter: SqlControlAdapter<'postgres'>,
|
|
154
158
|
name: string,
|
|
155
|
-
):
|
|
159
|
+
): Promise<SqlExecuteRequest> {
|
|
156
160
|
const result = closure();
|
|
157
161
|
const plan = isBuildable(result) ? result.build() : result;
|
|
158
162
|
assertContractMatches(plan, contract, name);
|
|
159
|
-
|
|
160
|
-
const params = lowered.params.map((slot) => {
|
|
161
|
-
if (slot.kind === 'literal') return slot.value;
|
|
162
|
-
throw new Error(
|
|
163
|
-
`data-transform: bind-site slot '${slot.name}' is not allowed in migration plans`,
|
|
164
|
-
);
|
|
165
|
-
});
|
|
166
|
-
return { sql: lowered.sql, params };
|
|
163
|
+
return adapter.lowerToExecuteRequest(plan.ast, { contract });
|
|
167
164
|
}
|
|
168
165
|
|
|
169
166
|
function isBuildable(value: unknown): value is Buildable {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { CodecControlHooks } from '@prisma-next/family-sql/control';
|
|
2
2
|
import type {
|
|
3
|
-
PostgresEnumStorageEntry,
|
|
4
3
|
StorageColumn,
|
|
5
4
|
StorageTable,
|
|
6
5
|
StorageTypeInstance,
|
|
@@ -14,7 +13,7 @@ export function buildCreateTableSql(
|
|
|
14
13
|
qualifiedTableName: string,
|
|
15
14
|
table: StorageTable,
|
|
16
15
|
codecHooks: ReadonlyMap<string, CodecControlHooks>,
|
|
17
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
16
|
+
storageTypes: Record<string, StorageTypeInstance> = {},
|
|
18
17
|
): string {
|
|
19
18
|
const columnDefinitions = Object.entries(table.columns).map(
|
|
20
19
|
([columnName, column]: [string, StorageColumn]) => {
|
|
@@ -79,7 +78,7 @@ function assertSafeDefaultExpression(expression: string): void {
|
|
|
79
78
|
export function buildColumnTypeSql(
|
|
80
79
|
column: StorageColumn,
|
|
81
80
|
codecHooks: ReadonlyMap<string, CodecControlHooks>,
|
|
82
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
81
|
+
storageTypes: Record<string, StorageTypeInstance> = {},
|
|
83
82
|
allowPseudoTypes = true,
|
|
84
83
|
): string {
|
|
85
84
|
const resolved = resolveColumnTypeMetadata(column, storageTypes);
|
|
@@ -200,7 +199,7 @@ export function buildAddColumnSql(
|
|
|
200
199
|
column: StorageColumn,
|
|
201
200
|
codecHooks: ReadonlyMap<string, CodecControlHooks>,
|
|
202
201
|
temporaryDefault?: string | null,
|
|
203
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
202
|
+
storageTypes: Record<string, StorageTypeInstance> = {},
|
|
204
203
|
): string {
|
|
205
204
|
const typeSql = buildColumnTypeSql(column, codecHooks, storageTypes);
|
|
206
205
|
const defaultSql =
|