okmodel 0.7.0 → 0.9.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 +14 -0
- package/dist/adapters/capabilities.d.ts +32 -0
- package/dist/adapters/failure.d.ts +1 -1
- package/dist/adapters/pg/bun-sql.d.ts +53 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +1 -1
- package/dist/adapters/pg/bunsql.d.ts +1 -1
- package/dist/adapters/pg/neon-extra.d.ts +18 -0
- package/dist/adapters/pg/neon.d.ts +104 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +1 -1
- package/dist/contracts/error.d.ts +1 -1
- package/dist/dialects/pg/ext/btree-gin.d.ts +26 -0
- package/dist/dialects/pg/ext/btree-gin.js +20 -0
- package/dist/dialects/pg/ext/btree-gist.d.ts +26 -0
- package/dist/dialects/pg/ext/btree-gist.js +20 -0
- package/dist/dialects/pg/ext/call.d.ts +53 -0
- package/dist/dialects/pg/ext/citext.js +1 -1
- package/dist/dialects/pg/ext/feature.d.ts +26 -0
- package/dist/dialects/pg/ext/fuzzystrmatch.d.ts +34 -0
- package/dist/dialects/pg/ext/fuzzystrmatch.js +33 -0
- package/dist/dialects/pg/ext/hstore.d.ts +41 -0
- package/dist/dialects/pg/ext/hstore.js +29 -0
- package/dist/dialects/pg/ext/index.d.ts +56 -0
- package/dist/dialects/pg/ext/index.js +1 -1
- package/dist/dialects/pg/ext/ltree.d.ts +41 -0
- package/dist/dialects/pg/ext/ltree.js +29 -0
- package/dist/dialects/pg/ext/pg-trgm.js +4 -13
- package/dist/dialects/pg/ext/pgcrypto.d.ts +33 -0
- package/dist/dialects/pg/ext/pgcrypto.js +33 -0
- package/dist/dialects/pg/ext/unaccent.d.ts +26 -0
- package/dist/dialects/pg/ext/unaccent.js +21 -0
- package/dist/dialects/pg/ext/using.d.ts +23 -0
- package/dist/dialects/pg/ext/versions.d.ts +36 -0
- package/dist/dialects/pg/external.d.ts +19 -0
- package/dist/dialects/pg/fn/index.d.ts +39 -1
- package/dist/dialects/pg/fn/index.js +118 -26
- package/dist/dialects/pg/index.d.ts +3 -0
- package/dist/dialects/pg/index.js +394 -14
- package/dist/dialects/pg/introspect.d.ts +11 -0
- package/dist/dialects/pg/operators.d.ts +1 -1
- package/dist/dialects/pg/ops/fragment.d.ts +119 -0
- package/dist/dialects/pg/ops/lane.d.ts +49 -0
- package/dist/dialects/pg/view/client.d.ts +14 -6
- package/dist/dialects/pg/view/index.d.ts +73 -1
- package/dist/dialects/pg/view/index.js +156 -5
- package/dist/dialects/pg/view/scratch.d.ts +11 -5
- package/dist/runtime/artifact-file.d.ts +22 -0
- package/dist/runtime/client.d.ts +10 -0
- package/dist/runtime/drift-detail.d.ts +2 -1
- package/dist/runtime/drift.d.ts +3 -10
- package/dist/runtime/otel.d.ts +105 -0
- package/dist/runtime/otel.js +97 -0
- package/dist/runtime/pg/bun.js +4 -4
- package/dist/runtime/pg/neon.d.ts +38 -0
- package/dist/runtime/pg/neon.js +64 -0
- package/dist/runtime/pg/pg.js +4 -4
- package/dist/runtime/pg/pglite.js +4 -4
- package/dist/runtime/pg/postgresjs.js +4 -4
- package/dist/runtime/plan.d.ts +1 -1
- package/dist/runtime/server-check.d.ts +36 -6
- package/dist/runtime/sql-fragment.d.ts +43 -0
- package/dist/runtime/tenancy/index.js +10 -10
- package/dist/runtime/topology.d.ts +1 -1
- package/dist/runtime/traits/index.js +16 -17
- package/dist/runtime/types.d.ts +15 -1
- package/dist/runtime/validate/index.js +4 -4
- package/dist/shared/{81ebdx9p.js → 0j6qe91y.js} +4 -4
- package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
- package/dist/shared/{gzaveazc.js → 1d9q9cv2.js} +29 -2
- package/dist/shared/{w79hsckn.js → 1mxm04fy.js} +5 -5
- package/dist/shared/{7k9grvf6.js → 2szgv6yj.js} +5 -5
- package/dist/shared/{gs74dbj5.js → 2zdxkt7b.js} +933 -111
- package/dist/shared/{m6p12kbr.js → 3456242y.js} +23 -23
- package/dist/shared/3bb7wsqt.js +99 -0
- package/dist/shared/{y6njgyda.js → 3t6kw83m.js} +2 -2
- package/dist/shared/{xhfsfkgk.js → 4vbf83xx.js} +9 -2
- package/dist/shared/{pt94kz7f.js → 5kyb3tqx.js} +1 -1
- package/dist/shared/61bmrmhr.js +35 -0
- package/dist/shared/{x933k9a3.js → 62b603gr.js} +10 -10
- package/dist/shared/{jgqj11w4.js → 6f0z3hzh.js} +4 -0
- package/dist/shared/{tsvww22q.js → 6nae0spm.js} +156 -95
- package/dist/shared/{mtaszv5a.js → 71n0jmhc.js} +102 -4
- package/dist/shared/{5e3tf63j.js → 760ppr76.js} +14 -6
- package/dist/shared/7ba5h6pb.js +17 -0
- package/dist/shared/{sfz1ksn6.js → 8jesqsrk.js} +2 -2
- package/dist/shared/{5v3xf80k.js → 8n688yjg.js} +1 -1
- package/dist/shared/{rs73fca9.js → 8qzkd9f3.js} +6 -6
- package/dist/shared/{ax7qv55k.js → 90sg0w5a.js} +202 -25
- package/dist/shared/{zm0ptry0.js → 99qp9vtg.js} +1 -1
- package/dist/shared/{xnxsed62.js → 9dr2qnx7.js} +14 -14
- package/dist/shared/{1w508jbr.js → 9dtgn1z2.js} +21 -17
- package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
- package/dist/shared/{q5c6ngn3.js → a62rb2da.js} +1 -1
- package/dist/shared/{te5as7z7.js → aksb89mn.js} +3 -3
- package/dist/shared/{bz84tkzm.js → bphrgwz9.js} +2 -2
- package/dist/shared/bsek72fg.js +225 -0
- package/dist/shared/{7mnme5tn.js → c3mvnq7a.js} +1 -1
- package/dist/shared/{p6qc5gcp.js → ccsmhv9r.js} +25 -7
- package/dist/shared/{pbp1ss85.js → cexb7z6b.js} +2 -2
- package/dist/shared/{ab9gmbwy.js → cf8zdz5p.js} +5 -5
- package/dist/shared/{jvd0mqag.js → ckz05z15.js} +5 -5
- package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
- package/dist/shared/{14vx95q4.js → dd5pmnky.js} +7 -7
- package/dist/shared/{vb6qfyve.js → ds229x4r.js} +2 -2
- package/dist/shared/{1qa0qajz.js → e275q7sd.js} +1 -1
- package/dist/shared/{zp9fmend.js → ebhz8vh6.js} +4 -4
- package/dist/shared/{hyh73qk6.js → ecn8mfdq.js} +5 -5
- package/dist/shared/{je4axnm8.js → fdsz3w80.js} +2 -2
- package/dist/shared/{9s0ypp87.js → fk9vef30.js} +85 -74
- package/dist/shared/{g6evj1j3.js → g89fmz5s.js} +1 -1
- package/dist/shared/{aytqh5y2.js → ghqzdp94.js} +2 -2
- package/dist/shared/h9811jjm.js +17 -0
- package/dist/shared/{dkxgzaqd.js → hqpxf4a4.js} +1 -1
- package/dist/shared/{8skf0cam.js → jpybhf98.js} +1 -1
- package/dist/shared/{67txcrcw.js → kgwp4jdd.js} +4 -4
- package/dist/shared/kzgrnckd.js +29 -0
- package/dist/shared/mazpbcdj.js +233 -0
- package/dist/shared/{kb2sdhfb.js → mfvx6kjx.js} +17 -1
- package/dist/shared/{svncdeh5.js → mgaq2sd3.js} +11 -8
- package/dist/shared/{5mtf6cj3.js → mvmm3xpb.js} +5 -2
- package/dist/shared/{b5pftnn2.js → myk8fswx.js} +66 -21
- package/dist/shared/{2shdbn8q.js → n306gqkd.js} +9 -9
- package/dist/shared/{n816peh1.js → n454kcnw.js} +1 -1
- package/dist/shared/n5whk3mt.js +665 -0
- package/dist/shared/n7kg8mmx.js +61 -0
- package/dist/shared/{vqrjpcqn.js → nmnsgj7x.js} +1 -1
- package/dist/shared/{tbrvgw6z.js → npdftanb.js} +19 -26
- package/dist/shared/{ek2wt2dz.js → pg4ezgyf.js} +11 -30
- package/dist/shared/{5fe3kbsh.js → pgsak1yw.js} +1 -1
- package/dist/shared/{bm22fvzr.js → qfw14tna.js} +2 -2
- package/dist/shared/{wa07eas9.js → qvwwp1mp.js} +62 -41
- package/dist/shared/rbxt795q.js +1766 -0
- package/dist/shared/{xjk7hnn5.js → s7he5e5d.js} +2 -2
- package/dist/shared/{w72kgg4q.js → ss2kv2rs.js} +6 -6
- package/dist/shared/stfa9xcw.js +450 -0
- package/dist/shared/{3v7t1yrv.js → th3be82n.js} +2 -2
- package/dist/shared/{79dt02vc.js → tr64w5p0.js} +1 -1
- package/dist/shared/{cn957f8d.js → tw1nvvfj.js} +3 -3
- package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
- package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
- package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
- package/dist/shared/{vczs8gd4.js → wvtjg5m3.js} +2 -2
- package/dist/shared/{9y3mmmh1.js → xfhe73sb.js} +1 -1
- package/dist/shared/xqacq37x.js +61 -0
- package/dist/shared/{1est4ezg.js → xtsydxjg.js} +3 -3
- package/dist/shared/xv8qj97g.js +96 -0
- package/dist/shared/{bg3rym3g.js → xwhdcrm4.js} +2 -2
- package/dist/shared/{kr0jzbw2.js → yvabyg9k.js} +7 -7
- package/dist/shared/yybhre6n.js +136 -0
- package/dist/shared/zdqf8k5d.js +8 -0
- package/dist/shared/{jznfax0y.js → zq1he88x.js} +4 -4
- package/dist/tooling/cli.js +108 -23
- package/dist/tooling/driver-run.js +4654 -0
- package/dist/tooling/driver-test.d.ts +36 -0
- package/dist/tooling/github/comment.d.ts +50 -0
- package/dist/tooling/github/post-comment.d.ts +17 -0
- package/dist/tooling/migrate/commands.d.ts +3 -2
- package/dist/tooling/migrate/config.d.ts +13 -0
- package/dist/tooling/migrate/export.d.ts +165 -0
- package/dist/tooling/migrate/ext-surface.d.ts +80 -0
- package/dist/tooling/migrate/ext.d.ts +31 -4
- package/dist/tooling/migrate/import-drizzle.d.ts +40 -0
- package/dist/tooling/migrate/index.d.ts +3 -0
- package/dist/tooling/migrate/index.js +55 -10
- package/dist/tooling/migrate/lint-rules.d.ts +18 -1
- package/dist/tooling/migrate/lint.d.ts +14 -1
- package/dist/tooling/migrate/place.d.ts +18 -0
- package/dist/tooling/migrate/plan-json.d.ts +65 -0
- package/dist/tooling/migrate/project.d.ts +13 -1
- package/dist/tooling/migrate/pull-emit.d.ts +98 -0
- package/dist/tooling/migrate/pull-routines.d.ts +126 -0
- package/dist/tooling/migrate/pull-verify.d.ts +26 -0
- package/dist/tooling/migrate/pull.d.ts +62 -0
- package/dist/tooling/migrate/reprint.d.ts +32 -0
- package/dist/tooling/migrate/sandbox.d.ts +8 -2
- package/dist/tooling/migrate/schema-api.d.ts +43 -0
- package/dist/tooling/migrate/sql-lex.d.ts +18 -0
- package/dist/tooling/shared/04svnxxj.js +344 -0
- package/dist/tooling/shared/0j0jtse1.js +13 -0
- package/dist/tooling/shared/0r05zhyq.js +618 -0
- package/dist/tooling/shared/1800eymw.js +49 -0
- package/dist/tooling/shared/35zemrmf.js +12 -0
- package/dist/tooling/shared/3rmaz3pq.js +140 -0
- package/dist/tooling/shared/3yn79q5m.js +12 -0
- package/dist/tooling/shared/54tqkxja.js +51 -0
- package/dist/tooling/shared/57btdkgm.js +209 -0
- package/dist/tooling/shared/5bmksndh.js +118 -0
- package/dist/tooling/shared/5p8km5jb.js +38 -0
- package/dist/tooling/shared/5x3pf400.js +185 -0
- package/dist/tooling/shared/5zrzffnk.js +6 -0
- package/dist/tooling/shared/62fxpc1p.js +332 -0
- package/dist/tooling/shared/68tf18v4.js +20 -0
- package/dist/tooling/shared/6vk28rjp.js +98 -0
- package/dist/tooling/shared/76pv6qff.js +9 -0
- package/dist/tooling/shared/7aews1zg.js +311 -0
- package/dist/tooling/shared/7b3xp9gc.js +195 -0
- package/dist/tooling/shared/7kms6fvj.js +20 -0
- package/dist/tooling/shared/7pxncnzs.js +40 -0
- package/dist/tooling/shared/829fjxyw.js +198 -0
- package/dist/tooling/shared/8m5znpdt.js +66 -0
- package/dist/tooling/shared/8yr7ges1.js +211 -0
- package/dist/tooling/shared/96ps4g1z.js +32 -0
- package/dist/tooling/shared/9qr9rkbh.js +143 -0
- package/dist/tooling/shared/9sfbtwsk.js +49 -0
- package/dist/tooling/shared/9wsnsvbf.js +10 -0
- package/dist/tooling/shared/a2xe04bm.js +18 -0
- package/dist/tooling/shared/a4pzghha.js +20 -0
- package/dist/tooling/shared/am04v8na.js +233 -0
- package/dist/tooling/shared/asgr07mp.js +194 -0
- package/dist/tooling/shared/c0xevn1h.js +312 -0
- package/dist/tooling/shared/dhatassp.js +134 -0
- package/dist/tooling/shared/ezqn88nj.js +1696 -0
- package/dist/tooling/shared/f77nnfqy.js +231 -0
- package/dist/tooling/shared/fh07z1dt.js +15 -0
- package/dist/tooling/shared/gqwevek4.js +81 -0
- package/dist/tooling/shared/hfq3n3bd.js +4116 -0
- package/dist/tooling/shared/htnaj77v.js +17 -0
- package/dist/tooling/shared/j664qjrt.js +64 -0
- package/dist/tooling/shared/jpgmjsx3.js +38 -0
- package/dist/tooling/shared/jr2nmr81.js +497 -0
- package/dist/tooling/shared/jsjjz875.js +139 -0
- package/dist/tooling/shared/kbqnrs1x.js +1425 -0
- package/dist/tooling/shared/kz715295.js +94 -0
- package/dist/tooling/shared/m3xt8b1h.js +22 -0
- package/dist/tooling/shared/m4hhb8aa.js +9 -0
- package/dist/tooling/shared/mw5npye0.js +16 -0
- package/dist/tooling/shared/n4jqhpqz.js +27 -0
- package/dist/tooling/shared/nxq95eb6.js +42 -0
- package/dist/tooling/shared/qartgazh.js +70 -0
- package/dist/tooling/shared/rcywj2w8.js +190 -0
- package/dist/tooling/shared/s6qha57m.js +16 -0
- package/dist/tooling/shared/shjs0379.js +150 -0
- package/dist/tooling/shared/sjwkt1pg.js +16 -0
- package/dist/tooling/shared/stebqyyd.js +401 -0
- package/dist/tooling/shared/t4xveemq.js +250 -0
- package/dist/tooling/shared/t6zjeake.js +261 -0
- package/dist/tooling/shared/tcwpjvxe.js +9 -0
- package/dist/tooling/shared/tpssp7ac.js +160 -0
- package/dist/tooling/shared/v6j1ep6w.js +42 -0
- package/dist/tooling/shared/vwr2y833.js +270 -0
- package/dist/tooling/shared/w17sj05d.js +7 -0
- package/dist/tooling/shared/w5d89rb4.js +131 -0
- package/dist/tooling/shared/wbwq1jsa.js +157 -0
- package/dist/tooling/shared/wezxf3h8.js +17 -0
- package/dist/tooling/shared/yb4kd19s.js +12 -0
- package/dist/tooling/shared/ybdew6j7.js +294 -0
- package/dist/tooling/shared/yfedr1zb.js +6 -0
- package/dist/tooling/shared/yhp829bx.js +177 -0
- package/dist/tooling/shared/ytk1tjs0.js +604 -0
- package/dist/tooling/shared/zs9aymcp.js +210 -0
- package/dist/tooling/shared/zx3v9phv.js +8 -0
- package/dist/tooling/testing/index.js +3 -3
- package/package.json +50 -9
- package/dist/shared/ktz42yez.js +0 -113
- package/dist/shared/ttsqgp4p.js +0 -71
- package/dist/shared/y34a8714.js +0 -150
- package/dist/shared/zy8r7qvz.js +0 -116
- package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
- package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readSelectFragment,
|
|
3
|
+
emitSqlSelect,
|
|
4
|
+
decodeSqlNumber
|
|
5
|
+
} from "./ybdew6j7.js";
|
|
6
|
+
import"./w5d89rb4.js";
|
|
7
|
+
import {
|
|
8
|
+
refusePrototypeKey
|
|
9
|
+
} from "./0j0jtse1.js";
|
|
10
|
+
import {
|
|
11
|
+
throwNamed,
|
|
12
|
+
emitWhere,
|
|
13
|
+
emitOrder,
|
|
14
|
+
refuseHidden,
|
|
15
|
+
emitLimit,
|
|
16
|
+
parseOrder,
|
|
17
|
+
projectExpr,
|
|
18
|
+
indexes,
|
|
19
|
+
quote,
|
|
20
|
+
list,
|
|
21
|
+
isRecord,
|
|
22
|
+
fail2
|
|
23
|
+
} from "./hfq3n3bd.js";
|
|
24
|
+
|
|
25
|
+
// src/dialects/pg/ops/window.ts
|
|
26
|
+
var RUNTIME = Symbol.for("okmodel.window");
|
|
27
|
+
function isWindow(value) {
|
|
28
|
+
return typeof value === "object" && value !== null && RUNTIME in value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/runtime/window.ts
|
|
32
|
+
var AS_NUMBER = (wire) => Number(wire);
|
|
33
|
+
var AS_TEXT = (wire) => wire;
|
|
34
|
+
var NUMERIC = /^(smallint|integer|bigint|real|double precision|numeric|decimal)\b/;
|
|
35
|
+
var OPTION_KEYS = ["as", "orderBy", "partitionBy"];
|
|
36
|
+
function attach(schema, call) {
|
|
37
|
+
const table = indexesOf(schema, call.table);
|
|
38
|
+
return { ...call, build: statement(readSpec(table, call.select)) };
|
|
39
|
+
}
|
|
40
|
+
function statement(spec) {
|
|
41
|
+
return (schema, table, sink, outputs, call, hooks) => {
|
|
42
|
+
sink.mark(`${call.op}|${table.model.name}|`);
|
|
43
|
+
if (call.include !== undefined && hooks === undefined) {
|
|
44
|
+
fail2("OKM1120", "An include needs the include planner.");
|
|
45
|
+
}
|
|
46
|
+
const includes = hooks === undefined || call.include === undefined ? [] : hooks.read(schema, table, call.include, call.all);
|
|
47
|
+
sink.text("select ");
|
|
48
|
+
let column = 0;
|
|
49
|
+
for (const item of spec.items) {
|
|
50
|
+
if (column > 0)
|
|
51
|
+
sink.text(", ");
|
|
52
|
+
if (item.kind === "column") {
|
|
53
|
+
sink.text(projectExpr(`t.${quote(item.column.sql)}`, item.column.dataType));
|
|
54
|
+
sink.mark(`s:${item.column.field}`);
|
|
55
|
+
outputs?.fields.push({ key: item.column.field, at: column, decode: item.column.decode });
|
|
56
|
+
} else if (item.kind === "sql") {
|
|
57
|
+
emitSqlSelect(table, item.parts, sink, "t");
|
|
58
|
+
sink.text("::text");
|
|
59
|
+
sink.mark(`s:${item.as}`);
|
|
60
|
+
outputs?.fields.push({
|
|
61
|
+
key: item.as,
|
|
62
|
+
at: column,
|
|
63
|
+
decode: item.textual === true ? AS_TEXT : decodeSqlNumber
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
emitWindow(table, item.window, sink);
|
|
67
|
+
sink.text("::text");
|
|
68
|
+
outputs?.fields.push({ key: item.window.as, at: column, decode: item.window.decode });
|
|
69
|
+
}
|
|
70
|
+
column += 1;
|
|
71
|
+
}
|
|
72
|
+
if (spec.items.length === 0 && includes.length === 0)
|
|
73
|
+
sink.text("1");
|
|
74
|
+
for (let index = 0;index < includes.length; index += 1) {
|
|
75
|
+
const include = includes[index];
|
|
76
|
+
if (include === undefined || hooks === undefined)
|
|
77
|
+
continue;
|
|
78
|
+
column = hooks.select(include, `i${String(index)}`, sink, outputs, column);
|
|
79
|
+
}
|
|
80
|
+
sink.text(" from ");
|
|
81
|
+
sink.text(quote(table.model.sql));
|
|
82
|
+
sink.text(" t");
|
|
83
|
+
for (let index = 0;index < includes.length; index += 1) {
|
|
84
|
+
const include = includes[index];
|
|
85
|
+
if (include === undefined || hooks === undefined)
|
|
86
|
+
continue;
|
|
87
|
+
hooks.join(schema, include, sink, "t", `i${String(index)}`, 0);
|
|
88
|
+
}
|
|
89
|
+
emitWhere(schema, table, call.where, sink, "t", 0, false, call.after);
|
|
90
|
+
emitResultOrder(table, call.orderBy, sink, spec.ordinals);
|
|
91
|
+
emitLimit(call, sink);
|
|
92
|
+
call.tail?.(sink);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function emitResultOrder(table, orderBy, sink, ordinals) {
|
|
96
|
+
if (!isRecord(orderBy) || !mentionsOrdinal(orderBy, ordinals)) {
|
|
97
|
+
emitOrder(table, orderBy, sink, "t");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const keys = Object.keys(orderBy);
|
|
101
|
+
sink.text(" order by ");
|
|
102
|
+
for (let index = 0;index < keys.length; index += 1) {
|
|
103
|
+
const key = keys[index];
|
|
104
|
+
if (key === undefined)
|
|
105
|
+
continue;
|
|
106
|
+
const parsed = parseOrder(key, orderBy[key]);
|
|
107
|
+
if (index > 0)
|
|
108
|
+
sink.text(", ");
|
|
109
|
+
const ordinal = ordinals.get(key);
|
|
110
|
+
if (ordinal !== undefined) {
|
|
111
|
+
sink.text(ordinal);
|
|
112
|
+
} else {
|
|
113
|
+
const column = table.columns.get(key);
|
|
114
|
+
if (column === undefined) {
|
|
115
|
+
throwNamed("OKM1120", key, table.names, `Field ${key} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
|
|
116
|
+
}
|
|
117
|
+
refuseHidden(column);
|
|
118
|
+
sink.text("t.");
|
|
119
|
+
sink.text(quote(column.sql));
|
|
120
|
+
}
|
|
121
|
+
sink.text(parsed.dir === "asc" ? " asc" : " desc");
|
|
122
|
+
sink.text(parsed.nulls === "first" ? " nulls first" : " nulls last");
|
|
123
|
+
sink.mark(`o:${key}:${parsed.dir}:${parsed.nulls}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function mentionsOrdinal(orderBy, ordinals) {
|
|
127
|
+
if (ordinals.size === 0)
|
|
128
|
+
return false;
|
|
129
|
+
for (const key of Object.keys(orderBy)) {
|
|
130
|
+
if (ordinals.has(key))
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
function emitWindow(table, win, sink) {
|
|
136
|
+
sink.mark(`w:${win.fn}:${win.as}:p:${win.partition.map((column) => column.field).join("+")}`);
|
|
137
|
+
if (win.fn === "sum") {
|
|
138
|
+
const column = win.column;
|
|
139
|
+
if (column === undefined)
|
|
140
|
+
fail2("OKM1120", "runningTotal needs a column.");
|
|
141
|
+
sink.text("sum(t.");
|
|
142
|
+
sink.text(quote(column.sql));
|
|
143
|
+
sink.text(")");
|
|
144
|
+
} else {
|
|
145
|
+
sink.text(win.fn);
|
|
146
|
+
sink.text("()");
|
|
147
|
+
}
|
|
148
|
+
sink.text(" over (");
|
|
149
|
+
if (win.partition.length > 0) {
|
|
150
|
+
sink.text("partition by ");
|
|
151
|
+
for (let index = 0;index < win.partition.length; index += 1) {
|
|
152
|
+
const column = win.partition[index];
|
|
153
|
+
if (column === undefined)
|
|
154
|
+
continue;
|
|
155
|
+
if (index > 0)
|
|
156
|
+
sink.text(", ");
|
|
157
|
+
sink.text("t.");
|
|
158
|
+
sink.text(quote(column.sql));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
emitOrder(table, win.orderBy, sink, "t");
|
|
162
|
+
if (win.tieBreak) {
|
|
163
|
+
const named = isRecord(win.orderBy) ? Object.keys(win.orderBy) : [];
|
|
164
|
+
for (const field of table.model.primary) {
|
|
165
|
+
if (named.includes(field))
|
|
166
|
+
continue;
|
|
167
|
+
const column = table.columns.get(field);
|
|
168
|
+
if (column === undefined)
|
|
169
|
+
continue;
|
|
170
|
+
sink.text(", t.");
|
|
171
|
+
sink.text(quote(column.sql));
|
|
172
|
+
sink.text(" asc");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
sink.text(")");
|
|
176
|
+
}
|
|
177
|
+
function readSpec(table, select) {
|
|
178
|
+
if (!Array.isArray(select))
|
|
179
|
+
fail2("OKM1120", "select must be a list of field names.");
|
|
180
|
+
const items = [];
|
|
181
|
+
const ordinals = new Map;
|
|
182
|
+
const names = new Set;
|
|
183
|
+
for (const entry of select) {
|
|
184
|
+
if (typeof entry === "string") {
|
|
185
|
+
const column = columnOn(table, entry, "select");
|
|
186
|
+
names.add(column.field);
|
|
187
|
+
items.push({ kind: "column", column });
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const sql = readSelectFragment(entry);
|
|
191
|
+
if (sql !== undefined) {
|
|
192
|
+
const as = readAs(sql.as, "fragment");
|
|
193
|
+
if (names.has(as) || table.columns.has(as)) {
|
|
194
|
+
fail2("OKM1120", `fragment as ${as} clashes with a column of ${table.model.name}.`, "Pick an as name that is not a column.");
|
|
195
|
+
}
|
|
196
|
+
names.add(as);
|
|
197
|
+
ordinals.set(as, String(items.length + 1));
|
|
198
|
+
items.push(sql.textual === true ? { kind: "sql", as, parts: sql.parts, textual: true } : { kind: "sql", as, parts: sql.parts });
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (!isWindow(entry)) {
|
|
202
|
+
fail2("OKM1120", "select takes field names or a window helper. A plain object is not a window.", "Pass rowNumber, rank, denseRank, or runningTotal.");
|
|
203
|
+
}
|
|
204
|
+
const win = readWindow(table, entry, names);
|
|
205
|
+
names.add(win.as);
|
|
206
|
+
ordinals.set(win.as, String(items.length + 1));
|
|
207
|
+
items.push({ kind: "window", window: win });
|
|
208
|
+
}
|
|
209
|
+
return { items, ordinals };
|
|
210
|
+
}
|
|
211
|
+
function readWindow(table, call, taken) {
|
|
212
|
+
if (!isRecord(call))
|
|
213
|
+
fail2("OKM1120", "A window helper was not created by its function.");
|
|
214
|
+
for (const key of Object.keys(call)) {
|
|
215
|
+
if (key === "label" || key === "fn" || key === "column")
|
|
216
|
+
continue;
|
|
217
|
+
if (OPTION_KEYS.includes(key))
|
|
218
|
+
continue;
|
|
219
|
+
fail2("OKM1120", `${call.label} does not take ${key}. Accepted: partitionBy, orderBy, as.`, "Pass partitionBy, orderBy, and as.");
|
|
220
|
+
}
|
|
221
|
+
const as = readAs(call.as, call.label);
|
|
222
|
+
if (taken.has(as) || table.columns.has(as)) {
|
|
223
|
+
fail2("OKM1120", `${call.label} as ${as} clashes with a column of ${table.model.name}.`, "Pick an as name that is not a column.");
|
|
224
|
+
}
|
|
225
|
+
const partition = readPartition(table, call.partitionBy, call.label);
|
|
226
|
+
if (!isRecord(call.orderBy) || Object.keys(call.orderBy).length === 0) {
|
|
227
|
+
fail2("OKM1120", `${call.label} needs orderBy, the order inside the group.`, 'Pass orderBy: { field: "desc" }.');
|
|
228
|
+
}
|
|
229
|
+
for (const field of Object.keys(call.orderBy))
|
|
230
|
+
columnOn(table, field, `${call.label} orderBy`);
|
|
231
|
+
let column;
|
|
232
|
+
let decode = AS_NUMBER;
|
|
233
|
+
if (call.fn === "sum") {
|
|
234
|
+
if (typeof call.column !== "string") {
|
|
235
|
+
fail2("OKM1120", "runningTotal needs the column to total.");
|
|
236
|
+
}
|
|
237
|
+
column = columnOn(table, call.column, "runningTotal");
|
|
238
|
+
if (!NUMERIC.test(column.dataType)) {
|
|
239
|
+
fail2("OKM1124", `runningTotal does not apply to ${column.dataType} column ${column.field}. It takes integer, real, and numeric columns.`);
|
|
240
|
+
}
|
|
241
|
+
decode = totalDecode(column);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
fn: call.fn,
|
|
245
|
+
label: call.label,
|
|
246
|
+
column,
|
|
247
|
+
partition,
|
|
248
|
+
orderBy: call.orderBy,
|
|
249
|
+
as,
|
|
250
|
+
decode,
|
|
251
|
+
tieBreak: call.fn === "row_number" || call.fn === "sum"
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function readPartition(table, value, label) {
|
|
255
|
+
if (value === undefined)
|
|
256
|
+
return [];
|
|
257
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
258
|
+
fail2("OKM1120", `${label} partitionBy needs the fields that form the group.`, 'Pass partitionBy: ["status"], or leave it out to use the whole result.');
|
|
259
|
+
}
|
|
260
|
+
const columns = [];
|
|
261
|
+
const seen = new Set;
|
|
262
|
+
for (const name of value) {
|
|
263
|
+
if (typeof name !== "string") {
|
|
264
|
+
fail2("OKM1120", `${label} partitionBy takes field names.`);
|
|
265
|
+
}
|
|
266
|
+
const column = columnOn(table, name, `${label} partitionBy`);
|
|
267
|
+
if (seen.has(column.field)) {
|
|
268
|
+
fail2("OKM1120", `${label} partitionBy lists ${column.field} twice.`);
|
|
269
|
+
}
|
|
270
|
+
seen.add(column.field);
|
|
271
|
+
columns.push(column);
|
|
272
|
+
}
|
|
273
|
+
return columns;
|
|
274
|
+
}
|
|
275
|
+
function readAs(value, label) {
|
|
276
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
277
|
+
fail2("OKM1120", `${label} needs as, the name of the result key.`, "Set as to a name, such as n.");
|
|
278
|
+
}
|
|
279
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
280
|
+
if ((value.charCodeAt(index) ?? 0) < 32) {
|
|
281
|
+
fail2("OKM1120", `${label} as has a control character.`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
refusePrototypeKey(value, `${label} as`);
|
|
285
|
+
return value;
|
|
286
|
+
}
|
|
287
|
+
function totalDecode(column) {
|
|
288
|
+
const kind = typeof (column.decode?.("0") ?? "");
|
|
289
|
+
if (kind === "string")
|
|
290
|
+
return AS_TEXT;
|
|
291
|
+
if (kind === "number")
|
|
292
|
+
return AS_NUMBER;
|
|
293
|
+
return fail2("OKM1124", `runningTotal needs a column whose value is a number or a string. ${column.field} reads as ${kind}.`);
|
|
294
|
+
}
|
|
295
|
+
function columnOn(table, name, where) {
|
|
296
|
+
const column = table.columns.get(name);
|
|
297
|
+
if (column === undefined) {
|
|
298
|
+
throwNamed("OKM1120", name, table.names, `Field ${name} is not on ${table.model.name}. ${where} accepts: ${list(table.names)}.`);
|
|
299
|
+
}
|
|
300
|
+
if (where !== "select")
|
|
301
|
+
refuseHidden(column);
|
|
302
|
+
return column;
|
|
303
|
+
}
|
|
304
|
+
function indexesOf(schema, name) {
|
|
305
|
+
const table = indexes(schema).get(name);
|
|
306
|
+
if (table === undefined)
|
|
307
|
+
fail2("OKM1120", `Table ${name} is not in the schema.`);
|
|
308
|
+
return table;
|
|
309
|
+
}
|
|
310
|
+
export {
|
|
311
|
+
attach
|
|
312
|
+
};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withHttp,
|
|
3
|
+
attachHttp,
|
|
4
|
+
mapOptions
|
|
5
|
+
} from "./jr2nmr81.js";
|
|
6
|
+
import {
|
|
7
|
+
OkmError,
|
|
8
|
+
POSTGRES_FLOOR,
|
|
9
|
+
isPostgresMajor,
|
|
10
|
+
parsePostgresFloor,
|
|
11
|
+
serverNeedsPostgres
|
|
12
|
+
} from "./hfq3n3bd.js";
|
|
13
|
+
|
|
14
|
+
// src/runtime/artifact-file.ts
|
|
15
|
+
function artifactDir(catalogDir) {
|
|
16
|
+
if (catalogDir !== undefined)
|
|
17
|
+
return catalogDir.replace(/[/\\]+$/, "");
|
|
18
|
+
const cwd = globalThis.process?.cwd?.() ?? ".";
|
|
19
|
+
return `${cwd}/.okm`;
|
|
20
|
+
}
|
|
21
|
+
async function readText(path) {
|
|
22
|
+
const bun = globalThis.Bun;
|
|
23
|
+
if (bun !== undefined) {
|
|
24
|
+
const file = bun.file(path);
|
|
25
|
+
if (!await file.exists())
|
|
26
|
+
return;
|
|
27
|
+
return file.text();
|
|
28
|
+
}
|
|
29
|
+
const loader = globalThis.process?.getBuiltinModule;
|
|
30
|
+
if (loader === undefined)
|
|
31
|
+
return;
|
|
32
|
+
try {
|
|
33
|
+
return await loader("node:fs/promises").readFile(path, "utf8");
|
|
34
|
+
} catch {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/runtime/server-check.ts
|
|
40
|
+
var versionQuery = "select current_setting('server_version_num'), version(), (select (xpath('//catalog_hash/text()', query_to_xml('select catalog_hash from okm_meta where id = ''head''', true, false, '')))[1]::text where to_regclass('okm_meta') is not null)";
|
|
41
|
+
var historyQuery = "select migration_id, class, catalog_hash from okm_history order by migration_id, step_index";
|
|
42
|
+
async function versionSql(namespace) {
|
|
43
|
+
if (namespace === "public")
|
|
44
|
+
return versionQuery;
|
|
45
|
+
const relation = await qualified("okm_meta", namespace);
|
|
46
|
+
const literal = relation.replaceAll("'", "''");
|
|
47
|
+
return `select current_setting('server_version_num'), version(), (select (xpath('//catalog_hash/text()', query_to_xml('select catalog_hash from ${literal} where id = ''head''', true, false, '')))[1]::text where to_regclass('${literal}') is not null)`;
|
|
48
|
+
}
|
|
49
|
+
async function historySql2(namespace) {
|
|
50
|
+
if (namespace === "public")
|
|
51
|
+
return historyQuery;
|
|
52
|
+
return `select migration_id, class, catalog_hash from ${await qualified("okm_history", namespace)} order by migration_id, step_index`;
|
|
53
|
+
}
|
|
54
|
+
async function recordedNamespace(catalogDir) {
|
|
55
|
+
const text = await readText(`${artifactDir(catalogDir)}/namespace`);
|
|
56
|
+
if (text === undefined)
|
|
57
|
+
return "public";
|
|
58
|
+
const line = text.trim();
|
|
59
|
+
if (line === "" || line === "public")
|
|
60
|
+
return "public";
|
|
61
|
+
if (line.includes("\x00") || line.includes(`
|
|
62
|
+
`) || line.includes("\r")) {
|
|
63
|
+
throw new OkmError("OKM1122", "The catalog namespace file is not one identifier.", {
|
|
64
|
+
fix: { summary: "Run okm build so .okm/namespace is the schema from defineConfig." }
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return line;
|
|
68
|
+
}
|
|
69
|
+
async function acceptServer2(pool, schema, http, requireMeta, options, source) {
|
|
70
|
+
const namespace = await recordedNamespace(source.catalogDir);
|
|
71
|
+
let rows;
|
|
72
|
+
try {
|
|
73
|
+
const result = await pool.execute(await versionSql(namespace), undefined, options);
|
|
74
|
+
rows = result.rows;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
const { mapPostgresError } = await import("./yfedr1zb.js");
|
|
77
|
+
throw mapPostgresError(error, mapOptions(http, false, schema));
|
|
78
|
+
}
|
|
79
|
+
for (const name in schema.model) {
|
|
80
|
+
if (schema.model[name]?.presets !== undefined) {
|
|
81
|
+
(await import("./5bmksndh.js")).checkSchema(schema);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const version = rows[0]?.[1];
|
|
86
|
+
if (version === null || version === undefined || !version.startsWith("PostgreSQL")) {
|
|
87
|
+
throw new OkmError("OKM1801", "The server is not PostgreSQL. The schema dialect is postgres.", withHttp(http, {
|
|
88
|
+
fix: { summary: "Open the schema with the Postgres driver that matches it." }
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
const recorded = rows[0]?.[2];
|
|
92
|
+
if (recorded === null || recorded === undefined || recorded.length === 0) {
|
|
93
|
+
if (requireMeta) {
|
|
94
|
+
throw new OkmError("OKM1520", "okm_meta has no catalog hash.", withHttp(http, {
|
|
95
|
+
fix: {
|
|
96
|
+
summary: "Apply migrations so okm_meta records the catalog, or omit requireMeta to adopt this database."
|
|
97
|
+
}
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
const { assertCompatible } = await import("./qartgazh.js");
|
|
102
|
+
try {
|
|
103
|
+
await assertCompatible(pool, schema, recorded, source, options, namespace);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (error instanceof OkmError)
|
|
106
|
+
throw attachHttp(http, error);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const major = Math.floor(Number(rows[0]?.[0] ?? "0") / 1e4);
|
|
111
|
+
const raw = schema.requires?.postgres;
|
|
112
|
+
if (raw === undefined) {
|
|
113
|
+
if (major < POSTGRES_FLOOR) {
|
|
114
|
+
throw new OkmError("OKM1803", serverNeedsPostgres(major, POSTGRES_FLOOR), withHttp(http, {
|
|
115
|
+
fix: {
|
|
116
|
+
summary: `Upgrade to PostgreSQL ${String(POSTGRES_FLOOR)} or higher.`
|
|
117
|
+
}
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const need = parsePostgresFloor(raw);
|
|
123
|
+
if (!isPostgresMajor(need) || major < need) {
|
|
124
|
+
throw new OkmError("OKM1802", serverNeedsPostgres(major, isPostgresMajor(need) ? need : POSTGRES_FLOOR), withHttp(http, {
|
|
125
|
+
fix: { summary: "Upgrade the server, or lower minPostgres to a major the server meets." }
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function qualified(table, namespace) {
|
|
130
|
+
const { quoteIdent } = await import("./zx3v9phv.js");
|
|
131
|
+
return `${quoteIdent(namespace)}.${table}`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { artifactDir, readText, historySql2, acceptServer2 };
|