okmodel 0.2.1 → 0.4.0
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/README.md +882 -48
- package/dist/contracts/catalog/document.d.ts +6 -2
- package/dist/contracts/catalog/enum.d.ts +31 -4
- package/dist/contracts/catalog/extension.d.ts +61 -0
- package/dist/contracts/catalog/privilege.d.ts +64 -0
- package/dist/contracts/catalog/routine.d.ts +56 -0
- package/dist/contracts/catalog/types.d.ts +164 -10
- package/dist/contracts/catalog/view.d.ts +73 -0
- package/dist/dialects/pg/column.d.ts +3 -1
- package/dist/dialects/pg/ddl.d.ts +65 -1
- package/dist/dialects/pg/enum.d.ts +10 -8
- package/dist/dialects/pg/ext/citext.d.ts +14 -0
- package/dist/dialects/pg/ext/citext.js +11 -0
- package/dist/dialects/pg/ext/index.d.ts +52 -0
- package/dist/dialects/pg/ext/index.js +6 -0
- package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
- package/dist/dialects/pg/ext/pg-trgm.js +42 -0
- package/dist/dialects/pg/fn/index.d.ts +107 -0
- package/dist/dialects/pg/fn/index.js +175 -0
- package/dist/dialects/pg/fn/touch.d.ts +14 -0
- package/dist/dialects/pg/index.js +104 -19
- package/dist/dialects/pg/introspect.d.ts +10 -1
- package/dist/dialects/pg/operators.d.ts +8 -1
- package/dist/dialects/pg/role/check.d.ts +45 -0
- package/dist/dialects/pg/role/index.d.ts +50 -0
- package/dist/dialects/pg/role/sql.d.ts +51 -0
- package/dist/dialects/pg/table.d.ts +24 -1
- package/dist/dialects/pg/tenancy.d.ts +9 -0
- package/dist/dialects/pg/view/client.d.ts +30 -0
- package/dist/dialects/pg/view/depend.d.ts +35 -0
- package/dist/dialects/pg/view/index.d.ts +114 -0
- package/dist/dialects/pg/view/index.js +289 -0
- package/dist/dialects/pg/view/scratch.d.ts +22 -0
- package/dist/dialects/pg/where.d.ts +2 -2
- package/dist/runtime/catalog-cache.d.ts +17 -0
- package/dist/runtime/compat-words.d.ts +23 -0
- package/dist/runtime/drift-detail.d.ts +20 -4
- package/dist/runtime/drift.d.ts +4 -2
- package/dist/runtime/pg/bun.js +3 -3
- package/dist/runtime/pg/pg.js +3 -3
- package/dist/runtime/pg/pglite.js +3 -3
- package/dist/runtime/pg/postgresjs.js +3 -3
- package/dist/runtime/tenancy/index.js +6 -3
- package/dist/runtime/traits/index.d.ts +7 -2
- package/dist/runtime/traits/index.js +151 -13
- package/dist/runtime/types.d.ts +2 -0
- package/dist/runtime/validate/index.js +4 -4
- package/dist/shared/{xkz8g6by.js → 1g0drakv.js} +2 -2
- package/dist/shared/2321avmn.js +418 -0
- package/dist/shared/{7mht49yd.js → 3p4b1fg0.js} +57 -18
- package/dist/shared/41kv2xdm.js +318 -0
- package/dist/shared/{97g2jnrw.js → 4ef7mmqf.js} +3 -3
- package/dist/shared/{sacqha1y.js → 4m9fn52z.js} +2 -2
- package/dist/shared/5mtf6cj3.js +94 -0
- package/dist/shared/{1dp5knt7.js → 5vdm4sgp.js} +2 -2
- package/dist/shared/{a1gdp7j9.js → 6693j9rs.js} +1 -1
- package/dist/shared/{38crxbgn.js → 6p5k20sm.js} +3 -3
- package/dist/shared/7nk68fj8.js +751 -0
- package/dist/shared/84ptn35q.js +71 -0
- package/dist/shared/{d2whjz4k.js → 8jb4ymh2.js} +581 -28
- package/dist/shared/8ktwd3rh.js +97 -0
- package/dist/shared/94ez8kzh.js +19 -0
- package/dist/shared/{3a5ne750.js → 9m80mkac.js} +2 -2
- package/dist/shared/9x25fxhc.js +150 -0
- package/dist/shared/9yn6a2vd.js +11 -0
- package/dist/shared/ady1ms74.js +72 -0
- package/dist/shared/{4jzzghr6.js → awrsqrn7.js} +6 -6
- package/dist/shared/{4b9da9d7.js → axhk06q1.js} +19 -1
- package/dist/shared/{d04j53v8.js → c5g81ngb.js} +82 -14
- package/dist/shared/{n47rd821.js → c8aghh05.js} +1 -1
- package/dist/shared/{dd4f8mnx.js → c9z5g0fm.js} +4 -2
- package/dist/shared/{ps43134h.js → dyj86cmj.js} +4 -4
- package/dist/shared/{0qkxbm1f.js → fa9vt245.js} +1 -1
- package/dist/shared/{qa5dsc7z.js → fb00y8fp.js} +3 -3
- package/dist/shared/{qxa0yb9j.js → g7ez901n.js} +30 -1
- package/dist/shared/{py3nh7jy.js → gdh9mrtp.js} +2 -2
- package/dist/shared/{yw5c610b.js → gjthds9j.js} +2 -2
- package/dist/shared/hcmdtwgh.js +102 -0
- package/dist/shared/hqjsxnz7.js +13 -0
- package/dist/shared/htnaj77v.js +17 -0
- package/dist/shared/{v18jva5b.js → jgxzjzcz.js} +1 -1
- package/dist/shared/{x9v1qgeb.js → jsd07prz.js} +3 -3
- package/dist/shared/{g9f0zqce.js → kafaa5zv.js} +1 -1
- package/dist/shared/kj680nxv.js +19 -0
- package/dist/shared/{mxmcdsh5.js → kkzwp3d2.js} +9 -9
- package/dist/shared/{g1b5zzj9.js → n0dgs0pb.js} +1 -1
- package/dist/shared/n5y9zyj1.js +2431 -0
- package/dist/shared/{zt8y0wzb.js → n7mcc1gk.js} +1 -1
- package/dist/shared/{ge03bfca.js → nxb42q7h.js} +2 -2
- package/dist/shared/q6zsyh31.js +2192 -0
- package/dist/shared/{sfh4pk75.js → q795afwa.js} +26 -21
- package/dist/shared/{10tjenmd.js → qn0srwwq.js} +1 -1
- package/dist/shared/s4mb6a4b.js +545 -0
- package/dist/shared/{ytg3xf9p.js → sf8m6tfy.js} +3 -3
- package/dist/shared/{zd93g3rq.js → sr5ms7b3.js} +1 -1
- package/dist/shared/{xatfg0gn.js → tmbdywx0.js} +4 -19
- package/dist/shared/tny2t3sm.js +100 -0
- package/dist/shared/{e7a268fy.js → v7tpnhnz.js} +1 -1
- package/dist/shared/{ecdzej21.js → wqem4jed.js} +7 -7
- package/dist/shared/xghkt7a9.js +1144 -0
- package/dist/shared/y005b761.js +112 -0
- package/dist/shared/ycatkxmq.js +84 -0
- package/dist/shared/ygem90rn.js +900 -0
- package/dist/shared/{eaxwrgby.js → yjw02enp.js} +6 -3
- package/dist/shared/{mrq77sgw.js → zg24x0hm.js} +1 -1
- package/dist/shared/{cstgkzdx.js → zvbjc949.js} +1 -1
- package/dist/tooling/cli.js +66 -13
- package/dist/tooling/migrate/apply.d.ts +75 -5
- package/dist/tooling/migrate/backfill.d.ts +136 -0
- package/dist/tooling/migrate/check.d.ts +65 -0
- package/dist/tooling/migrate/classify.d.ts +108 -0
- package/dist/tooling/migrate/commands.d.ts +2 -1
- package/dist/tooling/migrate/config.d.ts +30 -0
- package/dist/tooling/migrate/doctor.d.ts +28 -0
- package/dist/tooling/migrate/drift.d.ts +35 -0
- package/dist/tooling/migrate/estimate.d.ts +50 -0
- package/dist/tooling/migrate/ext.d.ts +17 -0
- package/dist/tooling/migrate/extensions.d.ts +53 -0
- package/dist/tooling/migrate/files.d.ts +12 -0
- package/dist/tooling/migrate/index.d.ts +3 -2
- package/dist/tooling/migrate/index.js +67 -1
- package/dist/tooling/migrate/lint-rules.d.ts +51 -0
- package/dist/tooling/migrate/lint.d.ts +71 -0
- package/dist/tooling/migrate/managed.d.ts +17 -0
- package/dist/tooling/migrate/plan.d.ts +78 -10
- package/dist/tooling/migrate/project.d.ts +64 -5
- package/dist/tooling/migrate/provision.d.ts +18 -0
- package/dist/tooling/migrate/reference.d.ts +40 -0
- package/dist/tooling/migrate/runner.d.ts +108 -0
- package/dist/tooling/migrate/safe.d.ts +77 -0
- package/dist/tooling/migrate/seed.d.ts +20 -0
- package/dist/tooling/migrate/snapshot.d.ts +78 -0
- package/dist/tooling/migrate/status.d.ts +25 -6
- package/dist/tooling/migrate/type-name.d.ts +19 -0
- package/dist/tooling/testing/factories.d.ts +117 -0
- package/dist/tooling/testing/facts.d.ts +72 -0
- package/dist/tooling/testing/index.d.ts +89 -0
- package/dist/tooling/testing/index.js +8 -0
- package/dist/tooling/testing/isolation.d.ts +30 -0
- package/dist/tooling/testing/random.d.ts +40 -0
- package/dist/tooling/testing/record.d.ts +38 -0
- package/package.json +26 -2
- package/dist/shared/5z4q2zda.js +0 -2073
- package/dist/shared/eqmtn1bj.js +0 -399
- package/dist/shared/rtnaqre0.js +0 -37
- package/dist/shared/zwmqxb0g.js +0 -79
- package/dist/shared/{m9tv7xn7.js → radd3z4g.js} +3 -3
- /package/dist/shared/{9k6vetvf.js → rrstp3kb.js} +0 -0
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
encodeText,
|
|
3
|
-
decodeText
|
|
4
|
-
} from "./sacqha1y.js";
|
|
5
1
|
import {
|
|
6
2
|
catalog,
|
|
7
3
|
enumType,
|
|
8
4
|
sameEnumLabels
|
|
9
|
-
} from "./
|
|
5
|
+
} from "./g7ez901n.js";
|
|
10
6
|
import {
|
|
11
7
|
snakeCase,
|
|
12
8
|
emittedTypeName,
|
|
13
9
|
rejectLater
|
|
14
|
-
} from "./
|
|
10
|
+
} from "./jsd07prz.js";
|
|
15
11
|
import {
|
|
16
12
|
withLocation
|
|
17
13
|
} from "./k7dwkhvq.js";
|
|
14
|
+
import {
|
|
15
|
+
encodeText,
|
|
16
|
+
decodeText
|
|
17
|
+
} from "./4m9fn52z.js";
|
|
18
18
|
import {
|
|
19
19
|
ColumnBuilder2,
|
|
20
20
|
formatType
|
|
21
|
-
} from "./
|
|
21
|
+
} from "./c9z5g0fm.js";
|
|
22
22
|
import {
|
|
23
23
|
definition,
|
|
24
|
-
unavailable
|
|
24
|
+
unavailable
|
|
25
|
+
} from "./tmbdywx0.js";
|
|
26
|
+
import {
|
|
25
27
|
quoteLiteral
|
|
26
|
-
} from "./
|
|
28
|
+
} from "./94ez8kzh.js";
|
|
27
29
|
import {
|
|
28
30
|
staticNamespace2,
|
|
29
31
|
table3,
|
|
@@ -221,19 +223,18 @@ var SCHEMA_KNOWN = new Set([
|
|
|
221
223
|
"casing",
|
|
222
224
|
"codecs",
|
|
223
225
|
"defaults",
|
|
226
|
+
"extensions",
|
|
227
|
+
"functions",
|
|
224
228
|
"requires",
|
|
225
229
|
"tables",
|
|
226
230
|
"tenancy",
|
|
227
231
|
"traits",
|
|
232
|
+
"triggers",
|
|
228
233
|
"types",
|
|
229
|
-
"validation"
|
|
234
|
+
"validation",
|
|
235
|
+
"views"
|
|
230
236
|
]);
|
|
231
|
-
var SCHEMA_LATER = {
|
|
232
|
-
extensions: "0.3",
|
|
233
|
-
functions: "0.3",
|
|
234
|
-
triggers: "0.3",
|
|
235
|
-
views: "0.3"
|
|
236
|
-
};
|
|
237
|
+
var SCHEMA_LATER = {};
|
|
237
238
|
var BIGINT_CODECS = new Set(["string", "number", "bigint"]);
|
|
238
239
|
var NUMERIC_CODECS = new Set(["string", "number"]);
|
|
239
240
|
function stage(jobs, build) {
|
|
@@ -250,7 +251,7 @@ function schema2(config) {
|
|
|
250
251
|
}
|
|
251
252
|
const casing = readCasing(config.casing);
|
|
252
253
|
const tables = rewritePass(config.tables, tenancy, schemaTraits, casing);
|
|
253
|
-
const hooks = collectHooks(tenancy, schemaTraits, config.tables);
|
|
254
|
+
const hooks = collectHooks(tenancy, schemaTraits, config.tables, config.views);
|
|
254
255
|
const types = readTypes(config.types);
|
|
255
256
|
const codecs = readCodecs(config.codecs);
|
|
256
257
|
const requires = readRequires(config.requires);
|
|
@@ -281,6 +282,7 @@ function schema2(config) {
|
|
|
281
282
|
for (const item of prepared) {
|
|
282
283
|
model[item.tsName] = tableModel(item, edges, byName, accepted);
|
|
283
284
|
}
|
|
285
|
+
bindViews(config.views, model, tenancy, tables, casing);
|
|
284
286
|
let document;
|
|
285
287
|
return {
|
|
286
288
|
get catalog() {
|
|
@@ -296,6 +298,14 @@ function schema2(config) {
|
|
|
296
298
|
provenance: note.provenance
|
|
297
299
|
}));
|
|
298
300
|
}
|
|
301
|
+
contributeListed(config.extensions, objects);
|
|
302
|
+
contributeListed(config.functions, objects);
|
|
303
|
+
contributeListed(schemaTraits, objects);
|
|
304
|
+
for (const item of config.tables) {
|
|
305
|
+
contributeListed(item.options?.traits, objects);
|
|
306
|
+
}
|
|
307
|
+
contributeListed(config.triggers, objects);
|
|
308
|
+
contributeListed(config.views, objects);
|
|
299
309
|
document = catalog(objects);
|
|
300
310
|
}
|
|
301
311
|
return document;
|
|
@@ -379,7 +389,7 @@ var registeredHooks = [];
|
|
|
379
389
|
function addSchemaHook(hook) {
|
|
380
390
|
registeredHooks.push(hook);
|
|
381
391
|
}
|
|
382
|
-
function collectHooks(tenancy, schemaTraits, tables) {
|
|
392
|
+
function collectHooks(tenancy, schemaTraits, tables, views) {
|
|
383
393
|
const found = [];
|
|
384
394
|
const seen = new Set;
|
|
385
395
|
const add = (value) => {
|
|
@@ -391,6 +401,12 @@ function collectHooks(tenancy, schemaTraits, tables) {
|
|
|
391
401
|
seen.add(value);
|
|
392
402
|
found.push(hook.bind(value));
|
|
393
403
|
};
|
|
404
|
+
if (Array.isArray(views)) {
|
|
405
|
+
for (const item of views) {
|
|
406
|
+
if (typeof item === "object" && item !== null)
|
|
407
|
+
add(item);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
394
410
|
if (tenancy !== undefined)
|
|
395
411
|
add(tenancy);
|
|
396
412
|
if (schemaTraits !== undefined) {
|
|
@@ -410,6 +426,17 @@ function collectHooks(tenancy, schemaTraits, tables) {
|
|
|
410
426
|
found.push(hook);
|
|
411
427
|
return found.length === 0 ? undefined : found;
|
|
412
428
|
}
|
|
429
|
+
function bindViews(views, model, tenancy, tables, casing) {
|
|
430
|
+
if (!Array.isArray(views))
|
|
431
|
+
return;
|
|
432
|
+
const scoped = new Set;
|
|
433
|
+
for (const item of views) {
|
|
434
|
+
if (typeof item !== "object" || item === null)
|
|
435
|
+
continue;
|
|
436
|
+
const install = item.install;
|
|
437
|
+
install?.call(item, model, tenancy, tables, casing, scoped);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
413
440
|
function archiveModel(item) {
|
|
414
441
|
const archive = item.archiveModel;
|
|
415
442
|
return archive === undefined ? undefined : { archive };
|
|
@@ -423,6 +450,16 @@ function bareTables(tables) {
|
|
|
423
450
|
}
|
|
424
451
|
return tables;
|
|
425
452
|
}
|
|
453
|
+
function contributeListed(value, objects) {
|
|
454
|
+
if (!Array.isArray(value))
|
|
455
|
+
return;
|
|
456
|
+
for (const item of value) {
|
|
457
|
+
const produced = item.contribute(value, objects);
|
|
458
|
+
if (Array.isArray(produced))
|
|
459
|
+
for (const object of produced)
|
|
460
|
+
objects.push(object);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
426
463
|
function openSchemaTraits(value) {
|
|
427
464
|
if (value === undefined)
|
|
428
465
|
return;
|
|
@@ -650,6 +687,7 @@ function pushCompiled(objects, column, input) {
|
|
|
650
687
|
objects.push(compiled.check);
|
|
651
688
|
if (compiled.unique !== undefined)
|
|
652
689
|
objects.push(compiled.unique);
|
|
690
|
+
column.state.domain?.emit?.(input.parent.namespace, input.provenance, objects);
|
|
653
691
|
}
|
|
654
692
|
function compileUniques(tableName, options, parent, provenance, byField, jobs) {
|
|
655
693
|
const unique = options?.unique;
|
|
@@ -695,6 +733,7 @@ function compileIndexes(tableName, options, handles, parent, provenance, jobs) {
|
|
|
695
733
|
unique: built.isUnique === true,
|
|
696
734
|
nameKey: built.columns.join("_"),
|
|
697
735
|
...built.predicate !== undefined ? { predicate: built.predicate } : {},
|
|
736
|
+
...built.expression !== undefined ? { expression: built.expression } : {},
|
|
698
737
|
provenance
|
|
699
738
|
}));
|
|
700
739
|
}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import {
|
|
2
|
+
creationOrder2
|
|
3
|
+
} from "./8jb4ymh2.js";
|
|
4
|
+
import {
|
|
5
|
+
isDomain
|
|
6
|
+
} from "./g7ez901n.js";
|
|
7
|
+
import {
|
|
8
|
+
quoteLiteral
|
|
9
|
+
} from "./94ez8kzh.js";
|
|
10
|
+
import {
|
|
11
|
+
identityKey2
|
|
12
|
+
} from "./t4tbsy9h.js";
|
|
13
|
+
import {
|
|
14
|
+
fitIdentifier2
|
|
15
|
+
} from "./nfzc5z0w.js";
|
|
16
|
+
|
|
17
|
+
// src/dialects/pg/ddl.ts
|
|
18
|
+
function quoteIdent(name) {
|
|
19
|
+
return `"${name.replaceAll('"', '""')}"`;
|
|
20
|
+
}
|
|
21
|
+
function renderCatalog(source, schema) {
|
|
22
|
+
const folded = foldedKeys(source);
|
|
23
|
+
const statements = [];
|
|
24
|
+
const ordered = creationOrder2(source);
|
|
25
|
+
for (const object of ordered) {
|
|
26
|
+
if (object.kind !== "type" || object.owner === "ignored")
|
|
27
|
+
continue;
|
|
28
|
+
const sql = createObjectSql(object, schema);
|
|
29
|
+
if (sql !== undefined)
|
|
30
|
+
statements.push(sql);
|
|
31
|
+
}
|
|
32
|
+
for (const object of ordered) {
|
|
33
|
+
if (object.kind === "type" || object.kind === "function" || object.kind === "trigger" || object.kind === "view" || object.kind === "materializedView" || ownedByView(object)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (object.owner === "ignored")
|
|
37
|
+
continue;
|
|
38
|
+
const key = identityKey2(object.identity);
|
|
39
|
+
if (object.kind === "table") {
|
|
40
|
+
statements.push(createTableSql(object, source, schema));
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (folded.has(key))
|
|
44
|
+
continue;
|
|
45
|
+
const sql = createObjectSql(object, schema);
|
|
46
|
+
if (sql !== undefined)
|
|
47
|
+
statements.push(sql);
|
|
48
|
+
}
|
|
49
|
+
for (const kind of ["function", "trigger"]) {
|
|
50
|
+
for (const object of ordered) {
|
|
51
|
+
if (object.kind !== kind || object.owner === "ignored")
|
|
52
|
+
continue;
|
|
53
|
+
const sql = createObjectSql(object, schema);
|
|
54
|
+
if (sql !== undefined)
|
|
55
|
+
statements.push(sql);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const kind of ["view", "materializedView"]) {
|
|
59
|
+
for (const object of ordered) {
|
|
60
|
+
if (object.kind !== kind || object.owner === "ignored")
|
|
61
|
+
continue;
|
|
62
|
+
const sql = createObjectSql(object, schema);
|
|
63
|
+
if (sql !== undefined)
|
|
64
|
+
statements.push(sql);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (const object of ordered) {
|
|
68
|
+
if (!ownedByView(object) || object.owner === "ignored")
|
|
69
|
+
continue;
|
|
70
|
+
const sql = createObjectSql(object, schema);
|
|
71
|
+
if (sql !== undefined)
|
|
72
|
+
statements.push(sql);
|
|
73
|
+
}
|
|
74
|
+
return statements;
|
|
75
|
+
}
|
|
76
|
+
function ownedByView(object) {
|
|
77
|
+
if (object.kind !== "index")
|
|
78
|
+
return false;
|
|
79
|
+
return object.dependencies.some((edge) => edge.target.kind === "view" || edge.target.kind === "materializedView");
|
|
80
|
+
}
|
|
81
|
+
function dropObjectSql(object, schema) {
|
|
82
|
+
if (object.owner === "ignored")
|
|
83
|
+
return;
|
|
84
|
+
switch (object.kind) {
|
|
85
|
+
case "table":
|
|
86
|
+
return `drop table ${qualify(schema, object.identity.name)}`;
|
|
87
|
+
case "column":
|
|
88
|
+
return `alter table ${qualify(schema, object.identity.parent.name)} drop column ${quoteIdent(object.identity.name)}`;
|
|
89
|
+
case "index":
|
|
90
|
+
return `drop index ${qualify(schema, object.identity.name)}`;
|
|
91
|
+
case "constraint":
|
|
92
|
+
return `alter table ${qualify(schema, object.identity.parent.name)} drop constraint ${quoteIdent(object.identity.name)}`;
|
|
93
|
+
case "sequence":
|
|
94
|
+
return `drop sequence ${qualify(schema, object.identity.name)}`;
|
|
95
|
+
case "type":
|
|
96
|
+
return `drop type ${qualify(schema, object.identity.name)}`;
|
|
97
|
+
case "extension":
|
|
98
|
+
return `drop extension ${quoteIdent(object.identity.name)}`;
|
|
99
|
+
case "function":
|
|
100
|
+
return `drop function ${qualify(schema, object.identity.name)}(${object.identity.argTypes.join(", ")})`;
|
|
101
|
+
case "trigger":
|
|
102
|
+
return `drop trigger ${quoteIdent(object.identity.name)} on ${qualify(schema, object.identity.parent.name)}`;
|
|
103
|
+
case "view":
|
|
104
|
+
return `drop view ${qualify(schema, object.identity.name)}`;
|
|
105
|
+
case "materializedView":
|
|
106
|
+
return `drop materialized view ${qualify(schema, object.identity.name)}`;
|
|
107
|
+
default:
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function createObjectSql(object, schema) {
|
|
112
|
+
switch (object.kind) {
|
|
113
|
+
case "column":
|
|
114
|
+
return `alter table ${qualify(schema, object.identity.parent.name)} add column ${columnSql(object)}`;
|
|
115
|
+
case "index":
|
|
116
|
+
return createIndexSql(object, schema);
|
|
117
|
+
case "constraint":
|
|
118
|
+
return `alter table ${qualify(schema, object.identity.parent.name)} add constraint ${quoteIdent(object.identity.name)} ${constraintBody(object, schema)}`;
|
|
119
|
+
case "sequence":
|
|
120
|
+
return createSequenceSql(object, schema);
|
|
121
|
+
case "type":
|
|
122
|
+
return createTypeSql(object, schema);
|
|
123
|
+
case "extension":
|
|
124
|
+
return createExtensionSql(object);
|
|
125
|
+
case "function":
|
|
126
|
+
return functionSql(object, schema, false);
|
|
127
|
+
case "trigger":
|
|
128
|
+
return triggerSql(object, schema);
|
|
129
|
+
case "view":
|
|
130
|
+
return viewSql(object, schema, false);
|
|
131
|
+
case "materializedView":
|
|
132
|
+
return materializedViewSql(object, schema);
|
|
133
|
+
case "table":
|
|
134
|
+
return;
|
|
135
|
+
default:
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function functionSql(object, schema, replace) {
|
|
140
|
+
const definition = object.definition;
|
|
141
|
+
const args = definition.arguments.map((argument) => `${quoteIdent(argument.name)} ${argument.type}`).join(", ");
|
|
142
|
+
const head = `${replace ? "create or replace" : "create"} function ${qualify(schema, object.identity.name)}(${args})`;
|
|
143
|
+
const security = ` security ${definition.security}`;
|
|
144
|
+
const path = definition.searchPath === undefined ? "" : ` set search_path to ${definition.searchPath}`;
|
|
145
|
+
const tail = `returns ${definition.returns} language ${definition.language} ${definition.volatility}${security}${path}`;
|
|
146
|
+
if (definition.atomic)
|
|
147
|
+
return `${head} ${tail} ${definition.body}`;
|
|
148
|
+
return `${head} ${tail} as ${dollarQuote(definition.body)}`;
|
|
149
|
+
}
|
|
150
|
+
function viewSql(object, schema, replace) {
|
|
151
|
+
const verb = replace ? "create or replace view" : "create view";
|
|
152
|
+
return `${verb} ${qualify(schema, object.identity.name)} as ${object.definition.query}`;
|
|
153
|
+
}
|
|
154
|
+
function materializedViewSql(object, schema) {
|
|
155
|
+
return `create materialized view ${qualify(schema, object.identity.name)} as ${object.definition.query} with no data`;
|
|
156
|
+
}
|
|
157
|
+
function refreshMaterializedViewSql(object, schema, populated = false) {
|
|
158
|
+
const concurrently = populated && object.definition.refresh === "concurrently" ? " concurrently" : "";
|
|
159
|
+
return `refresh materialized view${concurrently} ${qualify(schema, object.identity.name)}`;
|
|
160
|
+
}
|
|
161
|
+
function triggerSql(object, schema) {
|
|
162
|
+
const definition = object.definition;
|
|
163
|
+
const timing = definition.timing === "instead" ? "instead of" : definition.timing;
|
|
164
|
+
const events = definition.events.map((event) => {
|
|
165
|
+
if (event !== "update" || definition.updateOf === undefined)
|
|
166
|
+
return event;
|
|
167
|
+
return `update of ${definition.updateOf.map((column) => quoteIdent(column)).join(", ")}`;
|
|
168
|
+
}).join(" or ");
|
|
169
|
+
const when = definition.when === undefined ? "" : ` when (${definition.when})`;
|
|
170
|
+
const args = definition.calls.argTypes.join(", ");
|
|
171
|
+
const fn = `${qualify(schema, definition.calls.name)}(${args})`;
|
|
172
|
+
return `create trigger ${quoteIdent(object.identity.name)} ${timing} ${events} on ${qualify(schema, object.identity.parent.name)} for each ${definition.level}${when} execute function ${fn}`;
|
|
173
|
+
}
|
|
174
|
+
function dollarQuote(body) {
|
|
175
|
+
let tag = "okm";
|
|
176
|
+
while (body.includes(`$${tag}$`))
|
|
177
|
+
tag = `${tag}_`;
|
|
178
|
+
return `$${tag}$${body}$${tag}$`;
|
|
179
|
+
}
|
|
180
|
+
function alterColumnSql(before, after, schema) {
|
|
181
|
+
const statements = [];
|
|
182
|
+
const table = qualify(schema, after.identity.parent.name);
|
|
183
|
+
const name = quoteIdent(after.identity.name);
|
|
184
|
+
const typeChanged = before.definition.dataType !== after.definition.dataType;
|
|
185
|
+
const collationChanged = before.definition.collation !== after.definition.collation;
|
|
186
|
+
if (typeChanged || collationChanged) {
|
|
187
|
+
const using = typeChanged ? ` using ${name}::${after.definition.dataType}` : "";
|
|
188
|
+
statements.push(`alter table ${table} alter column ${name} set data type ${after.definition.dataType}${collateSql(after.definition.collation)}${using}`);
|
|
189
|
+
}
|
|
190
|
+
if (before.definition.nullable !== after.definition.nullable) {
|
|
191
|
+
statements.push(`alter table ${table} alter column ${name} ${after.definition.nullable ? "drop not null" : "set not null"}`);
|
|
192
|
+
}
|
|
193
|
+
if (before.definition.defaultExpression !== after.definition.defaultExpression) {
|
|
194
|
+
statements.push(after.definition.defaultExpression === undefined ? `alter table ${table} alter column ${name} drop default` : `alter table ${table} alter column ${name} set default ${after.definition.defaultExpression}`);
|
|
195
|
+
}
|
|
196
|
+
return statements;
|
|
197
|
+
}
|
|
198
|
+
function identitySequence(sequence, source) {
|
|
199
|
+
const key = identityKey2(sequence.identity);
|
|
200
|
+
return source.objects.some((object) => {
|
|
201
|
+
if (object.kind !== "column" || object.definition.identity === undefined)
|
|
202
|
+
return false;
|
|
203
|
+
return object.dependencies.some((edge) => identityKey2(edge.target) === key);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
function foldedKeys(source) {
|
|
207
|
+
const keys = new Set;
|
|
208
|
+
for (const object of source.objects) {
|
|
209
|
+
if (object.kind === "column")
|
|
210
|
+
keys.add(identityKey2(object.identity));
|
|
211
|
+
if (object.kind === "constraint" && object.definition.constraintKind === "primaryKey") {
|
|
212
|
+
keys.add(identityKey2(object.identity));
|
|
213
|
+
}
|
|
214
|
+
if (object.kind === "sequence" && identitySequence(object, source)) {
|
|
215
|
+
keys.add(identityKey2(object.identity));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return keys;
|
|
219
|
+
}
|
|
220
|
+
function createTableSql(tableObject, source, schema) {
|
|
221
|
+
const parent = tableObject.identity.name;
|
|
222
|
+
const columns = source.objects.filter((object) => object.kind === "column" && object.identity.parent.name === parent);
|
|
223
|
+
const primary = source.objects.find((object) => object.kind === "constraint" && object.definition.constraintKind === "primaryKey" && object.identity.parent.name === parent);
|
|
224
|
+
const lines = columns.map((column) => columnSql(column));
|
|
225
|
+
if (primary !== undefined) {
|
|
226
|
+
const cols = primary.definition.columns.map((name) => quoteIdent(name)).join(", ");
|
|
227
|
+
lines.push(`constraint ${quoteIdent(primary.identity.name)} primary key (${cols})`);
|
|
228
|
+
}
|
|
229
|
+
const partition = tableObject.definition.partition;
|
|
230
|
+
const tail = partition === undefined ? "" : ` partition by ${partition.method} (${partition.columns.map((name) => quoteIdent(name)).join(", ")})`;
|
|
231
|
+
return `create table ${qualify(schema, parent)} (
|
|
232
|
+
${lines.join(`,
|
|
233
|
+
`)}
|
|
234
|
+
)${tail}`;
|
|
235
|
+
}
|
|
236
|
+
function collateSql(collation) {
|
|
237
|
+
if (collation === undefined)
|
|
238
|
+
return "";
|
|
239
|
+
return ` collate ${quoteIdent(collation)}`;
|
|
240
|
+
}
|
|
241
|
+
function createTypeSql(object, schema) {
|
|
242
|
+
if (isDomain(object.definition)) {
|
|
243
|
+
const name = object.identity.name;
|
|
244
|
+
const constraint = quoteIdent(fitIdentifier2(`${name}_check`));
|
|
245
|
+
return `create domain ${qualify(schema, name)} as ${object.definition.base} constraint ${constraint} check (${object.definition.check})`;
|
|
246
|
+
}
|
|
247
|
+
const labels = object.definition.labels.map((label) => quoteLiteral(label)).join(", ");
|
|
248
|
+
return `create type ${qualify(schema, object.identity.name)} as enum (${labels})`;
|
|
249
|
+
}
|
|
250
|
+
function columnSql(column) {
|
|
251
|
+
const definition = column.definition;
|
|
252
|
+
let sql = `${quoteIdent(column.identity.name)} ${definition.dataType}${collateSql(definition.collation)}`;
|
|
253
|
+
if (definition.identity !== undefined) {
|
|
254
|
+
sql += definition.identity.always ? " generated always as identity" : " generated by default as identity";
|
|
255
|
+
} else if (definition.generated !== undefined) {
|
|
256
|
+
sql += ` generated always as (${definition.generated.expression}) stored`;
|
|
257
|
+
}
|
|
258
|
+
if (!definition.nullable)
|
|
259
|
+
sql += " not null";
|
|
260
|
+
if (definition.defaultExpression !== undefined)
|
|
261
|
+
sql += ` default ${definition.defaultExpression}`;
|
|
262
|
+
return sql;
|
|
263
|
+
}
|
|
264
|
+
function createIndexSql(object, schema) {
|
|
265
|
+
const unique = object.definition.unique ? "unique " : "";
|
|
266
|
+
const where = object.definition.predicate === undefined ? "" : ` where ${object.definition.predicate}`;
|
|
267
|
+
const expression = object.definition.expression;
|
|
268
|
+
const name = quoteIdent(object.identity.name);
|
|
269
|
+
const on = qualify(schema, object.identity.parent.name);
|
|
270
|
+
if (expression !== undefined && expression.startsWith("using ")) {
|
|
271
|
+
return `create ${unique}index ${name} on ${on} ${expression}${where}`;
|
|
272
|
+
}
|
|
273
|
+
const target = expression !== undefined ? `(${expression})` : object.definition.columns.map((column) => quoteIdent(column)).join(", ");
|
|
274
|
+
return `create ${unique}index ${name} on ${on} (${target})${where}`;
|
|
275
|
+
}
|
|
276
|
+
function createExtensionSql(object) {
|
|
277
|
+
const version = object.definition.version;
|
|
278
|
+
const pinned = version !== undefined && /^\d+(?:\.\d+)*$/.test(version) ? ` version ${quoteLiteral(version)}` : "";
|
|
279
|
+
return `create extension ${quoteIdent(object.identity.name)} schema ${quoteIdent(object.definition.schema)}${pinned}`;
|
|
280
|
+
}
|
|
281
|
+
function createSequenceSql(object, schema) {
|
|
282
|
+
const definition = object.definition;
|
|
283
|
+
const cycle = definition.cycle ? " cycle" : "";
|
|
284
|
+
return `create sequence ${qualify(schema, object.identity.name)} as ${definition.dataType} start ${definition.start} increment ${definition.increment}${cycle}`;
|
|
285
|
+
}
|
|
286
|
+
function constraintBody(object, schema) {
|
|
287
|
+
const definition = object.definition;
|
|
288
|
+
const columns = definition.columns.map((name) => quoteIdent(name)).join(", ");
|
|
289
|
+
switch (definition.constraintKind) {
|
|
290
|
+
case "primaryKey":
|
|
291
|
+
return `primary key (${columns})`;
|
|
292
|
+
case "unique": {
|
|
293
|
+
const nulls = definition.nullsNotDistinct ? " nulls not distinct" : "";
|
|
294
|
+
return `unique${nulls} (${columns})${deferClause(definition)}`;
|
|
295
|
+
}
|
|
296
|
+
case "check":
|
|
297
|
+
return `check (${definition.expression ?? "true"})${deferClause(definition)}`;
|
|
298
|
+
case "foreignKey": {
|
|
299
|
+
const references = definition.references;
|
|
300
|
+
const target = references === undefined ? "" : ` references ${qualify(schema, references.parent.name)} (${references.columns.map((name) => quoteIdent(name)).join(", ")})`;
|
|
301
|
+
const onDelete = references?.onDelete === undefined ? "" : ` on delete ${references.onDelete}`;
|
|
302
|
+
const onUpdate = references?.onUpdate === undefined ? "" : ` on update ${references.onUpdate}`;
|
|
303
|
+
return `foreign key (${columns})${target}${onDelete}${onUpdate}${deferClause(definition)}`;
|
|
304
|
+
}
|
|
305
|
+
default:
|
|
306
|
+
return definition.constraintKind;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function deferClause(definition) {
|
|
310
|
+
if (!definition.deferrable)
|
|
311
|
+
return "";
|
|
312
|
+
return ` deferrable initially ${definition.initially}`;
|
|
313
|
+
}
|
|
314
|
+
function qualify(schema, name) {
|
|
315
|
+
return `${quoteIdent(schema)}.${quoteIdent(name)}`;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export { quoteIdent, renderCatalog, ownedByView, dropObjectSql, createObjectSql, functionSql, viewSql, refreshMaterializedViewSql, alterColumnSql, identitySequence, createTableSql, qualify };
|
|
@@ -2,17 +2,17 @@ import {
|
|
|
2
2
|
send2,
|
|
3
3
|
reserve,
|
|
4
4
|
park
|
|
5
|
-
} from "./
|
|
5
|
+
} from "./sf8m6tfy.js";
|
|
6
6
|
import {
|
|
7
7
|
isConnectionLost
|
|
8
8
|
} from "./tbszx8mz.js";
|
|
9
9
|
import {
|
|
10
10
|
WireSession
|
|
11
|
-
} from "./
|
|
11
|
+
} from "./zvbjc949.js";
|
|
12
12
|
import {
|
|
13
13
|
rejectClosed,
|
|
14
14
|
runCall
|
|
15
|
-
} from "./
|
|
15
|
+
} from "./rrstp3kb.js";
|
|
16
16
|
|
|
17
17
|
// src/adapters/pg/bunsql-extra.ts
|
|
18
18
|
async function checkout(held) {
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BEHIND_EXPAND,
|
|
3
|
+
BEHIND_CONTRACT,
|
|
4
|
+
AHEAD_CONTRACT
|
|
5
|
+
} from "./9yn6a2vd.js";
|
|
6
|
+
import {
|
|
7
|
+
OkmError2
|
|
8
|
+
} from "./52szzakm.js";
|
|
9
|
+
|
|
10
|
+
// src/runtime/drift-detail.ts
|
|
11
|
+
function driftVerdict(codeHash, recordedHash, migrations) {
|
|
12
|
+
const codeAt = indexOfHash(migrations, codeHash);
|
|
13
|
+
const recordedAt = indexOfHash(migrations, recordedHash);
|
|
14
|
+
if (codeAt >= 0 && recordedAt >= codeAt) {
|
|
15
|
+
for (let index = codeAt + 1;index <= recordedAt; index += 1) {
|
|
16
|
+
const migration = migrations[index];
|
|
17
|
+
if (migration !== undefined && migration.expand !== true) {
|
|
18
|
+
return { state: "ahead by contract", migrationId: migration.id };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return { state: "ok" };
|
|
22
|
+
}
|
|
23
|
+
if (codeAt >= 0 && recordedAt >= 0 && recordedAt < codeAt) {
|
|
24
|
+
const next = migrations[recordedAt + 1];
|
|
25
|
+
if (next !== undefined) {
|
|
26
|
+
return {
|
|
27
|
+
state: next.expand ? "behind by expand" : "behind by contract",
|
|
28
|
+
migrationId: next.id
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (recordedAt >= 0) {
|
|
33
|
+
const at = migrations[recordedAt];
|
|
34
|
+
if (at !== undefined)
|
|
35
|
+
return { state: "behind", migrationId: at.id };
|
|
36
|
+
}
|
|
37
|
+
const last = migrations.at(-1);
|
|
38
|
+
return { state: "behind", migrationId: last?.id ?? "" };
|
|
39
|
+
}
|
|
40
|
+
async function assertDrift(pool, codeHash, recordedHash, options) {
|
|
41
|
+
let rows;
|
|
42
|
+
try {
|
|
43
|
+
const result = await pool.execute("select migration_id, class, catalog_hash from okm_history order by migration_id, step_index", undefined, options);
|
|
44
|
+
rows = result.rows;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw gapError({ state: "behind", migrationId: "" }, error);
|
|
47
|
+
}
|
|
48
|
+
const verdict = driftVerdict(codeHash, recordedHash, groupMigrations(rows));
|
|
49
|
+
if (verdict.state === "ok")
|
|
50
|
+
return;
|
|
51
|
+
throw gapError(verdict);
|
|
52
|
+
}
|
|
53
|
+
function indexOfHash(migrations, hash) {
|
|
54
|
+
let found = -1;
|
|
55
|
+
for (let index = 0;index < migrations.length; index += 1) {
|
|
56
|
+
if (migrations[index]?.catalogHash === hash)
|
|
57
|
+
found = index;
|
|
58
|
+
}
|
|
59
|
+
return found;
|
|
60
|
+
}
|
|
61
|
+
function groupMigrations(rows) {
|
|
62
|
+
const grouped = [];
|
|
63
|
+
for (const row of rows) {
|
|
64
|
+
const id = row[0];
|
|
65
|
+
const stepClass = row[1];
|
|
66
|
+
const hash = row[2];
|
|
67
|
+
if (id == null || stepClass == null || hash == null)
|
|
68
|
+
continue;
|
|
69
|
+
const expand = stepClass === "expand";
|
|
70
|
+
const last = grouped.at(-1);
|
|
71
|
+
if (last !== undefined && last.id === id) {
|
|
72
|
+
grouped[grouped.length - 1] = {
|
|
73
|
+
id,
|
|
74
|
+
catalogHash: hash,
|
|
75
|
+
expand: last.expand && expand
|
|
76
|
+
};
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
grouped.push({ id, catalogHash: hash, expand });
|
|
80
|
+
}
|
|
81
|
+
return grouped;
|
|
82
|
+
}
|
|
83
|
+
function gapError(verdict, cause) {
|
|
84
|
+
const named = verdict.migrationId;
|
|
85
|
+
const phrase = verdict.state === "ahead by contract" ? `${AHEAD_CONTRACT} migration ${named}` : verdict.state === "behind by expand" ? `${BEHIND_EXPAND} migration ${named}` : verdict.state === "behind by contract" ? `${BEHIND_CONTRACT} migration ${named}` : named.length > 0 ? `behind the app at migration ${named}` : "behind the app";
|
|
86
|
+
const fix = named.length > 0 ? `Apply ${named}, or change the deploy order.` : "Apply migrations, or change the deploy order.";
|
|
87
|
+
return new OkmError2("OKM1520", `The database is ${phrase}.`, {
|
|
88
|
+
...cause === undefined ? {} : { cause },
|
|
89
|
+
fix: { summary: fix }
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
assertDrift
|
|
94
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PgSession
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./wqem4jed.js";
|
|
4
4
|
import {
|
|
5
5
|
isConnectionLost
|
|
6
6
|
} from "./tbszx8mz.js";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
runCall,
|
|
12
12
|
rowsFrom,
|
|
13
13
|
resultFrom
|
|
14
|
-
} from "./
|
|
14
|
+
} from "./rrstp3kb.js";
|
|
15
15
|
|
|
16
16
|
// src/adapters/pg/postgres-extra.ts
|
|
17
17
|
var RESET_ALL = "RESET ALL";
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
noticeBuffer,
|
|
4
4
|
WireSession,
|
|
5
5
|
cursorStream
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./zvbjc949.js";
|
|
7
7
|
import {
|
|
8
8
|
NODE_POSTGRES_CAPABILITIES,
|
|
9
9
|
driverErrors,
|
|
10
10
|
rejectClosed,
|
|
11
11
|
mapFailure,
|
|
12
12
|
runCall
|
|
13
|
-
} from "./
|
|
13
|
+
} from "./rrstp3kb.js";
|
|
14
14
|
|
|
15
15
|
// src/adapters/pg/nodepostgres.ts
|
|
16
16
|
import net from "node:net";
|
|
@@ -53,7 +53,7 @@ function open4(config) {
|
|
|
53
53
|
counters.busy = Math.max(0, counters.busy - 1);
|
|
54
54
|
}, inflight);
|
|
55
55
|
const held = { pool, acquireMs, counters, notices, named, isClosed };
|
|
56
|
-
const checkout = () => closed ? rejectClosed() : import("./
|
|
56
|
+
const checkout = () => closed ? rejectClosed() : import("./fb00y8fp.js").then((mod) => mod.checkout(held));
|
|
57
57
|
return {
|
|
58
58
|
capabilities: NODE_POSTGRES_CAPABILITIES,
|
|
59
59
|
execute(text, params, options) {
|