@prisma-next/target-postgres 0.13.0-dev.34 → 0.13.0-dev.36
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/contract-free.d.mts +147 -14
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +3 -16
- package/dist/contract-free.mjs.map +1 -1
- package/dist/control.mjs +2 -2
- package/dist/ddl-QDyOSeLc.mjs +251 -0
- package/dist/ddl-QDyOSeLc.mjs.map +1 -0
- package/dist/{issue-planner-DsjB7xDj.mjs → issue-planner-CoI_0uM1.mjs} +9 -119
- package/dist/issue-planner-CoI_0uM1.mjs.map +1 -0
- package/dist/issue-planner.d.mts +2 -2
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +4 -80
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +3 -3
- package/dist/{op-factory-call-CjR846f7.mjs → op-factory-call-B1bXWtfa.mjs} +551 -241
- package/dist/op-factory-call-B1bXWtfa.mjs.map +1 -0
- package/dist/{op-factory-call-CdtMyrlU.d.mts → op-factory-call-DmQEc3XV.d.mts} +111 -20
- package/dist/op-factory-call-DmQEc3XV.d.mts.map +1 -0
- package/dist/op-factory-call.d.mts +1 -1
- package/dist/op-factory-call.mjs +1 -1
- package/dist/{planner-_FOL4I21.mjs → planner-DS5XBhmi.mjs} +4 -4
- package/dist/{planner-_FOL4I21.mjs.map → planner-DS5XBhmi.mjs.map} +1 -1
- package/dist/{planner-produced-postgres-migration-BmCpyWLJ.mjs → planner-produced-postgres-migration-DTwCCek_.mjs} +2 -2
- package/dist/{planner-produced-postgres-migration-BmCpyWLJ.mjs.map → planner-produced-postgres-migration-DTwCCek_.mjs.map} +1 -1
- package/dist/{planner-produced-postgres-migration-wLhnJMMA.d.mts → planner-produced-postgres-migration-QqHa2C2l.d.mts} +2 -2
- package/dist/{planner-produced-postgres-migration-wLhnJMMA.d.mts.map → planner-produced-postgres-migration-QqHa2C2l.d.mts.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 +152 -0
- package/dist/planner-sql-checks-jqUUGyQR.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts +1 -47
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +2 -2
- package/dist/planner.d.mts +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{postgres-contract-serializer-CyAe8ZFv.mjs → postgres-contract-serializer-E92REOFk.mjs} +3 -3
- package/dist/postgres-contract-serializer-E92REOFk.mjs.map +1 -0
- package/dist/postgres-migration-Y4YBJqkS.d.mts +181 -0
- package/dist/postgres-migration-Y4YBJqkS.d.mts.map +1 -0
- package/dist/postgres-migration-otiaw3Ru.mjs +145 -0
- package/dist/postgres-migration-otiaw3Ru.mjs.map +1 -0
- package/dist/{postgres-schema-CTKYiTHu.mjs → postgres-schema-COGZ1ark.mjs} +71 -29
- package/dist/postgres-schema-COGZ1ark.mjs.map +1 -0
- package/dist/runtime.mjs +1 -1
- package/dist/table-source-BvFo7gVs.d.mts +15 -0
- package/dist/table-source-BvFo7gVs.d.mts.map +1 -0
- package/dist/types.d.mts +28 -8
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +1 -1
- package/package.json +17 -17
- package/src/contract-free/checks.ts +363 -0
- package/src/core/migrations/op-factory-call.ts +417 -94
- package/src/core/migrations/operations/columns.ts +175 -140
- package/src/core/migrations/operations/constraints.ts +79 -108
- package/src/core/migrations/operations/dependencies.ts +16 -14
- package/src/core/migrations/operations/indexes.ts +31 -28
- package/src/core/migrations/operations/shared.ts +2 -2
- package/src/core/migrations/operations/tables.ts +13 -14
- package/src/core/migrations/planner-recipes.ts +42 -33
- package/src/core/migrations/planner-sql-checks.ts +1 -172
- package/src/core/migrations/planner-strategies.ts +25 -73
- package/src/core/migrations/postgres-migration.ts +272 -7
- package/src/core/postgres-contract-serializer.ts +1 -1
- package/src/core/postgres-schema.ts +70 -52
- package/src/exports/contract-free.ts +21 -0
- package/src/exports/migration.ts +1 -22
- package/src/exports/planner-sql-checks.ts +0 -7
- package/dist/ddl-DY2R_Yqz.mjs +0 -45
- package/dist/ddl-DY2R_Yqz.mjs.map +0 -1
- package/dist/issue-planner-DsjB7xDj.mjs.map +0 -1
- package/dist/op-factory-call-CdtMyrlU.d.mts.map +0 -1
- package/dist/op-factory-call-CjR846f7.mjs.map +0 -1
- package/dist/planner-sql-checks-CJJtPfDH.mjs +0 -272
- package/dist/planner-sql-checks-CJJtPfDH.mjs.map +0 -1
- package/dist/postgres-contract-serializer-CyAe8ZFv.mjs.map +0 -1
- package/dist/postgres-migration-DLXL0GBf.d.mts +0 -77
- package/dist/postgres-migration-DLXL0GBf.d.mts.map +0 -1
- package/dist/postgres-migration-dG-J0aI8.mjs +0 -75
- package/dist/postgres-migration-dG-J0aI8.mjs.map +0 -1
- package/dist/postgres-schema-CTKYiTHu.mjs.map +0 -1
- package/dist/shared-jcsbXxiW.d.mts +0 -25
- package/dist/shared-jcsbXxiW.d.mts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CodecControlHooks } from '@prisma-next/family-sql/control';
|
|
2
2
|
import type { StorageColumn, StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
3
3
|
import { postgresCreateNamespace } from '../postgres-schema';
|
|
4
|
-
import {
|
|
4
|
+
import { quoteIdentifier } from '../sql-utils';
|
|
5
5
|
import { resolveColumnTypeMetadata } from './planner-type-resolution';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -19,105 +19,6 @@ export function qualifyTableName(schema: string, table: string): string {
|
|
|
19
19
|
return postgresCreateNamespace({ id: schema, entries: { table: {} } }).qualifyTable(table);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export function toRegclassLiteral(schema: string, name: string): string {
|
|
23
|
-
return postgresCreateNamespace({ id: schema, entries: { table: {} } }).regclassLiteral(name);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* When `table` is omitted the check matches by name + schema across all tables.
|
|
28
|
-
* Pass `table` to scope the check to a single table (prevents false matches on
|
|
29
|
-
* identically-named constraints in different tables).
|
|
30
|
-
*/
|
|
31
|
-
export function constraintExistsCheck({
|
|
32
|
-
constraintName,
|
|
33
|
-
schema,
|
|
34
|
-
table,
|
|
35
|
-
exists = true,
|
|
36
|
-
}: {
|
|
37
|
-
constraintName: string;
|
|
38
|
-
schema: string;
|
|
39
|
-
table?: string;
|
|
40
|
-
exists?: boolean;
|
|
41
|
-
}): string {
|
|
42
|
-
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
43
|
-
const existsClause = exists ? 'EXISTS' : 'NOT EXISTS';
|
|
44
|
-
const tableFilter = table
|
|
45
|
-
? `AND c.conrelid = to_regclass(${namespace.regclassLiteral(table)})`
|
|
46
|
-
: '';
|
|
47
|
-
return `SELECT ${existsClause} (
|
|
48
|
-
SELECT 1 FROM pg_constraint c
|
|
49
|
-
JOIN pg_namespace n ON c.connamespace = n.oid
|
|
50
|
-
WHERE c.conname = '${escapeLiteral(constraintName)}'
|
|
51
|
-
AND n.nspname = ${namespace.schemaSqlExpression()}
|
|
52
|
-
${tableFilter}
|
|
53
|
-
)`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function columnExistsCheck({
|
|
57
|
-
schema,
|
|
58
|
-
table,
|
|
59
|
-
column,
|
|
60
|
-
exists = true,
|
|
61
|
-
}: {
|
|
62
|
-
schema: string;
|
|
63
|
-
table: string;
|
|
64
|
-
column: string;
|
|
65
|
-
exists?: boolean;
|
|
66
|
-
}): string {
|
|
67
|
-
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
68
|
-
const existsClause = exists ? '' : 'NOT ';
|
|
69
|
-
return `SELECT ${existsClause}EXISTS (
|
|
70
|
-
SELECT 1
|
|
71
|
-
FROM information_schema.columns
|
|
72
|
-
WHERE table_schema = ${namespace.schemaSqlExpression()}
|
|
73
|
-
AND table_name = '${escapeLiteral(table)}'
|
|
74
|
-
AND column_name = '${escapeLiteral(column)}'
|
|
75
|
-
)`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function columnNullabilityCheck({
|
|
79
|
-
schema,
|
|
80
|
-
table,
|
|
81
|
-
column,
|
|
82
|
-
nullable,
|
|
83
|
-
}: {
|
|
84
|
-
schema: string;
|
|
85
|
-
table: string;
|
|
86
|
-
column: string;
|
|
87
|
-
nullable: boolean;
|
|
88
|
-
}): string {
|
|
89
|
-
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
90
|
-
const expected = nullable ? 'YES' : 'NO';
|
|
91
|
-
return `SELECT EXISTS (
|
|
92
|
-
SELECT 1
|
|
93
|
-
FROM information_schema.columns
|
|
94
|
-
WHERE table_schema = ${namespace.schemaSqlExpression()}
|
|
95
|
-
AND table_name = '${escapeLiteral(table)}'
|
|
96
|
-
AND column_name = '${escapeLiteral(column)}'
|
|
97
|
-
AND is_nullable = '${expected}'
|
|
98
|
-
)`;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function tableIsEmptyCheck(qualifiedTableName: string): string {
|
|
102
|
-
return `SELECT NOT EXISTS (SELECT 1 FROM ${qualifiedTableName} LIMIT 1)`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function columnHasNoDefaultCheck(opts: {
|
|
106
|
-
schema: string;
|
|
107
|
-
table: string;
|
|
108
|
-
column: string;
|
|
109
|
-
}): string {
|
|
110
|
-
const namespace = postgresCreateNamespace({ id: opts.schema, entries: { table: {} } });
|
|
111
|
-
return `SELECT NOT EXISTS (
|
|
112
|
-
SELECT 1
|
|
113
|
-
FROM information_schema.columns
|
|
114
|
-
WHERE table_schema = ${namespace.schemaSqlExpression()}
|
|
115
|
-
AND table_name = '${escapeLiteral(opts.table)}'
|
|
116
|
-
AND column_name = '${escapeLiteral(opts.column)}'
|
|
117
|
-
AND column_default IS NOT NULL
|
|
118
|
-
)`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
22
|
const FORMAT_TYPE_DISPLAY: ReadonlyMap<string, string> = new Map([
|
|
122
23
|
['int2', 'smallint'],
|
|
123
24
|
['int4', 'integer'],
|
|
@@ -266,75 +167,3 @@ export function buildExpectedFormatType(
|
|
|
266
167
|
|
|
267
168
|
return FORMAT_TYPE_DISPLAY.get(resolved.nativeType) ?? resolved.nativeType;
|
|
268
169
|
}
|
|
269
|
-
|
|
270
|
-
export function columnTypeCheck({
|
|
271
|
-
schema,
|
|
272
|
-
table,
|
|
273
|
-
column,
|
|
274
|
-
expectedType,
|
|
275
|
-
}: {
|
|
276
|
-
schema: string;
|
|
277
|
-
table: string;
|
|
278
|
-
column: string;
|
|
279
|
-
expectedType: string;
|
|
280
|
-
}): string {
|
|
281
|
-
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
282
|
-
return `SELECT EXISTS (
|
|
283
|
-
SELECT 1
|
|
284
|
-
FROM pg_attribute a
|
|
285
|
-
JOIN pg_class c ON c.oid = a.attrelid
|
|
286
|
-
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
287
|
-
WHERE n.nspname = ${namespace.schemaSqlExpression()}
|
|
288
|
-
AND c.relname = '${escapeLiteral(table)}'
|
|
289
|
-
AND a.attname = '${escapeLiteral(column)}'
|
|
290
|
-
AND format_type(a.atttypid, a.atttypmod) = '${escapeLiteral(expectedType)}'
|
|
291
|
-
AND NOT a.attisdropped
|
|
292
|
-
)`;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export function columnDefaultExistsCheck({
|
|
296
|
-
schema,
|
|
297
|
-
table,
|
|
298
|
-
column,
|
|
299
|
-
exists = true,
|
|
300
|
-
}: {
|
|
301
|
-
schema: string;
|
|
302
|
-
table: string;
|
|
303
|
-
column: string;
|
|
304
|
-
exists?: boolean;
|
|
305
|
-
}): string {
|
|
306
|
-
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
307
|
-
const nullCheck = exists ? 'IS NOT NULL' : 'IS NULL';
|
|
308
|
-
return `SELECT EXISTS (
|
|
309
|
-
SELECT 1
|
|
310
|
-
FROM information_schema.columns
|
|
311
|
-
WHERE table_schema = ${namespace.schemaSqlExpression()}
|
|
312
|
-
AND table_name = '${escapeLiteral(table)}'
|
|
313
|
-
AND column_name = '${escapeLiteral(column)}'
|
|
314
|
-
AND column_default ${nullCheck}
|
|
315
|
-
)`;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
export function tableHasPrimaryKeyCheck(
|
|
319
|
-
schema: string,
|
|
320
|
-
table: string,
|
|
321
|
-
exists: boolean,
|
|
322
|
-
constraintName?: string,
|
|
323
|
-
): string {
|
|
324
|
-
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
325
|
-
const comparison = exists ? '' : 'NOT ';
|
|
326
|
-
const constraintFilter = constraintName
|
|
327
|
-
? `AND c2.relname = '${escapeLiteral(constraintName)}'`
|
|
328
|
-
: '';
|
|
329
|
-
return `SELECT ${comparison}EXISTS (
|
|
330
|
-
SELECT 1
|
|
331
|
-
FROM pg_index i
|
|
332
|
-
JOIN pg_class c ON c.oid = i.indrelid
|
|
333
|
-
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
334
|
-
LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid
|
|
335
|
-
WHERE n.nspname = ${namespace.schemaSqlExpression()}
|
|
336
|
-
AND c.relname = '${escapeLiteral(table)}'
|
|
337
|
-
AND i.indisprimary
|
|
338
|
-
${constraintFilter}
|
|
339
|
-
)`;
|
|
340
|
-
}
|
|
@@ -43,6 +43,8 @@ import { isPostgresSchema } from '../postgres-schema';
|
|
|
43
43
|
import {
|
|
44
44
|
AddCheckConstraintCall,
|
|
45
45
|
AddColumnCall,
|
|
46
|
+
AddNotNullColumnDirectCall,
|
|
47
|
+
AddNotNullColumnWithTempDefaultCall,
|
|
46
48
|
AlterColumnTypeCall,
|
|
47
49
|
DataTransformCall,
|
|
48
50
|
DropCheckConstraintCall,
|
|
@@ -53,18 +55,8 @@ import {
|
|
|
53
55
|
} from './op-factory-call';
|
|
54
56
|
import { buildAddColumnSql, buildColumnTypeSql } from './planner-ddl-builders';
|
|
55
57
|
import { resolveIdentityValue } from './planner-identity-values';
|
|
56
|
-
import {
|
|
57
|
-
buildAddColumnOperationIdentity,
|
|
58
|
-
buildAddNotNullColumnWithTemporaryDefaultOperation,
|
|
59
|
-
} from './planner-recipes';
|
|
60
58
|
import { buildSchemaLookupMap, hasForeignKey, hasUniqueConstraint } from './planner-schema-lookup';
|
|
61
|
-
import {
|
|
62
|
-
buildExpectedFormatType,
|
|
63
|
-
columnExistsCheck,
|
|
64
|
-
columnNullabilityCheck,
|
|
65
|
-
qualifyTableName,
|
|
66
|
-
tableIsEmptyCheck,
|
|
67
|
-
} from './planner-sql-checks';
|
|
59
|
+
import { buildExpectedFormatType, qualifyTableName } from './planner-sql-checks';
|
|
68
60
|
import { buildTargetDetails, type PostgresPlanTargetDetails } from './planner-target-details';
|
|
69
61
|
import { resolveColumnTypeMetadata } from './planner-type-resolution';
|
|
70
62
|
|
|
@@ -595,74 +587,34 @@ export const notNullAddColumnCallStrategy: CallMigrationStrategy = (issues, ctx)
|
|
|
595
587
|
|
|
596
588
|
if (canUseSharedTempDefault && temporaryDefault !== null) {
|
|
597
589
|
calls.push(
|
|
598
|
-
new
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
}),
|
|
608
|
-
),
|
|
590
|
+
new AddNotNullColumnWithTempDefaultCall({
|
|
591
|
+
schemaName: schemaForTable,
|
|
592
|
+
tableName: issue.table,
|
|
593
|
+
columnName: issue.column,
|
|
594
|
+
column,
|
|
595
|
+
codecHooks: mutableCodecHooks,
|
|
596
|
+
storageTypes: mutableStorageTypes,
|
|
597
|
+
temporaryDefault,
|
|
598
|
+
}),
|
|
609
599
|
);
|
|
610
600
|
continue;
|
|
611
601
|
}
|
|
612
602
|
|
|
613
603
|
const qualified = qualifyTableName(schemaForTable, issue.table);
|
|
614
604
|
calls.push(
|
|
615
|
-
new
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
{
|
|
629
|
-
description: `ensure table "${issue.table}" is empty before adding NOT NULL column without default`,
|
|
630
|
-
sql: tableIsEmptyCheck(qualified),
|
|
631
|
-
},
|
|
632
|
-
],
|
|
633
|
-
execute: [
|
|
634
|
-
{
|
|
635
|
-
description: `add column "${issue.column}"`,
|
|
636
|
-
sql: buildAddColumnSql(
|
|
637
|
-
qualified,
|
|
638
|
-
issue.column,
|
|
639
|
-
column,
|
|
640
|
-
mutableCodecHooks,
|
|
641
|
-
undefined,
|
|
642
|
-
mutableStorageTypes,
|
|
643
|
-
),
|
|
644
|
-
},
|
|
645
|
-
],
|
|
646
|
-
postcheck: [
|
|
647
|
-
{
|
|
648
|
-
description: `verify column "${issue.column}" exists`,
|
|
649
|
-
sql: columnExistsCheck({
|
|
650
|
-
schema: schemaForTable,
|
|
651
|
-
table: issue.table,
|
|
652
|
-
column: issue.column,
|
|
653
|
-
}),
|
|
654
|
-
},
|
|
655
|
-
{
|
|
656
|
-
description: `verify column "${issue.column}" is NOT NULL`,
|
|
657
|
-
sql: columnNullabilityCheck({
|
|
658
|
-
schema: schemaForTable,
|
|
659
|
-
table: issue.table,
|
|
660
|
-
column: issue.column,
|
|
661
|
-
nullable: false,
|
|
662
|
-
}),
|
|
663
|
-
},
|
|
664
|
-
],
|
|
665
|
-
}),
|
|
605
|
+
new AddNotNullColumnDirectCall(
|
|
606
|
+
schemaForTable,
|
|
607
|
+
issue.table,
|
|
608
|
+
issue.column,
|
|
609
|
+
buildAddColumnSql(
|
|
610
|
+
qualified,
|
|
611
|
+
issue.column,
|
|
612
|
+
column,
|
|
613
|
+
mutableCodecHooks,
|
|
614
|
+
undefined,
|
|
615
|
+
mutableStorageTypes,
|
|
616
|
+
),
|
|
617
|
+
),
|
|
666
618
|
);
|
|
667
619
|
}
|
|
668
620
|
|
|
@@ -3,12 +3,34 @@ 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 { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
7
6
|
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
8
7
|
import type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';
|
|
9
8
|
import { errorPostgresMigrationStackMissing } from '../errors';
|
|
10
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
AddCheckConstraintCall,
|
|
11
|
+
AddColumnCall,
|
|
12
|
+
AddForeignKeyCall,
|
|
13
|
+
AddPrimaryKeyCall,
|
|
14
|
+
AddUniqueCall,
|
|
15
|
+
AlterColumnTypeCall,
|
|
16
|
+
type AlterColumnTypeOptions,
|
|
17
|
+
CreateIndexCall,
|
|
18
|
+
CreateSchemaCall,
|
|
19
|
+
CreateTableCall,
|
|
20
|
+
DropCheckConstraintCall,
|
|
21
|
+
DropColumnCall,
|
|
22
|
+
DropConstraintCall,
|
|
23
|
+
DropDefaultCall,
|
|
24
|
+
DropIndexCall,
|
|
25
|
+
DropNotNullCall,
|
|
26
|
+
DropTableCall,
|
|
27
|
+
SetDefaultCall,
|
|
28
|
+
SetNotNullCall,
|
|
29
|
+
} from './op-factory-call';
|
|
11
30
|
import { type DataTransformOptions, dataTransform } from './operations/data-transform';
|
|
31
|
+
import { installExtension } from './operations/dependencies';
|
|
32
|
+
import type { CreateIndexExtras } from './operations/indexes';
|
|
33
|
+
import type { ForeignKeySpec } from './operations/shared';
|
|
12
34
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
13
35
|
|
|
14
36
|
/**
|
|
@@ -30,6 +52,13 @@ import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
|
30
52
|
* instance method forwards to the free `dataTransform` factory with that
|
|
31
53
|
* stored adapter, so user migrations can write `this.dataTransform(...)`
|
|
32
54
|
* without threading the adapter through every call.
|
|
55
|
+
*
|
|
56
|
+
* Every method requires an explicit `schema`. Postgres migrations name their
|
|
57
|
+
* schema deliberately — there is no default and no `search_path`-relative
|
|
58
|
+
* option. A migration that left the schema unspecified would resolve against
|
|
59
|
+
* whatever `search_path` the connection happened to carry, and that ambiguity
|
|
60
|
+
* is an antipattern in a migration. (The unbound/unspecified namespace concept
|
|
61
|
+
* remains for SQLite, which has no schemas, and for Mongo's connection `db`.)
|
|
33
62
|
*/
|
|
34
63
|
export abstract class PostgresMigration extends SqlMigration<
|
|
35
64
|
PostgresPlanTargetDetails,
|
|
@@ -77,7 +106,7 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
77
106
|
* Throws if no adapter is present (i.e. migration instantiated without a stack).
|
|
78
107
|
*/
|
|
79
108
|
protected createTable(options: {
|
|
80
|
-
readonly schema
|
|
109
|
+
readonly schema: string;
|
|
81
110
|
readonly table: string;
|
|
82
111
|
readonly ifNotExists?: boolean;
|
|
83
112
|
readonly columns: readonly DdlColumn[];
|
|
@@ -87,7 +116,7 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
87
116
|
throw errorPostgresMigrationStackMissing();
|
|
88
117
|
}
|
|
89
118
|
return new CreateTableCall(
|
|
90
|
-
options.schema
|
|
119
|
+
options.schema,
|
|
91
120
|
options.table,
|
|
92
121
|
options.columns,
|
|
93
122
|
options.constraints,
|
|
@@ -110,17 +139,253 @@ export abstract class PostgresMigration extends SqlMigration<
|
|
|
110
139
|
}
|
|
111
140
|
|
|
112
141
|
protected addColumn(options: {
|
|
113
|
-
readonly schema
|
|
142
|
+
readonly schema: string;
|
|
114
143
|
readonly table: string;
|
|
115
144
|
readonly column: DdlColumn;
|
|
116
145
|
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
117
146
|
if (!this.controlAdapter) {
|
|
118
147
|
throw errorPostgresMigrationStackMissing();
|
|
119
148
|
}
|
|
120
|
-
return new AddColumnCall(
|
|
121
|
-
|
|
149
|
+
return new AddColumnCall(options.schema, options.table, options.column).toOp(
|
|
150
|
+
this.controlAdapter,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
protected addPrimaryKey(options: {
|
|
155
|
+
readonly schema: string;
|
|
156
|
+
readonly table: string;
|
|
157
|
+
readonly constraint: string;
|
|
158
|
+
readonly columns: readonly string[];
|
|
159
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
160
|
+
if (!this.controlAdapter) {
|
|
161
|
+
throw errorPostgresMigrationStackMissing();
|
|
162
|
+
}
|
|
163
|
+
return new AddPrimaryKeyCall(
|
|
164
|
+
options.schema,
|
|
165
|
+
options.table,
|
|
166
|
+
options.constraint,
|
|
167
|
+
options.columns,
|
|
168
|
+
).toOp(this.controlAdapter);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
protected addUnique(options: {
|
|
172
|
+
readonly schema: string;
|
|
173
|
+
readonly table: string;
|
|
174
|
+
readonly constraint: string;
|
|
175
|
+
readonly columns: readonly string[];
|
|
176
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
177
|
+
if (!this.controlAdapter) {
|
|
178
|
+
throw errorPostgresMigrationStackMissing();
|
|
179
|
+
}
|
|
180
|
+
return new AddUniqueCall(
|
|
181
|
+
options.schema,
|
|
182
|
+
options.table,
|
|
183
|
+
options.constraint,
|
|
184
|
+
options.columns,
|
|
185
|
+
).toOp(this.controlAdapter);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
protected addForeignKey(options: {
|
|
189
|
+
readonly schema: string;
|
|
190
|
+
readonly table: string;
|
|
191
|
+
readonly foreignKey: ForeignKeySpec;
|
|
192
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
193
|
+
if (!this.controlAdapter) {
|
|
194
|
+
throw errorPostgresMigrationStackMissing();
|
|
195
|
+
}
|
|
196
|
+
return new AddForeignKeyCall(options.schema, options.table, options.foreignKey).toOp(
|
|
197
|
+
this.controlAdapter,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
protected addCheckConstraint(options: {
|
|
202
|
+
readonly schema: string;
|
|
203
|
+
readonly table: string;
|
|
204
|
+
readonly constraint: string;
|
|
205
|
+
readonly column: string;
|
|
206
|
+
readonly values: readonly string[];
|
|
207
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
208
|
+
if (!this.controlAdapter) {
|
|
209
|
+
throw errorPostgresMigrationStackMissing();
|
|
210
|
+
}
|
|
211
|
+
return new AddCheckConstraintCall(
|
|
212
|
+
options.schema,
|
|
213
|
+
options.table,
|
|
214
|
+
options.constraint,
|
|
215
|
+
options.column,
|
|
216
|
+
options.values,
|
|
217
|
+
).toOp(this.controlAdapter);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
protected dropCheckConstraint(options: {
|
|
221
|
+
readonly schema: string;
|
|
222
|
+
readonly table: string;
|
|
223
|
+
readonly constraint: string;
|
|
224
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
225
|
+
if (!this.controlAdapter) {
|
|
226
|
+
throw errorPostgresMigrationStackMissing();
|
|
227
|
+
}
|
|
228
|
+
return new DropCheckConstraintCall(options.schema, options.table, options.constraint).toOp(
|
|
229
|
+
this.controlAdapter,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
protected dropConstraint(options: {
|
|
234
|
+
readonly schema: string;
|
|
235
|
+
readonly table: string;
|
|
236
|
+
readonly constraint: string;
|
|
237
|
+
readonly kind?: 'foreignKey' | 'unique' | 'primaryKey';
|
|
238
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
239
|
+
if (!this.controlAdapter) {
|
|
240
|
+
throw errorPostgresMigrationStackMissing();
|
|
241
|
+
}
|
|
242
|
+
return new DropConstraintCall(
|
|
243
|
+
options.schema,
|
|
244
|
+
options.table,
|
|
245
|
+
options.constraint,
|
|
246
|
+
options.kind ?? 'unique',
|
|
247
|
+
).toOp(this.controlAdapter);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
protected dropTable(options: {
|
|
251
|
+
readonly schema: string;
|
|
252
|
+
readonly table: string;
|
|
253
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
254
|
+
if (!this.controlAdapter) {
|
|
255
|
+
throw errorPostgresMigrationStackMissing();
|
|
256
|
+
}
|
|
257
|
+
return new DropTableCall(options.schema, options.table).toOp(this.controlAdapter);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
protected dropColumn(options: {
|
|
261
|
+
readonly schema: string;
|
|
262
|
+
readonly table: string;
|
|
263
|
+
readonly column: string;
|
|
264
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
265
|
+
if (!this.controlAdapter) {
|
|
266
|
+
throw errorPostgresMigrationStackMissing();
|
|
267
|
+
}
|
|
268
|
+
return new DropColumnCall(options.schema, options.table, options.column).toOp(
|
|
269
|
+
this.controlAdapter,
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
protected alterColumnType(options: {
|
|
274
|
+
readonly schema: string;
|
|
275
|
+
readonly table: string;
|
|
276
|
+
readonly column: string;
|
|
277
|
+
readonly options: AlterColumnTypeOptions;
|
|
278
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
279
|
+
if (!this.controlAdapter) {
|
|
280
|
+
throw errorPostgresMigrationStackMissing();
|
|
281
|
+
}
|
|
282
|
+
return new AlterColumnTypeCall(
|
|
283
|
+
options.schema,
|
|
122
284
|
options.table,
|
|
123
285
|
options.column,
|
|
286
|
+
options.options,
|
|
124
287
|
).toOp(this.controlAdapter);
|
|
125
288
|
}
|
|
289
|
+
|
|
290
|
+
protected setNotNull(options: {
|
|
291
|
+
readonly schema: string;
|
|
292
|
+
readonly table: string;
|
|
293
|
+
readonly column: string;
|
|
294
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
295
|
+
if (!this.controlAdapter) {
|
|
296
|
+
throw errorPostgresMigrationStackMissing();
|
|
297
|
+
}
|
|
298
|
+
return new SetNotNullCall(options.schema, options.table, options.column).toOp(
|
|
299
|
+
this.controlAdapter,
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
protected dropNotNull(options: {
|
|
304
|
+
readonly schema: string;
|
|
305
|
+
readonly table: string;
|
|
306
|
+
readonly column: string;
|
|
307
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
308
|
+
if (!this.controlAdapter) {
|
|
309
|
+
throw errorPostgresMigrationStackMissing();
|
|
310
|
+
}
|
|
311
|
+
return new DropNotNullCall(options.schema, options.table, options.column).toOp(
|
|
312
|
+
this.controlAdapter,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
protected setDefault(options: {
|
|
317
|
+
readonly schema: string;
|
|
318
|
+
readonly table: string;
|
|
319
|
+
readonly column: string;
|
|
320
|
+
readonly defaultSql: string;
|
|
321
|
+
readonly operationClass?: 'additive' | 'widening';
|
|
322
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
323
|
+
if (!this.controlAdapter) {
|
|
324
|
+
throw errorPostgresMigrationStackMissing();
|
|
325
|
+
}
|
|
326
|
+
return new SetDefaultCall(
|
|
327
|
+
options.schema,
|
|
328
|
+
options.table,
|
|
329
|
+
options.column,
|
|
330
|
+
options.defaultSql,
|
|
331
|
+
options.operationClass,
|
|
332
|
+
).toOp(this.controlAdapter);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
protected dropDefault(options: {
|
|
336
|
+
readonly schema: string;
|
|
337
|
+
readonly table: string;
|
|
338
|
+
readonly column: string;
|
|
339
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
340
|
+
if (!this.controlAdapter) {
|
|
341
|
+
throw errorPostgresMigrationStackMissing();
|
|
342
|
+
}
|
|
343
|
+
return new DropDefaultCall(options.schema, options.table, options.column).toOp(
|
|
344
|
+
this.controlAdapter,
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
protected createIndex(options: {
|
|
349
|
+
readonly schema: string;
|
|
350
|
+
readonly table: string;
|
|
351
|
+
readonly index: string;
|
|
352
|
+
readonly columns: readonly string[];
|
|
353
|
+
readonly extras?: CreateIndexExtras;
|
|
354
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
355
|
+
if (!this.controlAdapter) {
|
|
356
|
+
throw errorPostgresMigrationStackMissing();
|
|
357
|
+
}
|
|
358
|
+
return new CreateIndexCall(
|
|
359
|
+
options.schema,
|
|
360
|
+
options.table,
|
|
361
|
+
options.index,
|
|
362
|
+
options.columns,
|
|
363
|
+
options.extras,
|
|
364
|
+
).toOp(this.controlAdapter);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
protected dropIndex(options: {
|
|
368
|
+
readonly schema: string;
|
|
369
|
+
readonly table: string;
|
|
370
|
+
readonly index: string;
|
|
371
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
372
|
+
if (!this.controlAdapter) {
|
|
373
|
+
throw errorPostgresMigrationStackMissing();
|
|
374
|
+
}
|
|
375
|
+
return new DropIndexCall(options.schema, options.table, options.index).toOp(
|
|
376
|
+
this.controlAdapter,
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
protected installExtension(options: {
|
|
381
|
+
readonly extensionName: string;
|
|
382
|
+
readonly invariantId: string;
|
|
383
|
+
readonly id: string;
|
|
384
|
+
readonly label?: string;
|
|
385
|
+
}): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {
|
|
386
|
+
if (!this.controlAdapter) {
|
|
387
|
+
throw errorPostgresMigrationStackMissing();
|
|
388
|
+
}
|
|
389
|
+
return installExtension(options, this.controlAdapter);
|
|
390
|
+
}
|
|
126
391
|
}
|
|
@@ -39,7 +39,7 @@ function isAuthoringEntityTypeFactoryOutput(
|
|
|
39
39
|
* Walks a pack's entity-type namespace tree and emits hydration factories
|
|
40
40
|
* keyed by the descriptor's `discriminator`. Used for `storage.types`
|
|
41
41
|
* (codec-triple hydration). Namespace entries hydration dispatches by
|
|
42
|
-
* entries key, not discriminator — handled by `
|
|
42
|
+
* entries key, not discriminator — handled by `hydrateNamespaceEntities`.
|
|
43
43
|
*/
|
|
44
44
|
function collectStorageTypesHydrators(
|
|
45
45
|
namespace: AuthoringEntityTypeNamespace,
|