@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
|
@@ -7,7 +7,7 @@ import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
|
7
7
|
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
8
8
|
import type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';
|
|
9
9
|
import { errorPostgresMigrationStackMissing } from '../errors';
|
|
10
|
-
import { CreateSchemaCall, CreateTableCall } from './op-factory-call';
|
|
10
|
+
import { AddColumnCall, CreateSchemaCall, CreateTableCall } from './op-factory-call';
|
|
11
11
|
import { type DataTransformOptions, dataTransform } from './operations/data-transform';
|
|
12
12
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
13
13
|
|
|
@@ -64,7 +64,7 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
64
64
|
contract: TContract,
|
|
65
65
|
name: string,
|
|
66
66
|
options: DataTransformOptions,
|
|
67
|
-
): SqlMigrationPlanOperation<PostgresPlanTargetDetails
|
|
67
|
+
): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
68
68
|
if (!this.controlAdapter) {
|
|
69
69
|
throw errorPostgresMigrationStackMissing();
|
|
70
70
|
}
|
|
@@ -82,7 +82,7 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
82
82
|
readonly ifNotExists?: boolean;
|
|
83
83
|
readonly columns: readonly DdlColumn[];
|
|
84
84
|
readonly constraints?: readonly DdlTableConstraint[];
|
|
85
|
-
}): SqlMigrationPlanOperation<PostgresPlanTargetDetails
|
|
85
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
86
86
|
if (!this.controlAdapter) {
|
|
87
87
|
throw errorPostgresMigrationStackMissing();
|
|
88
88
|
}
|
|
@@ -102,10 +102,25 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
102
102
|
protected createSchema(options: {
|
|
103
103
|
readonly schema: string;
|
|
104
104
|
readonly ifNotExists?: boolean;
|
|
105
|
-
}): SqlMigrationPlanOperation<PostgresPlanTargetDetails
|
|
105
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
106
106
|
if (!this.controlAdapter) {
|
|
107
107
|
throw errorPostgresMigrationStackMissing();
|
|
108
108
|
}
|
|
109
109
|
return new CreateSchemaCall(options.schema).toOp(this.controlAdapter);
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
protected addColumn(options: {
|
|
113
|
+
readonly schema?: string;
|
|
114
|
+
readonly table: string;
|
|
115
|
+
readonly column: DdlColumn;
|
|
116
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
117
|
+
if (!this.controlAdapter) {
|
|
118
|
+
throw errorPostgresMigrationStackMissing();
|
|
119
|
+
}
|
|
120
|
+
return new AddColumnCall(
|
|
121
|
+
options.schema ?? UNBOUND_NAMESPACE_ID,
|
|
122
|
+
options.table,
|
|
123
|
+
options.column,
|
|
124
|
+
).toOp(this.controlAdapter);
|
|
125
|
+
}
|
|
111
126
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';
|
|
3
|
+
import type {
|
|
4
|
+
MigrationPlanOperation,
|
|
5
|
+
OpFactoryCall,
|
|
6
|
+
} from '@prisma-next/framework-components/control';
|
|
4
7
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
8
|
+
import { isThenable } from '@prisma-next/utils/promise';
|
|
5
9
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
6
10
|
|
|
7
11
|
type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
|
|
@@ -13,11 +17,11 @@ type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
|
|
|
13
17
|
* silently flow through to postgres-shaped renderers — exactly the
|
|
14
18
|
* place to fail loudly with op metadata (`id` + `target.id`).
|
|
15
19
|
*/
|
|
16
|
-
function assertPostgresOp(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
function assertPostgresOp(op: MigrationPlanOperation, callFactoryName: string): asserts op is Op {
|
|
21
|
+
const targetId = blindCast<
|
|
22
|
+
{ target?: { id?: string } },
|
|
23
|
+
'op.target is present on concrete SqlMigrationPlanOperation but absent on the framework MigrationPlanOperation base'
|
|
24
|
+
>(op).target?.id;
|
|
21
25
|
if (targetId !== 'postgres') {
|
|
22
26
|
throw new Error(
|
|
23
27
|
`renderOps: expected postgres op but got target.id="${String(targetId)}" for op.id="${op.id}" (factoryName="${callFactoryName}"). An OpFactoryCall produced an op for a different target on the postgres planner path; check the call's target binding.`,
|
|
@@ -25,13 +29,22 @@ function assertPostgresOp(
|
|
|
25
29
|
}
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
export function renderOps(
|
|
32
|
+
export function renderOps(
|
|
33
|
+
calls: readonly OpFactoryCall[],
|
|
34
|
+
lowerer?: ExecuteRequestLowerer,
|
|
35
|
+
): (Op | Promise<Op>)[] {
|
|
29
36
|
return calls.map((c) => {
|
|
30
|
-
const
|
|
31
|
-
{ toOp(lowerer?:
|
|
32
|
-
'PG OpFactoryCall.toOp accepts an optional
|
|
37
|
+
const opOrPromise = blindCast<
|
|
38
|
+
{ toOp(lowerer?: ExecuteRequestLowerer): Op | Promise<Op> },
|
|
39
|
+
'PG OpFactoryCall.toOp accepts an optional ExecuteRequestLowerer; the framework interface omits it because not all targets need a lowerer — the PG target overrides with this extended signature'
|
|
33
40
|
>(c).toOp(lowerer);
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
if (isThenable(opOrPromise)) {
|
|
42
|
+
return opOrPromise.then((op) => {
|
|
43
|
+
assertPostgresOp(op, c.factoryName);
|
|
44
|
+
return op;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
assertPostgresOp(opOrPromise, c.factoryName);
|
|
48
|
+
return opOrPromise;
|
|
36
49
|
});
|
|
37
50
|
}
|
|
@@ -18,13 +18,13 @@ import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
|
|
|
18
18
|
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
19
19
|
import type { SqlControlDriverInstance, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
20
20
|
import { SqlQueryError } from '@prisma-next/sql-errors';
|
|
21
|
-
import type {
|
|
21
|
+
import type { SqlExecuteRequest } from '@prisma-next/sql-relational-core/ast';
|
|
22
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
22
23
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
23
24
|
import type { Result } from '@prisma-next/utils/result';
|
|
24
25
|
import { notOk, ok, okVoid } from '@prisma-next/utils/result';
|
|
25
26
|
import { parsePostgresDefault } from '../default-normalizer';
|
|
26
27
|
import { normalizeSchemaNativeType } from '../native-type-normalizer';
|
|
27
|
-
import { createResolveExistingEnumValues } from './enum-planning';
|
|
28
28
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
29
29
|
|
|
30
30
|
interface ApplyPlanSuccessValue {
|
|
@@ -86,6 +86,12 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
86
86
|
const space = options.plan.spaceId;
|
|
87
87
|
const lockKey = `${LOCK_DOMAIN}:${schema}:${space}`;
|
|
88
88
|
|
|
89
|
+
// Materialize any async ops before running checks or executing.
|
|
90
|
+
const planOps = blindCast<
|
|
91
|
+
readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],
|
|
92
|
+
'ops were produced by the PG planner and are SqlMigrationPlanOperation<PostgresPlanTargetDetails>; MigrationPlan.operations uses the wider framework type to accommodate Promise covariance'
|
|
93
|
+
>(await Promise.all(options.plan.operations));
|
|
94
|
+
|
|
89
95
|
// Static checks (idempotent — safe to run again when the caller is
|
|
90
96
|
// `execute(...)` because the cost is a single object comparison).
|
|
91
97
|
const destinationCheck = this.ensurePlanMatchesDestinationContract(
|
|
@@ -94,7 +100,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
94
100
|
);
|
|
95
101
|
if (!destinationCheck.ok) return destinationCheck;
|
|
96
102
|
|
|
97
|
-
const policyCheck = this.enforcePolicyCompatibility(options.policy,
|
|
103
|
+
const policyCheck = this.enforcePolicyCompatibility(options.policy, planOps);
|
|
98
104
|
if (!policyCheck.ok) return policyCheck;
|
|
99
105
|
|
|
100
106
|
await this.acquireLock(driver, lockKey);
|
|
@@ -113,7 +119,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
113
119
|
if (skipOperations) {
|
|
114
120
|
applyValue = { operationsExecuted: 0, executedOperations: [] };
|
|
115
121
|
} else {
|
|
116
|
-
const applyResult = await this.applyPlan(driver, options);
|
|
122
|
+
const applyResult = await this.applyPlan(driver, options, planOps);
|
|
117
123
|
if (!applyResult.ok) return applyResult;
|
|
118
124
|
applyValue = applyResult.value;
|
|
119
125
|
}
|
|
@@ -137,9 +143,6 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
137
143
|
frameworkComponents: options.frameworkComponents,
|
|
138
144
|
normalizeDefault: parsePostgresDefault,
|
|
139
145
|
normalizeNativeType: normalizeSchemaNativeType,
|
|
140
|
-
resolveExistingEnumValues: createResolveExistingEnumValues(
|
|
141
|
-
options.destinationContract.storage,
|
|
142
|
-
),
|
|
143
146
|
});
|
|
144
147
|
if (!schemaVerifyResult.ok) {
|
|
145
148
|
return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
|
|
@@ -158,11 +161,16 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
158
161
|
if (!isSelfEdgeNoOp) {
|
|
159
162
|
const markerResult = await this.upsertMarker(driver, options, existingMarker, space);
|
|
160
163
|
if (!markerResult.ok) return markerResult;
|
|
161
|
-
await this.recordLedgerEntries(
|
|
164
|
+
await this.recordLedgerEntries(
|
|
165
|
+
driver,
|
|
166
|
+
options,
|
|
167
|
+
applyValue.executedOperations,
|
|
168
|
+
planOps.length,
|
|
169
|
+
);
|
|
162
170
|
}
|
|
163
171
|
|
|
164
172
|
return runnerSuccess({
|
|
165
|
-
operationsPlanned:
|
|
173
|
+
operationsPlanned: planOps.length,
|
|
166
174
|
operationsExecuted: applyValue.operationsExecuted,
|
|
167
175
|
});
|
|
168
176
|
}
|
|
@@ -209,6 +217,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
209
217
|
private async applyPlan(
|
|
210
218
|
driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],
|
|
211
219
|
options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,
|
|
220
|
+
ops: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],
|
|
212
221
|
): Promise<Result<ApplyPlanSuccessValue, SqlMigrationRunnerFailure>> {
|
|
213
222
|
const checks = options.executionChecks;
|
|
214
223
|
const runPrechecks = checks?.prechecks !== false; // Default true
|
|
@@ -217,7 +226,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
217
226
|
|
|
218
227
|
let operationsExecuted = 0;
|
|
219
228
|
const executedOperations: Array<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> = [];
|
|
220
|
-
for (const operation of
|
|
229
|
+
for (const operation of ops) {
|
|
221
230
|
options.callbacks?.onOperationStart?.(operation);
|
|
222
231
|
try {
|
|
223
232
|
// Idempotency probe: only run if both postchecks and idempotency checks are enabled
|
|
@@ -282,13 +291,13 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
282
291
|
if (schemaQuery === undefined) {
|
|
283
292
|
throw new Error('Postgres control-table bootstrap must include CREATE SCHEMA');
|
|
284
293
|
}
|
|
285
|
-
await this.executeStatement(driver, this.family.lowerAst(schemaQuery, lowererContext));
|
|
294
|
+
await this.executeStatement(driver, await this.family.lowerAst(schemaQuery, lowererContext));
|
|
286
295
|
const legacyDetection = await this.detectLegacyMarkerShape(driver);
|
|
287
296
|
if (!legacyDetection.ok) {
|
|
288
297
|
return legacyDetection;
|
|
289
298
|
}
|
|
290
299
|
for (const query of tableQueries) {
|
|
291
|
-
await this.executeStatement(driver, this.family.lowerAst(query, lowererContext));
|
|
300
|
+
await this.executeStatement(driver, await this.family.lowerAst(query, lowererContext));
|
|
292
301
|
}
|
|
293
302
|
return okVoid();
|
|
294
303
|
}
|
|
@@ -629,14 +638,15 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
629
638
|
driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],
|
|
630
639
|
options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,
|
|
631
640
|
executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],
|
|
641
|
+
planOpsLength: number,
|
|
632
642
|
): Promise<void> {
|
|
633
643
|
const plan = options.plan;
|
|
634
644
|
const space = plan.spaceId;
|
|
635
645
|
const edges = options.migrationEdges;
|
|
636
646
|
const totalEdgeOps = edges.reduce((sum, edge) => sum + edge.operationCount, 0);
|
|
637
|
-
if (totalEdgeOps !==
|
|
647
|
+
if (totalEdgeOps !== planOpsLength) {
|
|
638
648
|
throw new Error(
|
|
639
|
-
`Ledger write: plan.operations length (${
|
|
649
|
+
`Ledger write: plan.operations length (${planOpsLength}) does not match sum of migrationEdges operationCount (${totalEdgeOps})`,
|
|
640
650
|
);
|
|
641
651
|
}
|
|
642
652
|
// The ledger records the operations as executed — idempotency-skipped ops
|
|
@@ -688,12 +698,8 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
688
698
|
|
|
689
699
|
private async executeStatement(
|
|
690
700
|
driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],
|
|
691
|
-
statement:
|
|
701
|
+
statement: SqlExecuteRequest,
|
|
692
702
|
): Promise<void> {
|
|
693
|
-
|
|
694
|
-
await driver.query(statement.sql, statement.params);
|
|
695
|
-
return;
|
|
696
|
-
}
|
|
697
|
-
await driver.query(statement.sql);
|
|
703
|
+
await driver.query(statement.sql, statement.params);
|
|
698
704
|
}
|
|
699
705
|
}
|
|
@@ -17,9 +17,7 @@ import {
|
|
|
17
17
|
import type { SqlNamespaceTablesInput, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
18
18
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
19
19
|
import type { JsonObject } from '@prisma-next/utils/json';
|
|
20
|
-
import type { Type } from 'arktype';
|
|
21
20
|
import { postgresAuthoringEntityTypes } from './authoring';
|
|
22
|
-
import type { PostgresEnumType } from './postgres-enum-type';
|
|
23
21
|
import { isPostgresSchema, PostgresSchema } from './postgres-schema';
|
|
24
22
|
|
|
25
23
|
const POSTGRES_AUTHORING_CTX: AuthoringEntityContext = {
|
|
@@ -38,27 +36,21 @@ function isAuthoringEntityTypeFactoryOutput(
|
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
/**
|
|
41
|
-
* Walks a pack's entity-type namespace tree and emits
|
|
42
|
-
*
|
|
43
|
-
*
|
|
39
|
+
* Walks a pack's entity-type namespace tree and emits hydration factories
|
|
40
|
+
* keyed by the descriptor's `discriminator`. Used for `storage.types`
|
|
41
|
+
* (codec-triple hydration). Namespace entries hydration dispatches by
|
|
42
|
+
* entries key, not discriminator — handled by `hydrateEntriesKind`.
|
|
44
43
|
*/
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const entityTypeRegistry = new Map<string, SqlEntityHydrationFactory>();
|
|
50
|
-
const validatorFragments = new Map<string, Type<unknown>>();
|
|
44
|
+
function collectStorageTypesHydrators(
|
|
45
|
+
namespace: AuthoringEntityTypeNamespace,
|
|
46
|
+
): ReadonlyMap<string, SqlEntityHydrationFactory> {
|
|
47
|
+
const registry = new Map<string, SqlEntityHydrationFactory>();
|
|
51
48
|
const walk = (node: AuthoringEntityTypeNamespace): void => {
|
|
52
49
|
for (const value of Object.values(node)) {
|
|
53
50
|
if (isAuthoringEntityTypeDescriptor(value)) {
|
|
54
51
|
if (isAuthoringEntityTypeFactoryOutput(value.output)) {
|
|
55
52
|
const { factory } = value.output;
|
|
56
|
-
|
|
57
|
-
factory(raw, POSTGRES_AUTHORING_CTX),
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
if (value.validatorSchema !== undefined) {
|
|
61
|
-
validatorFragments.set(value.discriminator, value.validatorSchema);
|
|
53
|
+
registry.set(value.discriminator, (raw) => factory(raw, POSTGRES_AUTHORING_CTX));
|
|
62
54
|
}
|
|
63
55
|
continue;
|
|
64
56
|
}
|
|
@@ -68,15 +60,13 @@ function collectEntityRegistryContributions(namespace: AuthoringEntityTypeNamesp
|
|
|
68
60
|
}
|
|
69
61
|
};
|
|
70
62
|
walk(namespace);
|
|
71
|
-
return
|
|
63
|
+
return registry;
|
|
72
64
|
}
|
|
73
65
|
|
|
74
66
|
export class PostgresContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {
|
|
75
67
|
constructor() {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
);
|
|
79
|
-
super(entityTypeRegistry, validatorFragments);
|
|
68
|
+
const storageTypesHydrators = collectStorageTypesHydrators(postgresAuthoringEntityTypes);
|
|
69
|
+
super(storageTypesHydrators);
|
|
80
70
|
}
|
|
81
71
|
|
|
82
72
|
protected override hydrateSqlNamespaceEntry(
|
|
@@ -88,40 +78,22 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
88
78
|
}
|
|
89
79
|
const hydrated = blindCast<
|
|
90
80
|
SqlNamespaceTablesInput,
|
|
91
|
-
'super.hydrateSqlNamespaceEntry returns
|
|
81
|
+
'super.hydrateSqlNamespaceEntry returns SqlNamespaceTablesInput when raw is not a NamespaceBase'
|
|
92
82
|
>(super.hydrateSqlNamespaceEntry(nsId, raw));
|
|
93
83
|
const { id, entries } = hydrated;
|
|
94
84
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
let typeSlot: Record<string, PostgresEnumType> | undefined;
|
|
100
|
-
if (rawEntries !== null && typeof rawEntries === 'object' && !Array.isArray(rawEntries)) {
|
|
101
|
-
const rawTypeSlot = (rawEntries as Record<string, unknown>)['type'];
|
|
102
|
-
if (rawTypeSlot !== null && typeof rawTypeSlot === 'object' && !Array.isArray(rawTypeSlot)) {
|
|
103
|
-
const enumFactory = this.entityTypeRegistry.get('postgres-enum');
|
|
104
|
-
typeSlot = Object.fromEntries(
|
|
105
|
-
Object.entries(rawTypeSlot as Record<string, unknown>).map(([name, entry]) => [
|
|
106
|
-
name,
|
|
107
|
-
blindCast<PostgresEnumType, 'postgres-enum factory returns PostgresEnumType'>(
|
|
108
|
-
enumFactory !== undefined ? enumFactory(entry) : entry,
|
|
109
|
-
),
|
|
110
|
-
]),
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const emptyTables = Object.keys(entries.table).length === 0;
|
|
116
|
-
const emptyTypes = !typeSlot || Object.keys(typeSlot).length === 0;
|
|
117
|
-
if (id === UNBOUND_NAMESPACE_ID && emptyTables && emptyTypes) {
|
|
85
|
+
const valueSetSlot = entries['valueSet'];
|
|
86
|
+
const hasValueSets = valueSetSlot !== undefined && Object.keys(valueSetSlot).length > 0;
|
|
87
|
+
const emptyTables = Object.keys(entries['table'] ?? {}).length === 0;
|
|
88
|
+
if (id === UNBOUND_NAMESPACE_ID && emptyTables && !hasValueSets) {
|
|
118
89
|
return PostgresSchema.unbound;
|
|
119
90
|
}
|
|
120
91
|
return new PostgresSchema({
|
|
121
92
|
id,
|
|
122
93
|
entries: {
|
|
123
|
-
|
|
124
|
-
|
|
94
|
+
...entries,
|
|
95
|
+
table: entries['table'] ?? {},
|
|
96
|
+
...(hasValueSets ? { valueSet: valueSetSlot } : {}),
|
|
125
97
|
},
|
|
126
98
|
});
|
|
127
99
|
}
|
|
@@ -139,7 +111,7 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
139
111
|
kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
|
|
140
112
|
entries: {
|
|
141
113
|
table: Object.fromEntries(
|
|
142
|
-
Object.entries(ns.entries.table).map(([tableName, table]) => [
|
|
114
|
+
Object.entries(ns.entries.table ?? {}).map(([tableName, table]) => [
|
|
143
115
|
tableName,
|
|
144
116
|
this.serializeJsonValue(table) as JsonObject,
|
|
145
117
|
]),
|
|
@@ -167,19 +139,25 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
167
139
|
|
|
168
140
|
private serializePostgresNamespace(ns: PostgresSchema, isUnboundSlot: boolean): JsonObject {
|
|
169
141
|
const tablesOut: Record<string, JsonObject> = {};
|
|
170
|
-
for (const [tableName, table] of Object.entries(ns.
|
|
142
|
+
for (const [tableName, table] of Object.entries(ns.table)) {
|
|
171
143
|
tablesOut[tableName] = this.serializeJsonValue(table) as JsonObject;
|
|
172
144
|
}
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
145
|
+
const valueSetEntries = ns.valueSet;
|
|
146
|
+
const valueSetOut: Record<string, JsonObject> = {};
|
|
147
|
+
if (valueSetEntries !== undefined) {
|
|
148
|
+
for (const [valueSetName, valueSet] of Object.entries(valueSetEntries)) {
|
|
149
|
+
valueSetOut[valueSetName] = blindCast<
|
|
150
|
+
JsonObject,
|
|
151
|
+
'serializeJsonValue round-trips the value-set node through JSON, yielding a JsonObject'
|
|
152
|
+
>(this.serializeJsonValue(valueSet));
|
|
153
|
+
}
|
|
176
154
|
}
|
|
177
155
|
return {
|
|
178
156
|
id: ns.id,
|
|
179
157
|
kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
|
|
180
158
|
entries: {
|
|
181
159
|
table: tablesOut,
|
|
182
|
-
|
|
160
|
+
...(Object.keys(valueSetOut).length > 0 ? { valueSet: valueSetOut } : {}),
|
|
183
161
|
},
|
|
184
162
|
};
|
|
185
163
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type } from 'arktype';
|
|
2
|
+
|
|
3
|
+
const ControlPolicySchema = type("'managed' | 'tolerated' | 'external' | 'observed'");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Arktype validator for a `postgres-enum` entry under
|
|
7
|
+
* `storage.namespaces[id].entries.type[name]`. Registered by the Postgres
|
|
8
|
+
* target pack against the `'type'` entries key so the family-layer namespace
|
|
9
|
+
* validator accepts (and rejects) entries of this kind.
|
|
10
|
+
*/
|
|
11
|
+
export const PostgresEnumTypeSchema = type({
|
|
12
|
+
kind: "'postgres-enum'",
|
|
13
|
+
'name?': 'string',
|
|
14
|
+
'nativeType?': 'string',
|
|
15
|
+
values: type.string.array().readonly(),
|
|
16
|
+
'control?': ControlPolicySchema,
|
|
17
|
+
});
|
|
@@ -4,21 +4,20 @@ import {
|
|
|
4
4
|
UNBOUND_NAMESPACE_ID,
|
|
5
5
|
} from '@prisma-next/framework-components/ir';
|
|
6
6
|
import {
|
|
7
|
-
type PostgresEnumStorageEntry,
|
|
8
7
|
type SqlNamespaceTablesInput,
|
|
9
8
|
type SqlStorage,
|
|
10
9
|
StorageTable,
|
|
11
10
|
type StorageTableInput,
|
|
11
|
+
StorageValueSet,
|
|
12
|
+
type StorageValueSetInput,
|
|
12
13
|
} from '@prisma-next/sql-contract/types';
|
|
13
|
-
import {
|
|
14
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
15
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
14
16
|
import { escapeLiteral } from './sql-utils';
|
|
15
17
|
|
|
16
18
|
export interface PostgresSchemaInput {
|
|
17
19
|
readonly id: string;
|
|
18
|
-
readonly entries:
|
|
19
|
-
readonly table: Record<string, StorageTable | StorageTableInput>;
|
|
20
|
-
readonly type: Record<string, PostgresEnumType | PostgresEnumTypeInput>;
|
|
21
|
-
};
|
|
20
|
+
readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
/**
|
|
@@ -27,7 +26,7 @@ export interface PostgresSchemaInput {
|
|
|
27
26
|
* `namespaces: Record<NamespaceId, PostgresSchema>` map populated by
|
|
28
27
|
* the Postgres PSL interpreter from `namespace { … }` AST buckets.
|
|
29
28
|
*
|
|
30
|
-
* `entries` holds entity-kind
|
|
29
|
+
* `entries` holds entity-kind maps (`table`, `valueSet`). Qualifier
|
|
31
30
|
* emission is the rendering seam: DDL / SQL emission asks the namespace
|
|
32
31
|
* for its qualifier (`"<schema>"`) or for a qualified table name
|
|
33
32
|
* (`"<schema>"."<table>"`) and consumes the result polymorphically.
|
|
@@ -47,31 +46,49 @@ export class PostgresSchema extends NamespaceBase {
|
|
|
47
46
|
|
|
48
47
|
declare readonly kind: 'schema';
|
|
49
48
|
readonly id: string;
|
|
50
|
-
readonly entries: Readonly<
|
|
51
|
-
readonly table: Readonly<Record<string, StorageTable>>;
|
|
52
|
-
readonly type: Readonly<Record<string, PostgresEnumType>>;
|
|
53
|
-
}>;
|
|
49
|
+
readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
54
50
|
|
|
55
51
|
constructor(input: PostgresSchemaInput) {
|
|
56
52
|
super();
|
|
57
53
|
this.id = input.id;
|
|
54
|
+
|
|
55
|
+
const carried: Record<string, Readonly<Record<string, unknown>>> = {};
|
|
56
|
+
let table: Readonly<Record<string, StorageTable>> = Object.freeze({});
|
|
57
|
+
let valueSet: Readonly<Record<string, StorageValueSet>> | undefined;
|
|
58
|
+
for (const [kind, rawMap] of Object.entries(input.entries)) {
|
|
59
|
+
if (kind === 'table') {
|
|
60
|
+
const tableMap: Record<string, StorageTable> = {};
|
|
61
|
+
for (const [name, v] of Object.entries(
|
|
62
|
+
blindCast<
|
|
63
|
+
Record<string, StorageTableInput>,
|
|
64
|
+
'entries[table] holds StorageTableInput by construction'
|
|
65
|
+
>(rawMap),
|
|
66
|
+
)) {
|
|
67
|
+
tableMap[name] = new StorageTable(v);
|
|
68
|
+
}
|
|
69
|
+
table = Object.freeze(tableMap);
|
|
70
|
+
} else if (kind === 'valueSet') {
|
|
71
|
+
const vsMap: Record<string, StorageValueSet> = {};
|
|
72
|
+
for (const [name, v] of Object.entries(
|
|
73
|
+
blindCast<
|
|
74
|
+
Record<string, StorageValueSetInput>,
|
|
75
|
+
'entries[valueSet] holds StorageValueSetInput by construction'
|
|
76
|
+
>(rawMap),
|
|
77
|
+
)) {
|
|
78
|
+
vsMap[name] = new StorageValueSet(v);
|
|
79
|
+
}
|
|
80
|
+
if (Object.keys(vsMap).length > 0) {
|
|
81
|
+
valueSet = Object.freeze(vsMap);
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
carried[kind] = Object.freeze(rawMap);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
58
88
|
this.entries = Object.freeze({
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
k,
|
|
63
|
-
v instanceof StorageTable ? v : new StorageTable(v as StorageTableInput),
|
|
64
|
-
]),
|
|
65
|
-
),
|
|
66
|
-
),
|
|
67
|
-
type: Object.freeze(
|
|
68
|
-
Object.fromEntries(
|
|
69
|
-
Object.entries(input.entries.type).map(([k, v]) => [
|
|
70
|
-
k,
|
|
71
|
-
v instanceof PostgresEnumType ? v : new PostgresEnumType(v as PostgresEnumTypeInput),
|
|
72
|
-
]),
|
|
73
|
-
),
|
|
74
|
-
),
|
|
89
|
+
...carried,
|
|
90
|
+
table,
|
|
91
|
+
...ifDefined('valueSet', valueSet),
|
|
75
92
|
});
|
|
76
93
|
Object.defineProperty(this, 'kind', {
|
|
77
94
|
value: 'schema',
|
|
@@ -82,6 +99,14 @@ export class PostgresSchema extends NamespaceBase {
|
|
|
82
99
|
freezeNode(this);
|
|
83
100
|
}
|
|
84
101
|
|
|
102
|
+
get table(): Readonly<Record<string, StorageTable>> {
|
|
103
|
+
return this.entries['table'] ?? Object.freeze({});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get valueSet(): Readonly<Record<string, StorageValueSet>> | undefined {
|
|
107
|
+
return this.entries['valueSet'] as Readonly<Record<string, StorageValueSet>> | undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
85
110
|
/**
|
|
86
111
|
* The bare schema qualifier as it would appear in a rendered SQL
|
|
87
112
|
* fragment (already quoted). The unbound-schema singleton overrides
|
|
@@ -162,7 +187,7 @@ export class PostgresUnboundSchema extends PostgresSchema {
|
|
|
162
187
|
static readonly instance: PostgresUnboundSchema = new PostgresUnboundSchema();
|
|
163
188
|
|
|
164
189
|
constructor(input?: PostgresSchemaInput) {
|
|
165
|
-
super(input ?? { id: UNBOUND_NAMESPACE_ID, entries: { table: {}
|
|
190
|
+
super(input ?? { id: UNBOUND_NAMESPACE_ID, entries: { table: {} } });
|
|
166
191
|
}
|
|
167
192
|
|
|
168
193
|
override qualifier(): string {
|
|
@@ -204,15 +229,12 @@ export function isPostgresSchema(ns: unknown): ns is PostgresSchema {
|
|
|
204
229
|
* by reference and trust the resulting `SqlStorage.namespaces` map to
|
|
205
230
|
* be value-stable for a given input set.
|
|
206
231
|
*/
|
|
207
|
-
export function postgresCreateNamespace(
|
|
208
|
-
input: SqlNamespaceTablesInput,
|
|
209
|
-
enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>,
|
|
210
|
-
): PostgresSchema {
|
|
232
|
+
export function postgresCreateNamespace(input: SqlNamespaceTablesInput): PostgresSchema {
|
|
211
233
|
const schemaInput: PostgresSchemaInput = {
|
|
212
234
|
id: input.id,
|
|
213
235
|
entries: {
|
|
214
|
-
|
|
215
|
-
|
|
236
|
+
...input.entries,
|
|
237
|
+
table: input.entries['table'] ?? {},
|
|
216
238
|
},
|
|
217
239
|
};
|
|
218
240
|
if (input.id === UNBOUND_NAMESPACE_ID) {
|
package/src/exports/codecs.ts
CHANGED
|
@@ -2,7 +2,6 @@ export type {
|
|
|
2
2
|
PgBitDescriptor,
|
|
3
3
|
PgBoolDescriptor,
|
|
4
4
|
PgCharDescriptor,
|
|
5
|
-
PgEnumDescriptor,
|
|
6
5
|
PgFloat4Descriptor,
|
|
7
6
|
PgFloat8Descriptor,
|
|
8
7
|
PgFloatDescriptor,
|
|
@@ -19,6 +18,7 @@ export type {
|
|
|
19
18
|
PgTimestampDescriptor,
|
|
20
19
|
PgTimestamptzDescriptor,
|
|
21
20
|
PgTimetzDescriptor,
|
|
21
|
+
PgUuidDescriptor,
|
|
22
22
|
PgVarbitDescriptor,
|
|
23
23
|
PgVarcharDescriptor,
|
|
24
24
|
} from '../core/codecs';
|
|
@@ -26,7 +26,6 @@ export {
|
|
|
26
26
|
pgBitColumn,
|
|
27
27
|
pgBoolColumn,
|
|
28
28
|
pgCharColumn,
|
|
29
|
-
pgEnumColumn,
|
|
30
29
|
pgFloat4Column,
|
|
31
30
|
pgFloat8Column,
|
|
32
31
|
pgFloatColumn,
|
|
@@ -43,6 +42,7 @@ export {
|
|
|
43
42
|
pgTimestampColumn,
|
|
44
43
|
pgTimestamptzColumn,
|
|
45
44
|
pgTimetzColumn,
|
|
45
|
+
pgUuidColumn,
|
|
46
46
|
pgVarbitColumn,
|
|
47
47
|
pgVarcharColumn,
|
|
48
48
|
} from '../core/codecs';
|
|
@@ -3,5 +3,5 @@ export {
|
|
|
3
3
|
buildControlTableBootstrapQueries,
|
|
4
4
|
buildSignMarkerBootstrapQueries,
|
|
5
5
|
} from '../contract-free/control-bootstrap';
|
|
6
|
-
export { createSchema, createTable } from '../contract-free/ddl';
|
|
6
|
+
export { addColumnAction, alterTable, createSchema, createTable } from '../contract-free/ddl';
|
|
7
7
|
export { PostgresTableSource } from '../core/ast/table-source';
|
package/src/exports/control.ts
CHANGED
|
@@ -10,10 +10,6 @@ import type {
|
|
|
10
10
|
import type { SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';
|
|
11
11
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
12
12
|
import { postgresTargetDescriptorMeta } from '../core/descriptor-meta';
|
|
13
|
-
import {
|
|
14
|
-
enumStorageCompoundKey,
|
|
15
|
-
resolveDdlSchemaForNamespaceStorage,
|
|
16
|
-
} from '../core/migrations/enum-planning';
|
|
17
13
|
import { createPostgresMigrationPlanner } from '../core/migrations/planner';
|
|
18
14
|
import { renderDefaultLiteral } from '../core/migrations/planner-ddl-builders';
|
|
19
15
|
import type { PostgresPlanTargetDetails } from '../core/migrations/planner-target-details';
|
|
@@ -34,12 +30,6 @@ function buildNativeTypeExpander(
|
|
|
34
30
|
readonly typeParams?: Record<string, unknown>;
|
|
35
31
|
}) => {
|
|
36
32
|
if (!input.typeParams) return input.nativeType;
|
|
37
|
-
// Mirror `renderExpectedNativeType` in verify-sql-schema: when a codec
|
|
38
|
-
// has no `expandNativeType` hook (e.g. `pg/enum@1`, whose typeParams
|
|
39
|
-
// describe the value set rather than a DDL suffix), fall back to the
|
|
40
|
-
// bare native type rather than throwing. Throwing here would reject
|
|
41
|
-
// every plan involving an enum-/values-typed column as soon as its
|
|
42
|
-
// `typeRef` resolved to a `StorageTypeInstance` carrying typeParams.
|
|
43
33
|
if (!input.codecId) return input.nativeType;
|
|
44
34
|
const hooks = codecHooks.get(input.codecId);
|
|
45
35
|
if (!hooks?.expandNativeType) return input.nativeType;
|
|
@@ -80,18 +70,6 @@ const postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresP
|
|
|
80
70
|
annotationNamespace: 'pg',
|
|
81
71
|
...ifDefined('expandNativeType', expander),
|
|
82
72
|
renderDefault: postgresRenderDefault,
|
|
83
|
-
// Schema-qualify enum annotation keys so the projected "from" IR's
|
|
84
|
-
// `storageTypes` match `readExistingEnumValues` on the read side
|
|
85
|
-
// (the contract-to-contract `migration plan` path). The DDL-schema
|
|
86
|
-
// resolution + compound-key format stay here in the target layer;
|
|
87
|
-
// the family projector treats the returned string as opaque.
|
|
88
|
-
// `undefined` schema IR ⇒ the unbound coordinate resolves to the
|
|
89
|
-
// default `public` landing schema, matching the read-side fallback.
|
|
90
|
-
resolveEnumStorageKey: (storage, namespaceId, nativeType) =>
|
|
91
|
-
enumStorageCompoundKey(
|
|
92
|
-
resolveDdlSchemaForNamespaceStorage(storage, namespaceId, undefined),
|
|
93
|
-
nativeType,
|
|
94
|
-
),
|
|
95
73
|
});
|
|
96
74
|
},
|
|
97
75
|
},
|