@prisma-next/target-postgres 0.14.0-dev.6 → 0.14.0-dev.61
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/authoring-BLkL4fFG.mjs +528 -0
- package/dist/authoring-BLkL4fFG.mjs.map +1 -0
- package/dist/canonicalize-CAbXtVtB.d.mts +37 -0
- package/dist/canonicalize-CAbXtVtB.d.mts.map +1 -0
- package/dist/{codec-ids-CnXu9Qy3.d.mts → codec-ids-BzrFF-I4.d.mts} +3 -2
- package/dist/codec-ids-BzrFF-I4.d.mts.map +1 -0
- package/dist/{codec-ids-BvytN2P8.mjs → codec-ids-C_-Hj6bL.mjs} +3 -2
- package/dist/codec-ids-C_-Hj6bL.mjs.map +1 -0
- package/dist/codec-ids.d.mts +2 -2
- package/dist/codec-ids.mjs +2 -2
- package/dist/{codec-types-DHCkwPKE.d.mts → codec-types-BiIWziRO.d.mts} +3 -2
- package/dist/codec-types-BiIWziRO.d.mts.map +1 -0
- package/dist/codec-types.d.mts +1 -1
- package/dist/codecs-CkVQrZ4G.mjs +913 -0
- package/dist/codecs-CkVQrZ4G.mjs.map +1 -0
- package/dist/{codecs--0A5_4Bq.d.mts → codecs-Cm-nS4mQ.d.mts} +111 -4
- package/dist/codecs-Cm-nS4mQ.d.mts.map +1 -0
- package/dist/codecs.d.mts +2 -2
- package/dist/codecs.mjs +3 -757
- package/dist/codecs.mjs.map +1 -1
- package/dist/contract-free.d.mts +33 -3
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +4 -4
- package/dist/control-policy-BpmChlAK.mjs +1151 -0
- package/dist/control-policy-BpmChlAK.mjs.map +1 -0
- package/dist/control.d.mts +2 -2
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +901 -35
- package/dist/control.mjs.map +1 -1
- package/dist/data-transform-BOWpliq8.mjs.map +1 -1
- package/dist/{data-transform-DDgWdB5o.d.mts → data-transform-DPzwBMhW.d.mts} +3 -3
- package/dist/{data-transform-DDgWdB5o.d.mts.map → data-transform-DPzwBMhW.d.mts.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/{ddl-QDyOSeLc.mjs → ddl-BovUVFVi.mjs} +77 -6
- package/dist/ddl-BovUVFVi.mjs.map +1 -0
- package/dist/ddl.d.mts +3 -2
- package/dist/ddl.mjs +2 -2
- package/dist/default-normalizer.d.mts +1 -1
- package/dist/default-normalizer.d.mts.map +1 -1
- package/dist/default-normalizer.mjs +247 -1
- package/dist/default-normalizer.mjs.map +1 -0
- package/dist/descriptor-meta-C1T4BXJ8.mjs +22 -0
- package/dist/descriptor-meta-C1T4BXJ8.mjs.map +1 -0
- package/dist/descriptor-meta-runtime-UwYdV8fD.mjs +12 -0
- package/dist/descriptor-meta-runtime-UwYdV8fD.mjs.map +1 -0
- package/dist/diff-database-schema-RMwnSOnz.mjs +298 -0
- package/dist/diff-database-schema-RMwnSOnz.mjs.map +1 -0
- package/dist/diff-database-schema.d.mts +46 -0
- package/dist/diff-database-schema.d.mts.map +1 -0
- package/dist/diff-database-schema.mjs +2 -0
- package/dist/errors-DO-w0EUS.mjs +35 -0
- package/dist/errors-DO-w0EUS.mjs.map +1 -0
- package/dist/errors.d.mts +11 -9
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/issue-planner.d.mts +35 -11
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +2 -2
- package/dist/migration.d.mts +5 -5
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +4 -4
- package/dist/namespace-ids-xtp_ZY86.mjs +7 -0
- package/dist/namespace-ids-xtp_ZY86.mjs.map +1 -0
- package/dist/native-type-normalizer.mjs +37 -1
- package/dist/native-type-normalizer.mjs.map +1 -0
- package/dist/nodes-B815pj_X.mjs +162 -0
- package/dist/nodes-B815pj_X.mjs.map +1 -0
- package/dist/nodes-BtQyZha6.d.mts +146 -0
- package/dist/nodes-BtQyZha6.d.mts.map +1 -0
- package/dist/{op-factory-call-D_p5vxwt.mjs → op-factory-call-CI00nS4z.mjs} +300 -31
- package/dist/op-factory-call-CI00nS4z.mjs.map +1 -0
- package/dist/{op-factory-call-DmQEc3XV.d.mts → op-factory-call-D6_7-7Vc.d.mts} +68 -15
- package/dist/op-factory-call-D6_7-7Vc.d.mts.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 +287 -3
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/planner-CAHZN1Ez.mjs +422 -0
- package/dist/planner-CAHZN1Ez.mjs.map +1 -0
- package/dist/{planner-ddl-builders-B2wOwLqI.mjs → planner-ddl-builders-B8Nn6nHN.mjs} +12 -27
- package/dist/planner-ddl-builders-B8Nn6nHN.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +4 -6
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +2 -2
- package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -1
- package/dist/planner-identity-values.d.mts +8 -2
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +2 -2
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts → planner-produced-postgres-migration-a-tjfKsA.d.mts} +4 -4
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts.map → planner-produced-postgres-migration-a-tjfKsA.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs → planner-produced-postgres-migration-flkG4Y7n.mjs} +3 -3
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs.map → planner-produced-postgres-migration-flkG4Y7n.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-sql-checks-jqUUGyQR.mjs → planner-sql-checks-C1-Kk3Eu.mjs} +2 -2
- package/dist/{planner-sql-checks-jqUUGyQR.mjs.map → planner-sql-checks-C1-Kk3Eu.mjs.map} +1 -1
- 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-target-details-CIY6tLeo.d.mts → planner-target-details-HkP4RrRO.d.mts} +2 -2
- package/dist/planner-target-details-HkP4RrRO.d.mts.map +1 -0
- package/dist/planner-target-details.d.mts +1 -1
- package/dist/planner.d.mts +72 -17
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +3 -2
- package/dist/postgres-contract-view-C9j5cqP0.d.mts +34 -0
- package/dist/postgres-contract-view-C9j5cqP0.d.mts.map +1 -0
- package/dist/{postgres-contract-serializer-k3TAcPMY.mjs → postgres-contract-view-DWLNQbdR.mjs} +45 -41
- package/dist/postgres-contract-view-DWLNQbdR.mjs.map +1 -0
- package/dist/postgres-database-schema-node-BVdOffjC.d.mts +221 -0
- package/dist/postgres-database-schema-node-BVdOffjC.d.mts.map +1 -0
- package/dist/{postgres-migration-Y4YBJqkS.d.mts → postgres-migration-Bzzi0Asr.d.mts} +28 -9
- package/dist/postgres-migration-Bzzi0Asr.d.mts.map +1 -0
- package/dist/{postgres-migration-B5jKrXv3.mjs → postgres-migration-C92swCzd.mjs} +53 -45
- package/dist/postgres-migration-C92swCzd.mjs.map +1 -0
- package/dist/postgres-native-enum-xdiqmBf_.mjs +41 -0
- package/dist/postgres-native-enum-xdiqmBf_.mjs.map +1 -0
- package/dist/postgres-rls-policy--CSddvMR.d.mts +52 -0
- package/dist/postgres-rls-policy--CSddvMR.d.mts.map +1 -0
- package/dist/postgres-role-schema-node-BmCboEa_.mjs +198 -0
- package/dist/postgres-role-schema-node-BmCboEa_.mjs.map +1 -0
- package/dist/{postgres-schema-COGZ1ark.mjs → postgres-schema-COEca21H.mjs} +188 -10
- package/dist/postgres-schema-COEca21H.mjs.map +1 -0
- package/dist/postgres-schema-DsrtYp2v.d.mts +269 -0
- package/dist/postgres-schema-DsrtYp2v.d.mts.map +1 -0
- package/dist/postgres-table-schema-node-9FCtCUz2.mjs +153 -0
- package/dist/postgres-table-schema-node-9FCtCUz2.mjs.map +1 -0
- package/dist/render-ops.d.mts +1 -1
- package/dist/{render-typescript-KMgosran.mjs → render-typescript-7yqILcwr.mjs} +45 -16
- package/dist/render-typescript-7yqILcwr.mjs.map +1 -0
- package/dist/render-typescript.mjs +1 -1
- package/dist/resolve-ddl-schema-ZkKxt2Fm.mjs +22 -0
- package/dist/resolve-ddl-schema-ZkKxt2Fm.mjs.map +1 -0
- package/dist/rls-canonicalize.d.mts +20 -0
- package/dist/rls-canonicalize.d.mts.map +1 -0
- package/dist/rls-canonicalize.mjs +2 -0
- package/dist/runtime.d.mts +6 -8
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema-ir-annotations.d.mts +15 -0
- package/dist/schema-ir-annotations.d.mts.map +1 -0
- package/dist/schema-ir-annotations.mjs +2 -0
- package/dist/types.d.mts +4 -140
- package/dist/types.mjs +5 -2
- package/dist/wire-name-rHHtr1h0.mjs +75 -0
- package/dist/wire-name-rHHtr1h0.mjs.map +1 -0
- package/package.json +23 -17
- package/src/contract-free/checks.ts +73 -0
- package/src/contract-free/ddl.ts +71 -1
- package/src/core/authoring.ts +467 -2
- package/src/core/codec-ids.ts +1 -0
- package/src/core/codec-type-map.ts +2 -0
- package/src/core/codecs.ts +180 -1
- package/src/core/ddl/nodes.ts +141 -2
- package/src/core/default-normalizer.ts +122 -2
- package/src/core/descriptor-meta.ts +10 -1
- package/src/core/entity-kinds.ts +41 -0
- package/src/core/errors.ts +14 -12
- package/src/core/migrations/bound-schema.ts +10 -0
- package/src/core/migrations/column-ddl-rendering.ts +117 -0
- package/src/core/migrations/contract-to-postgres-database-schema-node.ts +160 -0
- package/src/core/migrations/control-policy.ts +126 -44
- package/src/core/migrations/diff-database-schema.ts +253 -0
- package/src/core/migrations/issue-planner.ts +692 -652
- package/src/core/migrations/op-factory-call.ts +189 -21
- package/src/core/migrations/operations/columns.ts +24 -12
- package/src/core/migrations/operations/constraints.ts +1 -1
- package/src/core/migrations/operations/data-transform.ts +6 -0
- package/src/core/migrations/operations/dependencies.ts +2 -1
- package/src/core/migrations/operations/rls.ts +187 -0
- package/src/core/migrations/operations/shared.ts +0 -30
- package/src/core/migrations/planner-ddl-builders.ts +20 -58
- package/src/core/migrations/planner-identity-values.ts +1 -1
- package/src/core/migrations/planner-recipes.ts +31 -13
- package/src/core/migrations/planner-sql-checks.ts +1 -1
- package/src/core/migrations/planner-strategies.ts +248 -216
- package/src/core/migrations/planner-target-details.ts +3 -1
- package/src/core/migrations/planner.ts +386 -59
- package/src/core/migrations/postgres-migration.ts +70 -86
- package/src/core/migrations/render-typescript.ts +42 -15
- package/src/core/migrations/resolve-ddl-schema.ts +26 -0
- package/src/core/migrations/runner.ts +10 -16
- package/src/core/migrations/verify-postgres-namespaces.ts +47 -31
- package/src/core/namespace-ids.ts +3 -0
- package/src/core/postgres-contract-serializer.ts +46 -71
- package/src/core/postgres-contract-view.ts +48 -0
- package/src/core/postgres-native-enum.ts +51 -0
- package/src/core/postgres-rls-enablement.ts +34 -0
- package/src/core/postgres-rls-policy.ts +64 -0
- package/src/core/postgres-role.ts +59 -0
- package/src/core/postgres-schema-verifier.ts +10 -7
- package/src/core/postgres-schema.ts +64 -15
- package/src/core/postgres-validators.ts +34 -0
- package/src/core/psl-infer/infer-psl-contract.ts +1326 -0
- package/src/core/psl-infer/postgres-default-mapping.ts +16 -0
- package/src/core/psl-infer/postgres-type-map.ts +128 -0
- package/src/core/rls/canonicalize.ts +48 -0
- package/src/core/rls/wire-name.ts +33 -0
- package/src/core/schema-ir/postgres-database-schema-node.ts +61 -0
- package/src/core/schema-ir/postgres-namespace-schema-node.ts +79 -0
- package/src/core/schema-ir/postgres-policy-schema-node.ts +90 -0
- package/src/core/schema-ir/postgres-role-schema-node.ts +65 -0
- package/src/core/schema-ir/postgres-table-schema-node.ts +140 -0
- package/src/core/schema-ir/schema-node-kinds.ts +113 -0
- package/src/exports/codecs.ts +3 -0
- package/src/exports/contract-free.ts +11 -1
- package/src/exports/control.ts +27 -33
- package/src/exports/ddl.ts +6 -0
- package/src/exports/diff-database-schema.ts +7 -0
- package/src/exports/issue-planner.ts +1 -1
- package/src/exports/migration.ts +1 -0
- package/src/exports/op-factory-call.ts +1 -0
- package/src/exports/planner-ddl-builders.ts +0 -2
- package/src/exports/planner-identity-values.ts +4 -1
- package/src/exports/planner.ts +1 -0
- package/src/exports/rls-canonicalize.ts +7 -0
- package/src/exports/runtime.ts +1 -0
- package/src/exports/schema-ir-annotations.ts +1 -0
- package/src/exports/types.ts +34 -0
- package/dist/codec-ids-BvytN2P8.mjs.map +0 -1
- package/dist/codec-ids-CnXu9Qy3.d.mts.map +0 -1
- package/dist/codec-types-DHCkwPKE.d.mts.map +0 -1
- package/dist/codecs--0A5_4Bq.d.mts.map +0 -1
- package/dist/ddl-QDyOSeLc.mjs.map +0 -1
- package/dist/default-normalizer-DyyCHQWs.mjs +0 -131
- package/dist/default-normalizer-DyyCHQWs.mjs.map +0 -1
- package/dist/descriptor-meta-CpGygXpI.mjs +0 -140
- package/dist/descriptor-meta-CpGygXpI.mjs.map +0 -1
- package/dist/errors-CUk87ByX.mjs +0 -33
- package/dist/errors-CUk87ByX.mjs.map +0 -1
- package/dist/issue-planner-DL6g3CmE.mjs +0 -824
- package/dist/issue-planner-DL6g3CmE.mjs.map +0 -1
- package/dist/native-type-normalizer-Bc9XJzWC.mjs +0 -38
- package/dist/native-type-normalizer-Bc9XJzWC.mjs.map +0 -1
- package/dist/nodes-Bbhs2rwj.mjs +0 -76
- package/dist/nodes-Bbhs2rwj.mjs.map +0 -1
- package/dist/nodes-pLeLgdis.d.mts +0 -67
- package/dist/nodes-pLeLgdis.d.mts.map +0 -1
- package/dist/op-factory-call-D_p5vxwt.mjs.map +0 -1
- package/dist/op-factory-call-DmQEc3XV.d.mts.map +0 -1
- package/dist/planner-Bs_baQax.mjs +0 -324
- package/dist/planner-Bs_baQax.mjs.map +0 -1
- package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +0 -1
- package/dist/planner-target-details-CIY6tLeo.d.mts.map +0 -1
- package/dist/postgres-contract-serializer-k3TAcPMY.mjs.map +0 -1
- package/dist/postgres-migration-B5jKrXv3.mjs.map +0 -1
- package/dist/postgres-migration-Y4YBJqkS.d.mts.map +0 -1
- package/dist/postgres-schema-COGZ1ark.mjs.map +0 -1
- package/dist/render-typescript-KMgosran.mjs.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/src/core/postgres-enum-type-schema.ts +0 -17
|
@@ -3,9 +3,11 @@ import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control'
|
|
|
3
3
|
import type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';
|
|
4
4
|
import { Migration as SqlMigration } from '@prisma-next/family-sql/migration';
|
|
5
5
|
import type { ControlStack } from '@prisma-next/framework-components/control';
|
|
6
|
+
import { MigrationContractViews } from '@prisma-next/migration-tools/migration';
|
|
6
7
|
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
7
8
|
import type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';
|
|
8
9
|
import { errorPostgresMigrationStackMissing } from '../errors';
|
|
10
|
+
import { PostgresContractView } from '../postgres-contract-view';
|
|
9
11
|
import {
|
|
10
12
|
AddCheckConstraintCall,
|
|
11
13
|
AddColumnCall,
|
|
@@ -60,20 +62,31 @@ import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
|
60
62
|
* is an antipattern in a migration. (The unbound/unspecified namespace concept
|
|
61
63
|
* remains for SQLite, which has no schemas, and for Mongo's connection `db`.)
|
|
62
64
|
*/
|
|
63
|
-
export abstract class PostgresMigration
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
> {
|
|
65
|
+
export abstract class PostgresMigration<
|
|
66
|
+
Start extends Contract<SqlStorage> = Contract<SqlStorage>,
|
|
67
|
+
End extends Contract<SqlStorage> = Contract<SqlStorage>,
|
|
68
|
+
> extends SqlMigration<PostgresPlanTargetDetails, 'postgres', Start, End> {
|
|
67
69
|
readonly targetId = 'postgres' as const;
|
|
68
70
|
|
|
69
71
|
/**
|
|
70
72
|
* Materialized Postgres control adapter, created once per migration
|
|
71
73
|
* instance from the injected stack. `undefined` only when the migration
|
|
72
|
-
* was instantiated without a stack (test fixtures); `
|
|
73
|
-
* throws in that case to surface the misuse.
|
|
74
|
+
* was instantiated without a stack (test fixtures); `controlAdapterFor`
|
|
75
|
+
* throws a PN-MIG-2007 in that case to surface the misuse.
|
|
74
76
|
*/
|
|
75
77
|
protected readonly controlAdapter: SqlControlAdapter<'postgres'> | undefined;
|
|
76
78
|
|
|
79
|
+
#endView = new MigrationContractViews<PostgresContractView<End>>(
|
|
80
|
+
this,
|
|
81
|
+
'PostgresMigration',
|
|
82
|
+
(json) => PostgresContractView.fromJson<End>(json),
|
|
83
|
+
);
|
|
84
|
+
#startView = new MigrationContractViews<PostgresContractView<Start>>(
|
|
85
|
+
this,
|
|
86
|
+
'PostgresMigration',
|
|
87
|
+
(json) => PostgresContractView.fromJson<Start>(json),
|
|
88
|
+
);
|
|
89
|
+
|
|
77
90
|
constructor(stack?: ControlStack<'sql', 'postgres'>) {
|
|
78
91
|
super(stack);
|
|
79
92
|
// The descriptor `create()` is typed as the wider `ControlAdapterInstance`;
|
|
@@ -84,6 +97,35 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
84
97
|
: undefined;
|
|
85
98
|
}
|
|
86
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Returns the materialized control adapter, or throws a PN-MIG-2007 naming
|
|
102
|
+
* `operation` when the migration was constructed without a `ControlStack`.
|
|
103
|
+
* Single home for the null-check that every DDL/DML method shares.
|
|
104
|
+
*/
|
|
105
|
+
private controlAdapterFor(operation: string): SqlControlAdapter<'postgres'> {
|
|
106
|
+
if (!this.controlAdapter) {
|
|
107
|
+
throw errorPostgresMigrationStackMissing(operation);
|
|
108
|
+
}
|
|
109
|
+
return this.controlAdapter;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The typed, schema-qualified Postgres view over this migration's end-state
|
|
114
|
+
* contract — `this.endContract.namespace.<schema>.table.<name>`, etc. Throws
|
|
115
|
+
* if no `endContractJson` was provided.
|
|
116
|
+
*/
|
|
117
|
+
get endContract(): PostgresContractView<End> {
|
|
118
|
+
return this.#endView.endContract;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* The typed Postgres view over this migration's start-state contract, or
|
|
123
|
+
* `null` for a baseline migration (no `startContractJson`).
|
|
124
|
+
*/
|
|
125
|
+
get startContract(): PostgresContractView<Start> | null {
|
|
126
|
+
return this.#startView.startContract;
|
|
127
|
+
}
|
|
128
|
+
|
|
87
129
|
/**
|
|
88
130
|
* Instance-method wrapper around the free `dataTransform` factory that
|
|
89
131
|
* supplies the stored control adapter. Authors call this from inside
|
|
@@ -94,10 +136,7 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
94
136
|
name: string,
|
|
95
137
|
options: DataTransformOptions,
|
|
96
138
|
): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
97
|
-
|
|
98
|
-
throw errorPostgresMigrationStackMissing();
|
|
99
|
-
}
|
|
100
|
-
return dataTransform(contract, name, options, this.controlAdapter);
|
|
139
|
+
return dataTransform(contract, name, options, this.controlAdapterFor('dataTransform'));
|
|
101
140
|
}
|
|
102
141
|
|
|
103
142
|
/**
|
|
@@ -112,15 +151,12 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
112
151
|
readonly columns: readonly DdlColumn[];
|
|
113
152
|
readonly constraints?: readonly DdlTableConstraint[];
|
|
114
153
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
115
|
-
if (!this.controlAdapter) {
|
|
116
|
-
throw errorPostgresMigrationStackMissing();
|
|
117
|
-
}
|
|
118
154
|
return new CreateTableCall(
|
|
119
155
|
options.schema,
|
|
120
156
|
options.table,
|
|
121
157
|
options.columns,
|
|
122
158
|
options.constraints,
|
|
123
|
-
).toOp(this.
|
|
159
|
+
).toOp(this.controlAdapterFor('createTable'));
|
|
124
160
|
}
|
|
125
161
|
|
|
126
162
|
/**
|
|
@@ -132,10 +168,7 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
132
168
|
readonly schema: string;
|
|
133
169
|
readonly ifNotExists?: boolean;
|
|
134
170
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
135
|
-
|
|
136
|
-
throw errorPostgresMigrationStackMissing();
|
|
137
|
-
}
|
|
138
|
-
return new CreateSchemaCall(options.schema).toOp(this.controlAdapter);
|
|
171
|
+
return new CreateSchemaCall(options.schema).toOp(this.controlAdapterFor('createSchema'));
|
|
139
172
|
}
|
|
140
173
|
|
|
141
174
|
protected addColumn(options: {
|
|
@@ -143,11 +176,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
143
176
|
readonly table: string;
|
|
144
177
|
readonly column: DdlColumn;
|
|
145
178
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
146
|
-
if (!this.controlAdapter) {
|
|
147
|
-
throw errorPostgresMigrationStackMissing();
|
|
148
|
-
}
|
|
149
179
|
return new AddColumnCall(options.schema, options.table, options.column).toOp(
|
|
150
|
-
this.
|
|
180
|
+
this.controlAdapterFor('addColumn'),
|
|
151
181
|
);
|
|
152
182
|
}
|
|
153
183
|
|
|
@@ -157,15 +187,12 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
157
187
|
readonly constraint: string;
|
|
158
188
|
readonly columns: readonly string[];
|
|
159
189
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
160
|
-
if (!this.controlAdapter) {
|
|
161
|
-
throw errorPostgresMigrationStackMissing();
|
|
162
|
-
}
|
|
163
190
|
return new AddPrimaryKeyCall(
|
|
164
191
|
options.schema,
|
|
165
192
|
options.table,
|
|
166
193
|
options.constraint,
|
|
167
194
|
options.columns,
|
|
168
|
-
).toOp(this.
|
|
195
|
+
).toOp(this.controlAdapterFor('addPrimaryKey'));
|
|
169
196
|
}
|
|
170
197
|
|
|
171
198
|
protected addUnique(options: {
|
|
@@ -174,15 +201,12 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
174
201
|
readonly constraint: string;
|
|
175
202
|
readonly columns: readonly string[];
|
|
176
203
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
177
|
-
if (!this.controlAdapter) {
|
|
178
|
-
throw errorPostgresMigrationStackMissing();
|
|
179
|
-
}
|
|
180
204
|
return new AddUniqueCall(
|
|
181
205
|
options.schema,
|
|
182
206
|
options.table,
|
|
183
207
|
options.constraint,
|
|
184
208
|
options.columns,
|
|
185
|
-
).toOp(this.
|
|
209
|
+
).toOp(this.controlAdapterFor('addUnique'));
|
|
186
210
|
}
|
|
187
211
|
|
|
188
212
|
protected addForeignKey(options: {
|
|
@@ -190,11 +214,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
190
214
|
readonly table: string;
|
|
191
215
|
readonly foreignKey: ForeignKeySpec;
|
|
192
216
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
193
|
-
if (!this.controlAdapter) {
|
|
194
|
-
throw errorPostgresMigrationStackMissing();
|
|
195
|
-
}
|
|
196
217
|
return new AddForeignKeyCall(options.schema, options.table, options.foreignKey).toOp(
|
|
197
|
-
this.
|
|
218
|
+
this.controlAdapterFor('addForeignKey'),
|
|
198
219
|
);
|
|
199
220
|
}
|
|
200
221
|
|
|
@@ -205,16 +226,13 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
205
226
|
readonly column: string;
|
|
206
227
|
readonly values: readonly string[];
|
|
207
228
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
208
|
-
if (!this.controlAdapter) {
|
|
209
|
-
throw errorPostgresMigrationStackMissing();
|
|
210
|
-
}
|
|
211
229
|
return new AddCheckConstraintCall(
|
|
212
230
|
options.schema,
|
|
213
231
|
options.table,
|
|
214
232
|
options.constraint,
|
|
215
233
|
options.column,
|
|
216
234
|
options.values,
|
|
217
|
-
).toOp(this.
|
|
235
|
+
).toOp(this.controlAdapterFor('addCheckConstraint'));
|
|
218
236
|
}
|
|
219
237
|
|
|
220
238
|
protected dropCheckConstraint(options: {
|
|
@@ -222,11 +240,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
222
240
|
readonly table: string;
|
|
223
241
|
readonly constraint: string;
|
|
224
242
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
225
|
-
if (!this.controlAdapter) {
|
|
226
|
-
throw errorPostgresMigrationStackMissing();
|
|
227
|
-
}
|
|
228
243
|
return new DropCheckConstraintCall(options.schema, options.table, options.constraint).toOp(
|
|
229
|
-
this.
|
|
244
|
+
this.controlAdapterFor('dropCheckConstraint'),
|
|
230
245
|
);
|
|
231
246
|
}
|
|
232
247
|
|
|
@@ -236,25 +251,21 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
236
251
|
readonly constraint: string;
|
|
237
252
|
readonly kind?: 'foreignKey' | 'unique' | 'primaryKey';
|
|
238
253
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
239
|
-
if (!this.controlAdapter) {
|
|
240
|
-
throw errorPostgresMigrationStackMissing();
|
|
241
|
-
}
|
|
242
254
|
return new DropConstraintCall(
|
|
243
255
|
options.schema,
|
|
244
256
|
options.table,
|
|
245
257
|
options.constraint,
|
|
246
258
|
options.kind ?? 'unique',
|
|
247
|
-
).toOp(this.
|
|
259
|
+
).toOp(this.controlAdapterFor('dropConstraint'));
|
|
248
260
|
}
|
|
249
261
|
|
|
250
262
|
protected dropTable(options: {
|
|
251
263
|
readonly schema: string;
|
|
252
264
|
readonly table: string;
|
|
253
265
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return new DropTableCall(options.schema, options.table).toOp(this.controlAdapter);
|
|
266
|
+
return new DropTableCall(options.schema, options.table).toOp(
|
|
267
|
+
this.controlAdapterFor('dropTable'),
|
|
268
|
+
);
|
|
258
269
|
}
|
|
259
270
|
|
|
260
271
|
protected dropColumn(options: {
|
|
@@ -262,11 +273,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
262
273
|
readonly table: string;
|
|
263
274
|
readonly column: string;
|
|
264
275
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
265
|
-
if (!this.controlAdapter) {
|
|
266
|
-
throw errorPostgresMigrationStackMissing();
|
|
267
|
-
}
|
|
268
276
|
return new DropColumnCall(options.schema, options.table, options.column).toOp(
|
|
269
|
-
this.
|
|
277
|
+
this.controlAdapterFor('dropColumn'),
|
|
270
278
|
);
|
|
271
279
|
}
|
|
272
280
|
|
|
@@ -276,15 +284,12 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
276
284
|
readonly column: string;
|
|
277
285
|
readonly options: AlterColumnTypeOptions;
|
|
278
286
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
279
|
-
if (!this.controlAdapter) {
|
|
280
|
-
throw errorPostgresMigrationStackMissing();
|
|
281
|
-
}
|
|
282
287
|
return new AlterColumnTypeCall(
|
|
283
288
|
options.schema,
|
|
284
289
|
options.table,
|
|
285
290
|
options.column,
|
|
286
291
|
options.options,
|
|
287
|
-
).toOp(this.
|
|
292
|
+
).toOp(this.controlAdapterFor('alterColumnType'));
|
|
288
293
|
}
|
|
289
294
|
|
|
290
295
|
protected setNotNull(options: {
|
|
@@ -292,11 +297,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
292
297
|
readonly table: string;
|
|
293
298
|
readonly column: string;
|
|
294
299
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
295
|
-
if (!this.controlAdapter) {
|
|
296
|
-
throw errorPostgresMigrationStackMissing();
|
|
297
|
-
}
|
|
298
300
|
return new SetNotNullCall(options.schema, options.table, options.column).toOp(
|
|
299
|
-
this.
|
|
301
|
+
this.controlAdapterFor('setNotNull'),
|
|
300
302
|
);
|
|
301
303
|
}
|
|
302
304
|
|
|
@@ -305,11 +307,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
305
307
|
readonly table: string;
|
|
306
308
|
readonly column: string;
|
|
307
309
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
308
|
-
if (!this.controlAdapter) {
|
|
309
|
-
throw errorPostgresMigrationStackMissing();
|
|
310
|
-
}
|
|
311
310
|
return new DropNotNullCall(options.schema, options.table, options.column).toOp(
|
|
312
|
-
this.
|
|
311
|
+
this.controlAdapterFor('dropNotNull'),
|
|
313
312
|
);
|
|
314
313
|
}
|
|
315
314
|
|
|
@@ -320,16 +319,13 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
320
319
|
readonly defaultSql: string;
|
|
321
320
|
readonly operationClass?: 'additive' | 'widening';
|
|
322
321
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
323
|
-
if (!this.controlAdapter) {
|
|
324
|
-
throw errorPostgresMigrationStackMissing();
|
|
325
|
-
}
|
|
326
322
|
return new SetDefaultCall(
|
|
327
323
|
options.schema,
|
|
328
324
|
options.table,
|
|
329
325
|
options.column,
|
|
330
326
|
options.defaultSql,
|
|
331
327
|
options.operationClass,
|
|
332
|
-
).toOp(this.
|
|
328
|
+
).toOp(this.controlAdapterFor('setDefault'));
|
|
333
329
|
}
|
|
334
330
|
|
|
335
331
|
protected dropDefault(options: {
|
|
@@ -337,11 +333,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
337
333
|
readonly table: string;
|
|
338
334
|
readonly column: string;
|
|
339
335
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
340
|
-
if (!this.controlAdapter) {
|
|
341
|
-
throw errorPostgresMigrationStackMissing();
|
|
342
|
-
}
|
|
343
336
|
return new DropDefaultCall(options.schema, options.table, options.column).toOp(
|
|
344
|
-
this.
|
|
337
|
+
this.controlAdapterFor('dropDefault'),
|
|
345
338
|
);
|
|
346
339
|
}
|
|
347
340
|
|
|
@@ -352,16 +345,13 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
352
345
|
readonly columns: readonly string[];
|
|
353
346
|
readonly extras?: CreateIndexExtras;
|
|
354
347
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
355
|
-
if (!this.controlAdapter) {
|
|
356
|
-
throw errorPostgresMigrationStackMissing();
|
|
357
|
-
}
|
|
358
348
|
return new CreateIndexCall(
|
|
359
349
|
options.schema,
|
|
360
350
|
options.table,
|
|
361
351
|
options.index,
|
|
362
352
|
options.columns,
|
|
363
353
|
options.extras,
|
|
364
|
-
).toOp(this.
|
|
354
|
+
).toOp(this.controlAdapterFor('createIndex'));
|
|
365
355
|
}
|
|
366
356
|
|
|
367
357
|
protected dropIndex(options: {
|
|
@@ -369,11 +359,8 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
369
359
|
readonly table: string;
|
|
370
360
|
readonly index: string;
|
|
371
361
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
372
|
-
if (!this.controlAdapter) {
|
|
373
|
-
throw errorPostgresMigrationStackMissing();
|
|
374
|
-
}
|
|
375
362
|
return new DropIndexCall(options.schema, options.table, options.index).toOp(
|
|
376
|
-
this.
|
|
363
|
+
this.controlAdapterFor('dropIndex'),
|
|
377
364
|
);
|
|
378
365
|
}
|
|
379
366
|
|
|
@@ -383,9 +370,6 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
383
370
|
readonly id: string;
|
|
384
371
|
readonly label?: string;
|
|
385
372
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
386
|
-
|
|
387
|
-
throw errorPostgresMigrationStackMissing();
|
|
388
|
-
}
|
|
389
|
-
return installExtension(options, this.controlAdapter);
|
|
373
|
+
return installExtension(options, this.controlAdapterFor('installExtension'));
|
|
390
374
|
}
|
|
391
375
|
}
|
|
@@ -45,15 +45,19 @@ export function renderCallsToTypeScript(
|
|
|
45
45
|
calls: ReadonlyArray<OpFactoryCall>,
|
|
46
46
|
meta: RenderMigrationMeta,
|
|
47
47
|
): string {
|
|
48
|
-
const imports = buildImports(calls);
|
|
48
|
+
const imports = buildImports(calls, meta);
|
|
49
49
|
const operationsBody = calls.map((c) => renderCall(c)).join(',\n');
|
|
50
|
+
const hasStart = meta.from !== null;
|
|
51
|
+
const startField = hasStart ? [' override readonly startContractJson = startContract;'] : [];
|
|
50
52
|
|
|
51
53
|
return [
|
|
52
54
|
shebangLineFor(detectScaffoldRuntime()),
|
|
53
55
|
imports,
|
|
54
56
|
'',
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
`export default class M extends Migration<${hasStart ? 'Start' : 'never'}, End> {`,
|
|
58
|
+
...startField,
|
|
59
|
+
' override readonly endContractJson = endContract;',
|
|
60
|
+
'',
|
|
57
61
|
' override get operations() {',
|
|
58
62
|
' return [',
|
|
59
63
|
indent(operationsBody, 6),
|
|
@@ -70,8 +74,8 @@ function renderCall(call: OpFactoryCall): string {
|
|
|
70
74
|
return call.renderTypeScript();
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
function buildImports(calls: ReadonlyArray<OpFactoryCall
|
|
74
|
-
const requirements: ImportRequirement[] = [...BASE_IMPORTS];
|
|
77
|
+
function buildImports(calls: ReadonlyArray<OpFactoryCall>, meta: RenderMigrationMeta): string {
|
|
78
|
+
const requirements: ImportRequirement[] = [...BASE_IMPORTS, ...contractImports(meta)];
|
|
75
79
|
for (const call of calls) {
|
|
76
80
|
for (const req of call.importRequirements()) {
|
|
77
81
|
requirements.push(req);
|
|
@@ -80,16 +84,39 @@ function buildImports(calls: ReadonlyArray<OpFactoryCall>): string {
|
|
|
80
84
|
return renderImports(requirements);
|
|
81
85
|
}
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
/**
|
|
88
|
+
* The committed contract-JSON imports the scaffold reads its from/to identity
|
|
89
|
+
* from. `end-contract.json` is always present; `start-contract.json` is added
|
|
90
|
+
* only for a non-baseline migration (`meta.from !== null`). The matching
|
|
91
|
+
* `Contract` type imports (aliased `Start`/`End`) feed the
|
|
92
|
+
* `Migration<Start, End>` generics. Baseline emits `Migration<never, End>` with
|
|
93
|
+
* no start imports — `never` is the honest "no prior contract" Start.
|
|
94
|
+
*/
|
|
95
|
+
function contractImports(meta: RenderMigrationMeta): readonly ImportRequirement[] {
|
|
96
|
+
const reqs: ImportRequirement[] = [
|
|
97
|
+
{
|
|
98
|
+
moduleSpecifier: './end-contract.json',
|
|
99
|
+
symbol: 'endContract',
|
|
100
|
+
kind: 'default',
|
|
101
|
+
attributes: { type: 'json' },
|
|
102
|
+
},
|
|
103
|
+
{ moduleSpecifier: './end-contract', symbol: 'Contract', alias: 'End', typeOnly: true },
|
|
104
|
+
];
|
|
105
|
+
if (meta.from !== null) {
|
|
106
|
+
reqs.push({
|
|
107
|
+
moduleSpecifier: './start-contract.json',
|
|
108
|
+
symbol: 'startContract',
|
|
109
|
+
kind: 'default',
|
|
110
|
+
attributes: { type: 'json' },
|
|
111
|
+
});
|
|
112
|
+
reqs.push({
|
|
113
|
+
moduleSpecifier: './start-contract',
|
|
114
|
+
symbol: 'Contract',
|
|
115
|
+
alias: 'Start',
|
|
116
|
+
typeOnly: true,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return reqs;
|
|
93
120
|
}
|
|
94
121
|
|
|
95
122
|
function indent(text: string, spaces: number): string {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
2
|
+
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
3
|
+
import { DEFAULT_NAMESPACE_ID } from '../namespace-ids';
|
|
4
|
+
import { isPostgresSchema } from '../postgres-schema';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Given the contract's storage and a namespace id, returns the live Postgres
|
|
8
|
+
* DDL schema name that namespace maps to. A named Postgres namespace dispatches
|
|
9
|
+
* to its `ddlSchemaName(storage)`; the unbound sentinel resolves to
|
|
10
|
+
* `DEFAULT_NAMESPACE_ID` (the search-path default for offline planning); a
|
|
11
|
+
* bare object payload (used by some tests) falls back to the namespace id
|
|
12
|
+
* itself.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveDdlSchemaForNamespaceStorage(
|
|
15
|
+
storage: SqlStorage,
|
|
16
|
+
namespaceId: string,
|
|
17
|
+
): string {
|
|
18
|
+
if (namespaceId === UNBOUND_NAMESPACE_ID) {
|
|
19
|
+
return DEFAULT_NAMESPACE_ID;
|
|
20
|
+
}
|
|
21
|
+
const namespace = storage.namespaces[namespaceId];
|
|
22
|
+
if (namespace && isPostgresSchema(namespace)) {
|
|
23
|
+
return namespace.ddlSchemaName(storage);
|
|
24
|
+
}
|
|
25
|
+
return namespaceId;
|
|
26
|
+
}
|
|
@@ -12,7 +12,6 @@ import type {
|
|
|
12
12
|
SqlMigrationRunnerSuccessValue,
|
|
13
13
|
} from '@prisma-next/family-sql/control';
|
|
14
14
|
import { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';
|
|
15
|
-
import { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';
|
|
16
15
|
import type { MigrationRunnerResult } from '@prisma-next/framework-components/control';
|
|
17
16
|
import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
|
|
18
17
|
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
@@ -23,8 +22,6 @@ import { blindCast } from '@prisma-next/utils/casts';
|
|
|
23
22
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
24
23
|
import type { Result } from '@prisma-next/utils/result';
|
|
25
24
|
import { notOk, ok, okVoid } from '@prisma-next/utils/result';
|
|
26
|
-
import { parsePostgresDefault } from '../default-normalizer';
|
|
27
|
-
import { normalizeSchemaNativeType } from '../native-type-normalizer';
|
|
28
25
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
29
26
|
|
|
30
27
|
interface ApplyPlanSuccessValue {
|
|
@@ -124,30 +121,27 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
124
121
|
applyValue = applyResult.value;
|
|
125
122
|
}
|
|
126
123
|
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
// an extension contract.
|
|
124
|
+
// Verify the schema on app-space only: extension spaces don't own
|
|
125
|
+
// user-facing tables, so verifying the destination contract against the
|
|
126
|
+
// database would flag every app-space table as "extra". Delegates to the
|
|
127
|
+
// family `verifySchema` — the same comparison the CLI verify runs.
|
|
132
128
|
if (space === APP_SPACE_ID) {
|
|
133
|
-
const
|
|
129
|
+
const schemaNode = await this.family.introspect({
|
|
134
130
|
driver,
|
|
135
131
|
contract: options.destinationContract,
|
|
136
132
|
});
|
|
137
|
-
const schemaVerifyResult =
|
|
133
|
+
const schemaVerifyResult = this.family.verifySchema({
|
|
138
134
|
contract: options.destinationContract,
|
|
139
|
-
schema:
|
|
135
|
+
schema: schemaNode,
|
|
140
136
|
strict: options.strictVerification ?? true,
|
|
141
|
-
context: options.context ?? {},
|
|
142
|
-
typeMetadataRegistry: this.family.typeMetadataRegistry,
|
|
143
137
|
frameworkComponents: options.frameworkComponents,
|
|
144
|
-
normalizeDefault: parsePostgresDefault,
|
|
145
|
-
normalizeNativeType: normalizeSchemaNativeType,
|
|
146
138
|
});
|
|
147
139
|
if (!schemaVerifyResult.ok) {
|
|
148
140
|
return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
|
|
149
141
|
why: 'The resulting database schema does not satisfy the destination contract.',
|
|
150
|
-
meta: {
|
|
142
|
+
meta: {
|
|
143
|
+
issues: schemaVerifyResult.schema.issues,
|
|
144
|
+
},
|
|
151
145
|
});
|
|
152
146
|
}
|
|
153
147
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { Contract } from '@prisma-next/contract/types';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
|
|
3
3
|
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
4
4
|
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
5
|
-
import type {
|
|
5
|
+
import type { SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
|
|
6
|
+
import { DEFAULT_NAMESPACE_ID } from '../namespace-ids';
|
|
6
7
|
import { isPostgresSchema } from '../postgres-schema';
|
|
8
|
+
import { PostgresDatabaseSchemaNode } from '../schema-ir/postgres-database-schema-node';
|
|
9
|
+
import { PostgresNamespaceSchemaNode } from '../schema-ir/postgres-namespace-schema-node';
|
|
10
|
+
import type { SqlSchemaDiffNode } from '../schema-ir/schema-node-kinds';
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* Resolves the live-database schema name for a given namespace
|
|
@@ -23,32 +27,36 @@ function resolveDdlSchemaName(storage: SqlStorage, namespaceId: string): string
|
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
|
-
* Reads the introspected list of schema names from the
|
|
27
|
-
*
|
|
28
|
-
* `
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* Reads the introspected list of schema names from the database-root schema
|
|
31
|
+
* node. `existingSchemas` is database-level, so it lives on the
|
|
32
|
+
* `PostgresDatabaseSchemaNode` root — not on the per-schema namespace nodes.
|
|
33
|
+
*
|
|
34
|
+
* Defaults to the always-present `public` schema when the node is not the
|
|
35
|
+
* database root — a fresh Postgres database always carries `public` (unless an
|
|
36
|
+
* operator dropped it manually), so any verifier path that runs without an
|
|
37
|
+
* enriched introspection still suppresses the redundant `CREATE SCHEMA
|
|
38
|
+
* "public"`.
|
|
32
39
|
*
|
|
33
40
|
* Production introspection (`PostgresControlAdapter.introspect`) is the
|
|
34
|
-
* authoritative source: it queries `pg_namespace` and
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* explicitly via the schema IR.
|
|
41
|
+
* authoritative source: it queries `pg_namespace` and sets `existingSchemas`
|
|
42
|
+
* on the returned root. Tests that want to assert against a richer initial
|
|
43
|
+
* state construct a `PostgresDatabaseSchemaNode` explicitly.
|
|
38
44
|
*/
|
|
39
|
-
function existingSchemasFromSchema(schema:
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
const slot = annotations?.pg?.existingSchemas;
|
|
43
|
-
if (Array.isArray(slot)) {
|
|
44
|
-
return slot.filter((s): s is string => typeof s === 'string');
|
|
45
|
+
function existingSchemasFromSchema(schema: SqlSchemaIRNode): readonly string[] {
|
|
46
|
+
if (PostgresDatabaseSchemaNode.is(schema)) {
|
|
47
|
+
return schema.existingSchemas;
|
|
45
48
|
}
|
|
46
|
-
return [
|
|
49
|
+
return [DEFAULT_NAMESPACE_ID];
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
/**
|
|
50
|
-
* Emits a `
|
|
51
|
-
* namespace whose live container does not yet
|
|
53
|
+
* Emits a `postgres-namespace` `not-found` diff issue for every
|
|
54
|
+
* contract-declared Postgres namespace whose live container does not yet
|
|
55
|
+
* exist. The planner prepends these (node-typed, synthesized) to the
|
|
56
|
+
* relational diff issues so a multi-schema plan emits `CREATE SCHEMA`
|
|
57
|
+
* before the tables that need it — a planner-only concern (verify already
|
|
58
|
+
* rejects via the `not-found` table issues a missing schema already
|
|
59
|
+
* produces), so this is not part of the shared diff.
|
|
52
60
|
*
|
|
53
61
|
* A namespace's live container is the schema returned by its
|
|
54
62
|
* polymorphic `ddlSchemaName(storage)` method — named schemas resolve
|
|
@@ -59,28 +67,36 @@ function existingSchemasFromSchema(schema: SqlSchemaIR): readonly string[] {
|
|
|
59
67
|
* introspected list. `public` is suppressed implicitly because the
|
|
60
68
|
* introspection (or its sensible default) always carries it.
|
|
61
69
|
*
|
|
62
|
-
* Each emitted issue
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
70
|
+
* Each emitted issue's path is `['database', ddlName]` — an ancestor of
|
|
71
|
+
* every table path under that schema, so it must never be run through
|
|
72
|
+
* `coalesceSubtreeIssues` alongside the table diff (it would swallow the
|
|
73
|
+
* table-level `not-found` issues that drive `CREATE TABLE`); the planner
|
|
74
|
+
* adds these AFTER coalescing the relational issues, and they are not
|
|
75
|
+
* subject to sibling-space ownership scoping (mirrors the retired
|
|
76
|
+
* coordinate walk, which prepended namespace issues after that filter).
|
|
66
77
|
*/
|
|
67
78
|
export function verifyPostgresNamespacePresence(input: {
|
|
68
79
|
readonly contract: Contract<SqlStorage>;
|
|
69
|
-
readonly schema:
|
|
70
|
-
}): readonly
|
|
80
|
+
readonly schema: SqlSchemaIRNode;
|
|
81
|
+
}): readonly SchemaDiffIssue<SqlSchemaDiffNode>[] {
|
|
71
82
|
const { contract, schema } = input;
|
|
72
83
|
const existing = new Set(existingSchemasFromSchema(schema));
|
|
73
|
-
const issues:
|
|
84
|
+
const issues: SchemaDiffIssue<SqlSchemaDiffNode>[] = [];
|
|
74
85
|
const namespaceIds = Object.keys(contract.storage.namespaces).sort();
|
|
75
86
|
for (const namespaceId of namespaceIds) {
|
|
76
87
|
if (namespaceId === UNBOUND_NAMESPACE_ID) continue;
|
|
77
88
|
const ddlName = resolveDdlSchemaName(contract.storage, namespaceId);
|
|
78
89
|
if (ddlName === UNBOUND_NAMESPACE_ID) continue;
|
|
79
90
|
if (existing.has(ddlName)) continue;
|
|
91
|
+
const namespace = new PostgresNamespaceSchemaNode({
|
|
92
|
+
schemaName: ddlName,
|
|
93
|
+
tables: {},
|
|
94
|
+
nativeEnumTypeNames: [],
|
|
95
|
+
});
|
|
80
96
|
issues.push({
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
97
|
+
path: ['database', ddlName],
|
|
98
|
+
reason: 'not-found',
|
|
99
|
+
expected: namespace,
|
|
84
100
|
});
|
|
85
101
|
}
|
|
86
102
|
return issues;
|