okmodel 0.5.1 → 0.7.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 +100 -1116
- package/dist/adapters/capabilities.d.ts +3 -0
- package/dist/adapters/failure.d.ts +13 -2
- package/dist/adapters/lazy-errors.d.ts +22 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
- package/dist/adapters/pg/bunsql.d.ts +14 -1
- package/dist/adapters/pg/cursor.d.ts +17 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +20 -0
- package/dist/adapters/pg/nodepostgres-extra.d.ts +22 -1
- package/dist/adapters/pg/nodepostgres.d.ts +12 -0
- package/dist/adapters/pg/pglite-wire.d.ts +24 -0
- package/dist/adapters/pg/pglite.d.ts +10 -0
- package/dist/adapters/pg/postgres-extra.d.ts +41 -3
- package/dist/adapters/pg/reserved.d.ts +42 -0
- package/dist/adapters/pg/session.d.ts +0 -18
- package/dist/contracts/catalog/document.d.ts +19 -5
- package/dist/contracts/catalog/object.d.ts +2 -1
- package/dist/contracts/catalog/policy.d.ts +48 -0
- package/dist/contracts/catalog/types.d.ts +25 -1
- package/dist/contracts/catalog/view.d.ts +2 -0
- package/dist/contracts/connection.d.ts +7 -6
- package/dist/contracts/internal.js +1 -1
- package/dist/contracts/location.d.ts +10 -0
- package/dist/dialects/pg/column.d.ts +13 -2
- package/dist/dialects/pg/ddl.d.ts +37 -1
- package/dist/dialects/pg/emit.d.ts +19 -1
- package/dist/dialects/pg/errors.d.ts +32 -1
- package/dist/dialects/pg/ext/citext.js +1 -1
- package/dist/dialects/pg/ext/index.js +1 -1
- package/dist/dialects/pg/ext/pg-trgm.js +1 -1
- package/dist/dialects/pg/filter-parse.d.ts +5 -4
- package/dist/dialects/pg/floor.d.ts +68 -0
- package/dist/dialects/pg/fn/index.js +2 -2
- package/dist/dialects/pg/index.d.ts +8 -2
- package/dist/dialects/pg/index.js +67 -171
- package/dist/dialects/pg/introspect.d.ts +7 -0
- package/dist/dialects/pg/keys.d.ts +11 -8
- package/dist/dialects/pg/model.d.ts +47 -2
- package/dist/dialects/pg/morph.d.ts +43 -0
- package/dist/dialects/pg/operator-fit.d.ts +2 -2
- package/dist/dialects/pg/operators.d.ts +14 -7
- package/dist/dialects/pg/ops/bucket.d.ts +65 -0
- package/dist/dialects/pg/ops/inc.d.ts +2 -2
- package/dist/dialects/pg/ops/matches.d.ts +9 -12
- package/dist/dialects/pg/ops/relevance.d.ts +13 -0
- package/dist/dialects/pg/ops/search-query.d.ts +22 -0
- package/dist/dialects/pg/ops/window.d.ts +103 -0
- package/dist/dialects/pg/owner.d.ts +42 -0
- package/dist/dialects/pg/path-endpoint.d.ts +20 -0
- package/dist/dialects/pg/preset.d.ts +1 -1
- package/dist/dialects/pg/relations.d.ts +100 -3
- package/dist/dialects/pg/role/check.d.ts +3 -0
- package/dist/dialects/pg/role/index.d.ts +71 -6
- package/dist/dialects/pg/role/sql.d.ts +11 -0
- package/dist/dialects/pg/schema.d.ts +33 -3
- package/dist/dialects/pg/table.d.ts +25 -3
- package/dist/dialects/pg/tenancy.d.ts +45 -3
- package/dist/dialects/pg/view/client.d.ts +19 -1
- package/dist/dialects/pg/view/index.d.ts +4 -0
- package/dist/dialects/pg/view/index.js +21 -178
- package/dist/dialects/pg/view/refresh.d.ts +24 -0
- package/dist/runtime/aggregate.d.ts +8 -2
- package/dist/runtime/batch.d.ts +1 -1
- package/dist/runtime/bucket-group.d.ts +70 -0
- package/dist/runtime/conflict.d.ts +24 -6
- package/dist/runtime/drift.d.ts +9 -0
- package/dist/runtime/include.d.ts +0 -8
- package/dist/runtime/inflight.d.ts +14 -0
- package/dist/runtime/page.d.ts +4 -1
- package/dist/runtime/pg/bun.js +12 -5
- package/dist/runtime/pg/pg.js +5 -5
- package/dist/runtime/pg/pglite.d.ts +1 -0
- package/dist/runtime/pg/pglite.js +9 -8
- package/dist/runtime/pg/postgresjs.js +5 -5
- package/dist/runtime/plan.d.ts +113 -15
- package/dist/runtime/predicate.d.ts +19 -0
- package/dist/runtime/read-stream.d.ts +13 -16
- package/dist/runtime/result-name.d.ts +17 -0
- package/dist/runtime/safety/index.js +1 -1
- package/dist/runtime/server-check.d.ts +3 -3
- package/dist/runtime/sort-bind.d.ts +21 -0
- package/dist/runtime/sort.d.ts +56 -0
- package/dist/runtime/sync.d.ts +70 -0
- package/dist/runtime/tenancy/composite.d.ts +26 -0
- package/dist/runtime/tenancy/context.d.ts +16 -0
- package/dist/runtime/tenancy/index.d.ts +9 -5
- package/dist/runtime/tenancy/index.js +1511 -38
- package/dist/runtime/tenancy/path.d.ts +87 -0
- package/dist/runtime/tenancy/rls.d.ts +67 -0
- package/dist/runtime/tenancy/via.d.ts +22 -0
- package/dist/runtime/text-search.d.ts +20 -0
- package/dist/runtime/traits/index.d.ts +80 -0
- package/dist/runtime/traits/index.js +187 -17
- package/dist/runtime/tree.d.ts +38 -0
- package/dist/runtime/types.d.ts +231 -23
- package/dist/runtime/validate/index.js +4 -4
- package/dist/runtime/version.d.ts +39 -0
- package/dist/runtime/window.d.ts +21 -0
- package/dist/runtime/write.d.ts +55 -3
- package/dist/shared/{krxx77g0.js → 14vx95q4.js} +12 -18
- package/dist/shared/1est4ezg.js +313 -0
- package/dist/shared/{4az561fn.js → 1qa0qajz.js} +8 -23
- package/dist/shared/1w508jbr.js +1611 -0
- package/dist/shared/2c13q96h.js +18 -0
- package/dist/shared/2d3xq4ps.js +9 -0
- package/dist/shared/2shdbn8q.js +23 -0
- package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
- package/dist/shared/3v7t1yrv.js +208 -0
- package/dist/shared/5e3tf63j.js +220 -0
- package/dist/shared/5fe3kbsh.js +10 -0
- package/dist/shared/5v3xf80k.js +37 -0
- package/dist/shared/{51mvgj8w.js → 63qtkrca.js} +130 -3
- package/dist/shared/{gbtcc2d7.js → 67txcrcw.js} +62 -66
- package/dist/shared/79dt02vc.js +12 -0
- package/dist/shared/{v36c5g6p.js → 7k9grvf6.js} +407 -14
- package/dist/shared/7kms6fvj.js +20 -0
- package/dist/shared/7mnme5tn.js +8 -0
- package/dist/shared/7n7ddwt4.js +6 -0
- package/dist/shared/{87jvvhnt.js → 81ebdx9p.js} +48 -68
- package/dist/shared/{szm0cksa.js → 8skf0cam.js} +34 -6
- package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
- package/dist/shared/9a4ae4p8.js +31 -0
- package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
- package/dist/shared/9y3mmmh1.js +436 -0
- package/dist/shared/ab9gmbwy.js +213 -0
- package/dist/shared/{sycnx8gt.js → ax7qv55k.js} +18 -8
- package/dist/shared/{f5cw5q5r.js → aytqh5y2.js} +6 -4
- package/dist/shared/{fancm5pt.js → b5pftnn2.js} +138 -15
- package/dist/shared/{efmy2gcg.js → b76b8d95.js} +2 -2
- package/dist/shared/bdk4sty6.js +58 -0
- package/dist/shared/{32zqc1dw.js → bg3rym3g.js} +63 -32
- package/dist/shared/{0t22wwh1.js → bm22fvzr.js} +16 -14
- package/dist/shared/bz84tkzm.js +342 -0
- package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
- package/dist/shared/cn957f8d.js +179 -0
- package/dist/shared/{pf0d8f77.js → cnkky55j.js} +25 -14
- package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
- package/dist/shared/{nkaxvt9q.js → dkxgzaqd.js} +224 -19
- package/dist/shared/dzj09cye.js +10 -0
- package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
- package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
- package/dist/shared/exn3sd90.js +359 -0
- package/dist/shared/g6evj1j3.js +66 -0
- package/dist/shared/ga9j92qj.js +25 -0
- package/dist/shared/{qv2ydck9.js → gs74dbj5.js} +651 -76
- package/dist/shared/gzaveazc.js +285 -0
- package/dist/shared/{8rsy3hxz.js → h15jx9bc.js} +1 -1
- package/dist/shared/{dyj86cmj.js → hyh73qk6.js} +3 -3
- package/dist/shared/je4axnm8.js +22 -0
- package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
- package/dist/shared/{6qd27mx0.js → jvd0mqag.js} +5 -5
- package/dist/shared/jznfax0y.js +155 -0
- package/dist/shared/{cgbamx3e.js → kb2sdhfb.js} +7 -4
- package/dist/shared/{ps7a6h14.js → kr0jzbw2.js} +12 -8
- package/dist/shared/{janx09m5.js → ktz42yez.js} +20 -8
- package/dist/shared/{gde73es6.js → m6p12kbr.js} +56 -55
- package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
- package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
- package/dist/shared/{nxdp2ze3.js → mtaszv5a.js} +144 -12
- package/dist/shared/n816peh1.js +45 -0
- package/dist/shared/nbw1z4yd.js +18 -0
- package/dist/shared/{cctw17hj.js → p6qc5gcp.js} +38 -34
- package/dist/shared/{6rk2gen5.js → pbp1ss85.js} +20 -17
- package/dist/shared/pt94kz7f.js +6 -0
- package/dist/shared/{wq9n6pwr.js → pz6rj8ay.js} +82 -9
- package/dist/shared/q5c6ngn3.js +13 -0
- package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
- package/dist/shared/{8ktwd3rh.js → r3j8s5y0.js} +1 -1
- package/dist/shared/rhs3xe4k.js +7 -0
- package/dist/shared/{ntneex2a.js → rpycarcr.js} +6 -6
- package/dist/shared/{sdc7r2ww.js → rs73fca9.js} +8 -8
- package/dist/shared/{tm5ab8we.js → sfz1ksn6.js} +7 -4
- package/dist/shared/{6mnp99hx.js → svncdeh5.js} +16 -12
- package/dist/shared/{hf22e0wt.js → tbrvgw6z.js} +62 -42
- package/dist/shared/te5as7z7.js +622 -0
- package/dist/shared/{ga3sfy93.js → tsvww22q.js} +535 -200
- package/dist/shared/{47x8x9ze.js → ttsqgp4p.js} +20 -13
- package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
- package/dist/shared/vb6qfyve.js +152 -0
- package/dist/shared/{r2sp8hrc.js → vczs8gd4.js} +22 -13
- package/dist/shared/{1g0drakv.js → vqrjpcqn.js} +145 -3
- package/dist/shared/{2pqx26h8.js → w72kgg4q.js} +31 -22
- package/dist/shared/{96qcj21c.js → w79hsckn.js} +16 -51
- package/dist/shared/wa07eas9.js +730 -0
- package/dist/shared/{k8v5v5wj.js → x933k9a3.js} +75 -34
- package/dist/shared/{cr74e96e.js → xhfsfkgk.js} +62 -28
- package/dist/shared/xjk7hnn5.js +272 -0
- package/dist/shared/{5enne4ma.js → xnxsed62.js} +66 -113
- package/dist/shared/xqve9598.js +53 -0
- package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
- package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
- package/dist/shared/y6njgyda.js +249 -0
- package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
- package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
- package/dist/shared/z7s6fpxv.js +62 -0
- package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
- package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
- package/dist/shared/zm0ptry0.js +40 -0
- package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
- package/dist/shared/zp9fmend.js +145 -0
- package/dist/shared/{y005b761.js → zy8r7qvz.js} +6 -2
- package/dist/tooling/cli.js +41 -15
- package/dist/tooling/migrate/apply.d.ts +14 -0
- package/dist/tooling/migrate/check.d.ts +3 -4
- package/dist/tooling/migrate/classify.d.ts +4 -0
- package/dist/tooling/migrate/config.d.ts +3 -2
- package/dist/tooling/migrate/engine.d.ts +3 -2
- package/dist/tooling/migrate/files.d.ts +11 -1
- package/dist/tooling/migrate/index.js +14 -14
- package/dist/tooling/migrate/lint.d.ts +1 -1
- package/dist/tooling/migrate/lost.d.ts +28 -0
- package/dist/tooling/migrate/paths.d.ts +14 -0
- package/dist/tooling/migrate/plan.d.ts +6 -3
- package/dist/tooling/migrate/runner.d.ts +25 -0
- package/dist/tooling/migrate/sandbox.d.ts +57 -0
- package/dist/tooling/migrate/sql-lex.d.ts +20 -3
- package/dist/tooling/migrate/text.d.ts +42 -0
- package/dist/tooling/node-version.d.ts +21 -0
- package/dist/tooling/testing/facts.d.ts +33 -5
- package/dist/tooling/testing/index.d.ts +1 -1
- package/dist/tooling/testing/index.js +3 -3
- package/dist/tooling/testing/isolation.d.ts +11 -5
- package/package.json +8 -3
- package/dist/shared/7m88x3e9.js +0 -45
- package/dist/shared/7zwwyh0v.js +0 -448
- package/dist/shared/aj2qxyhj.js +0 -90
- package/dist/shared/caw8b9d8.js +0 -204
- package/dist/shared/jwtxdj06.js +0 -76
- package/dist/shared/kfjp0gck.js +0 -212
- package/dist/shared/q58y17hy.js +0 -21
- package/dist/shared/qm7cdtvr.js +0 -912
- package/dist/shared/r8x5qhd7.js +0 -86
- package/dist/shared/zqrnhwsq.js +0 -31
|
@@ -9,6 +9,7 @@ function isConnectionErrno(code) {
|
|
|
9
9
|
case "EPIPE":
|
|
10
10
|
case "ENOTFOUND":
|
|
11
11
|
case "ETIMEDOUT":
|
|
12
|
+
case "CONNECT_TIMEOUT":
|
|
12
13
|
case "EHOSTUNREACH":
|
|
13
14
|
case "ENETUNREACH":
|
|
14
15
|
case "EAI_AGAIN":
|
|
@@ -21,28 +22,38 @@ function isConnectionErrno(code) {
|
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
function isConnectionFailure(error) {
|
|
24
|
-
|
|
25
|
-
if (sqlstate !== undefined && (isConnectionSqlstate(sqlstate) || isConnectionErrno(sqlstate))) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
if (!(error instanceof Error))
|
|
29
|
-
return false;
|
|
30
|
-
const message = error.message;
|
|
31
|
-
return message.includes("ECONNREFUSED") || message.includes("ECONNRESET") || message.includes("CONNECTION_CLOSED") || message.includes("terminating connection") || message.includes("The pool is closed");
|
|
25
|
+
return at(error, true);
|
|
32
26
|
}
|
|
33
27
|
function isConnectionLost(error) {
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
return at(error, false);
|
|
29
|
+
}
|
|
30
|
+
function at(error, failure) {
|
|
36
31
|
if (typeof error !== "object" || error === null)
|
|
37
32
|
return false;
|
|
38
|
-
|
|
33
|
+
const named = readCode(error, "sqlstate");
|
|
34
|
+
if (isState(named))
|
|
35
|
+
return lostState(named);
|
|
36
|
+
const code = readCode(error, "code");
|
|
37
|
+
const errno = readCode(error, "errno");
|
|
38
|
+
if (code !== undefined && (isConnectionErrno(code) || code === "ERR_POSTGRES_CONNECTION_CLOSED")) {
|
|
39
39
|
return true;
|
|
40
|
-
|
|
40
|
+
}
|
|
41
|
+
if (errno !== undefined && isConnectionErrno(errno))
|
|
41
42
|
return true;
|
|
42
|
-
if (
|
|
43
|
+
if (isState(code))
|
|
44
|
+
return lostState(code);
|
|
45
|
+
if (isState(errno))
|
|
46
|
+
return lostState(errno);
|
|
47
|
+
if (!failure && Reflect.get(error, "kind") === "outcome_unknown")
|
|
43
48
|
return true;
|
|
44
49
|
const cause = Reflect.get(error, "cause");
|
|
45
|
-
return cause !== undefined && cause !== error &&
|
|
50
|
+
return cause !== undefined && cause !== error && at(cause, failure);
|
|
51
|
+
}
|
|
52
|
+
function lostState(state) {
|
|
53
|
+
return isConnectionSqlstate(state) && state !== "53300";
|
|
54
|
+
}
|
|
55
|
+
function isState(value) {
|
|
56
|
+
return value !== undefined && /^[0-9A-Z]{5}$/.test(value);
|
|
46
57
|
}
|
|
47
58
|
function readCode(error, key) {
|
|
48
59
|
if (typeof error !== "object" || error === null || !(key in error))
|
|
@@ -7,9 +7,11 @@ import {
|
|
|
7
7
|
startupCatalog2,
|
|
8
8
|
startupHash2,
|
|
9
9
|
loadTrustedCatalog2,
|
|
10
|
+
catalogFileText2,
|
|
10
11
|
parseCatalog2
|
|
11
|
-
} from "./
|
|
12
|
+
} from "./qq3899ht.js";
|
|
12
13
|
export {
|
|
14
|
+
catalogFileText2 as catalogFileText,
|
|
13
15
|
catalogHash2 as catalogHash,
|
|
14
16
|
creationOrder2 as creationOrder,
|
|
15
17
|
loadTrustedCatalog2 as loadTrustedCatalog,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
+
orderHasRelevance,
|
|
2
3
|
emitRelationFrom,
|
|
4
|
+
needsOperatorSql,
|
|
3
5
|
decodeResult,
|
|
4
6
|
emitJoin,
|
|
5
7
|
emitWhere,
|
|
6
8
|
emitOrder,
|
|
7
9
|
emitPrimaryOrder,
|
|
10
|
+
refuseHidden,
|
|
8
11
|
selectedColumns,
|
|
9
12
|
rejectKeys,
|
|
10
13
|
readLimit,
|
|
@@ -16,8 +19,8 @@ import {
|
|
|
16
19
|
list,
|
|
17
20
|
isRecord,
|
|
18
21
|
registerFailFix,
|
|
19
|
-
|
|
20
|
-
} from "./
|
|
22
|
+
fail2
|
|
23
|
+
} from "./67txcrcw.js";
|
|
21
24
|
import {
|
|
22
25
|
throwNamed2
|
|
23
26
|
} from "./52szzakm.js";
|
|
@@ -26,6 +29,32 @@ import {
|
|
|
26
29
|
registerFailFix("OKM1105", "Pass limit on the include, or call .all(reason).");
|
|
27
30
|
var INCLUDE_OPTIONS = ["all", "include", "limit", "orderBy", "select", "where"];
|
|
28
31
|
function emitIncludeSelect(include, alias, sink, outputs, column) {
|
|
32
|
+
const morph = include.morphTo;
|
|
33
|
+
if (morph !== undefined) {
|
|
34
|
+
if (column > 0 || outputs?.fields.length)
|
|
35
|
+
sink.text(", ");
|
|
36
|
+
sink.text(alias);
|
|
37
|
+
sink.text(".payload");
|
|
38
|
+
outputs?.includes.push({
|
|
39
|
+
name: include.name,
|
|
40
|
+
kind: "one",
|
|
41
|
+
at: column,
|
|
42
|
+
fields: [],
|
|
43
|
+
nested: [],
|
|
44
|
+
morph: {
|
|
45
|
+
typeKey: morph.typeKey,
|
|
46
|
+
targets: morph.targets.map((target) => ({
|
|
47
|
+
type: target.type,
|
|
48
|
+
fields: target.columns.map((item, at) => ({
|
|
49
|
+
key: item.field,
|
|
50
|
+
at,
|
|
51
|
+
decode: item.decode
|
|
52
|
+
}))
|
|
53
|
+
}))
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return column + 1;
|
|
57
|
+
}
|
|
29
58
|
const selected = include.columns;
|
|
30
59
|
sink.mark(`i:${include.name}:${include.relation.kind}`);
|
|
31
60
|
if (include.relation.kind === "many") {
|
|
@@ -109,9 +138,13 @@ function emitIncludeSelect(include, alias, sink, outputs, column) {
|
|
|
109
138
|
return cursor;
|
|
110
139
|
}
|
|
111
140
|
function emitIncludeJoin(schema, include, sink, parentAlias, alias, depth) {
|
|
141
|
+
if (include.morphTo !== undefined) {
|
|
142
|
+
emitMorphJoin(schema, include, sink, parentAlias, alias, depth);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
112
145
|
const child = indexes(schema).get(include.relation.table);
|
|
113
146
|
if (child === undefined) {
|
|
114
|
-
|
|
147
|
+
fail2("OKM1120", `Relation ${include.name} names ${include.relation.table}, which is not in the schema.`);
|
|
115
148
|
}
|
|
116
149
|
const childAlias = `r${String(depth)}_${include.name}`;
|
|
117
150
|
sink.text(" left join lateral (");
|
|
@@ -135,10 +168,7 @@ function emitIncludeJoin(schema, include, sink, parentAlias, alias, depth) {
|
|
|
135
168
|
sink.text(") as item from ");
|
|
136
169
|
emitRelationFrom(schema, include.relation, child, sink, parentAlias, childAlias, depth + 1);
|
|
137
170
|
emitWhere(schema, child, include.where, sink, childAlias, depth + 1, true);
|
|
138
|
-
|
|
139
|
-
if (include.orderBy === undefined && child.model.primary.length > 0) {
|
|
140
|
-
emitPrimaryOrder(child, sink, childAlias);
|
|
141
|
-
}
|
|
171
|
+
emitIncludeOrder(child, include.orderBy, sink, childAlias);
|
|
142
172
|
if (include.limit !== undefined) {
|
|
143
173
|
sink.text(" limit ");
|
|
144
174
|
sink.param(String(include.limit));
|
|
@@ -207,9 +237,12 @@ function emitIncludeJoin(schema, include, sink, parentAlias, alias, depth) {
|
|
|
207
237
|
sink.text(" on true");
|
|
208
238
|
}
|
|
209
239
|
function emitNestedAggregate(schema, include, sink, alias, depth) {
|
|
240
|
+
if (include.relation.morph?.direction === "to") {
|
|
241
|
+
fail2("OKM1120", `Include ${include.name} is a morph and cannot be nested in this version.`);
|
|
242
|
+
}
|
|
210
243
|
const child = indexes(schema).get(include.relation.table);
|
|
211
244
|
if (child === undefined) {
|
|
212
|
-
|
|
245
|
+
fail2("OKM1120", `Relation ${include.name} names ${include.relation.table}, which is not in the schema.`);
|
|
213
246
|
}
|
|
214
247
|
const childAlias = `n${String(depth)}_${include.name}`;
|
|
215
248
|
sink.text("(select coalesce(json_agg(item order by ord), '[]'::json) from (select item, row_number() over () as ord from (select json_build_array(");
|
|
@@ -226,10 +259,7 @@ function emitNestedAggregate(schema, include, sink, alias, depth) {
|
|
|
226
259
|
sink.text(") as item from ");
|
|
227
260
|
emitRelationFrom(schema, include.relation, child, sink, alias, childAlias, depth);
|
|
228
261
|
emitWhere(schema, child, include.where, sink, childAlias, depth, true);
|
|
229
|
-
|
|
230
|
-
if (include.orderBy === undefined && child.model.primary.length > 0) {
|
|
231
|
-
emitPrimaryOrder(child, sink, childAlias);
|
|
232
|
-
}
|
|
262
|
+
emitIncludeOrder(child, include.orderBy, sink, childAlias);
|
|
233
263
|
if (include.limit !== undefined) {
|
|
234
264
|
sink.text(" limit ");
|
|
235
265
|
sink.param(String(include.limit));
|
|
@@ -237,6 +267,14 @@ function emitNestedAggregate(schema, include, sink, alias, depth) {
|
|
|
237
267
|
}
|
|
238
268
|
sink.text(") limited) ordered)");
|
|
239
269
|
}
|
|
270
|
+
function includeColumns(table, select) {
|
|
271
|
+
const columns = selectedColumns(table, select);
|
|
272
|
+
if (select === undefined)
|
|
273
|
+
return omitHidden(columns);
|
|
274
|
+
for (const column of columns)
|
|
275
|
+
refuseHidden(column);
|
|
276
|
+
return columns;
|
|
277
|
+
}
|
|
240
278
|
function omitHidden(columns) {
|
|
241
279
|
for (const column of columns) {
|
|
242
280
|
if (!column.hidden)
|
|
@@ -249,7 +287,7 @@ function readIncludes(schema, table, include, all) {
|
|
|
249
287
|
if (include === undefined)
|
|
250
288
|
return [];
|
|
251
289
|
if (!isRecord(include)) {
|
|
252
|
-
|
|
290
|
+
fail2("OKM1120", "include must be an object of relations.");
|
|
253
291
|
}
|
|
254
292
|
const parsed = [];
|
|
255
293
|
for (const name of Object.keys(include)) {
|
|
@@ -262,9 +300,11 @@ function readIncludes(schema, table, include, all) {
|
|
|
262
300
|
return parsed;
|
|
263
301
|
}
|
|
264
302
|
function parseInclude(schema, name, relation, value, all) {
|
|
303
|
+
if (relation.morph?.direction === "to")
|
|
304
|
+
return parseMorph(schema, name, relation, value);
|
|
265
305
|
if (value === true) {
|
|
266
306
|
if (relation.kind === "many" && all === undefined) {
|
|
267
|
-
|
|
307
|
+
fail2("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
|
|
268
308
|
}
|
|
269
309
|
const child = childIndex(schema, relation);
|
|
270
310
|
const columns = omitHidden(selectedColumns(child, undefined));
|
|
@@ -280,7 +320,7 @@ function parseInclude(schema, name, relation, value, all) {
|
|
|
280
320
|
};
|
|
281
321
|
}
|
|
282
322
|
if (!isRecord(value)) {
|
|
283
|
-
|
|
323
|
+
fail2("OKM1120", `Include ${name} must be true or an object.`);
|
|
284
324
|
}
|
|
285
325
|
rejectKeys(value, INCLUDE_OPTIONS, `include ${name}`);
|
|
286
326
|
const reason = typeof value.all === "string" ? value.all : all;
|
|
@@ -288,10 +328,10 @@ function parseInclude(schema, name, relation, value, all) {
|
|
|
288
328
|
if (value.limit !== undefined)
|
|
289
329
|
limit = readLimit(value.limit);
|
|
290
330
|
if (relation.kind === "many" && limit === undefined && reason === undefined) {
|
|
291
|
-
|
|
331
|
+
fail2("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
|
|
292
332
|
}
|
|
293
333
|
const child = childIndex(schema, relation);
|
|
294
|
-
const columns =
|
|
334
|
+
const columns = includeColumns(child, value.select);
|
|
295
335
|
const nestedValue = value.include;
|
|
296
336
|
const nested = nestedValue === undefined ? [] : readIncludes(schema, child, nestedValue, reason);
|
|
297
337
|
return {
|
|
@@ -317,10 +357,125 @@ function anchored(table, columns) {
|
|
|
317
357
|
function childIndex(schema, relation) {
|
|
318
358
|
const child = indexes(schema).get(relation.table);
|
|
319
359
|
if (child === undefined) {
|
|
320
|
-
|
|
360
|
+
fail2("OKM1120", `Relation ${relation.name} names ${relation.table}, which is not in the schema.`);
|
|
321
361
|
}
|
|
322
362
|
return child;
|
|
323
363
|
}
|
|
364
|
+
function parseMorph(schema, name, relation, value) {
|
|
365
|
+
if (value !== true) {
|
|
366
|
+
fail2("OKM1120", `Include ${name} is a morph. Pass true. select, where, orderBy, and limit are not available on it.`);
|
|
367
|
+
}
|
|
368
|
+
const morph = relation.morph;
|
|
369
|
+
if (morph === undefined)
|
|
370
|
+
fail2("OKM1120", `Include ${name} is not a morph.`);
|
|
371
|
+
const planned = [];
|
|
372
|
+
for (const target of morph.targets) {
|
|
373
|
+
const child = indexes(schema).get(target.table);
|
|
374
|
+
if (child === undefined) {
|
|
375
|
+
fail2("OKM1120", `Relation ${name} names ${target.table}, which is not in the schema.`);
|
|
376
|
+
}
|
|
377
|
+
planned.push({
|
|
378
|
+
type: target.type,
|
|
379
|
+
table: target.table,
|
|
380
|
+
sql: target.sql,
|
|
381
|
+
keySql: target.keySql,
|
|
382
|
+
columns: omitHidden(selectedColumns(child, undefined))
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
name,
|
|
387
|
+
relation,
|
|
388
|
+
where: undefined,
|
|
389
|
+
orderBy: undefined,
|
|
390
|
+
limit: undefined,
|
|
391
|
+
columns: [],
|
|
392
|
+
presence: undefined,
|
|
393
|
+
anchor: 0,
|
|
394
|
+
nested: [],
|
|
395
|
+
morphTo: {
|
|
396
|
+
typeKey: morph.typeField,
|
|
397
|
+
typeSql: morph.typeSql,
|
|
398
|
+
idSql: morph.idSql,
|
|
399
|
+
targets: planned
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
function emitMorphJoin(schema, include, sink, parentAlias, alias, depth) {
|
|
404
|
+
const morph = include.morphTo;
|
|
405
|
+
if (morph === undefined)
|
|
406
|
+
fail2("OKM1120", `Include ${include.name} is not a morph.`);
|
|
407
|
+
sink.text(" left join lateral (select payload from (");
|
|
408
|
+
for (let index = 0;index < morph.targets.length; index += 1) {
|
|
409
|
+
const target = morph.targets[index];
|
|
410
|
+
if (target === undefined)
|
|
411
|
+
continue;
|
|
412
|
+
if (index > 0)
|
|
413
|
+
sink.text(" union all ");
|
|
414
|
+
const childAlias = `m${String(depth)}_${include.name}_${String(index)}`;
|
|
415
|
+
const child = indexes(schema).get(target.table);
|
|
416
|
+
if (child === undefined) {
|
|
417
|
+
fail2("OKM1120", `Relation ${include.name} names ${target.table}, which is not in the schema.`);
|
|
418
|
+
}
|
|
419
|
+
sink.text("select json_build_array(");
|
|
420
|
+
sink.param(target.type);
|
|
421
|
+
sink.text("::text");
|
|
422
|
+
sink.mark(`mt:${target.type}`);
|
|
423
|
+
for (const column of target.columns) {
|
|
424
|
+
sink.text(", ");
|
|
425
|
+
sink.text(jsonExpr(`${childAlias}.${quote(column.sql)}`, column.dataType));
|
|
426
|
+
}
|
|
427
|
+
sink.text(") as payload from ");
|
|
428
|
+
sink.text(quote(target.sql));
|
|
429
|
+
sink.text(" ");
|
|
430
|
+
sink.text(childAlias);
|
|
431
|
+
sink.text(" where ");
|
|
432
|
+
sink.text(parentAlias);
|
|
433
|
+
sink.text(".");
|
|
434
|
+
sink.text(quote(morph.typeSql));
|
|
435
|
+
sink.text(" = ");
|
|
436
|
+
sink.param(target.type);
|
|
437
|
+
sink.text("::text");
|
|
438
|
+
sink.text(" and ");
|
|
439
|
+
sink.text(childAlias);
|
|
440
|
+
sink.text(".");
|
|
441
|
+
sink.text(quote(target.keySql));
|
|
442
|
+
sink.text(" = ");
|
|
443
|
+
sink.text(parentAlias);
|
|
444
|
+
sink.text(".");
|
|
445
|
+
sink.text(quote(morph.idSql));
|
|
446
|
+
emitWhere(schema, child, undefined, sink, childAlias, depth + 1, true);
|
|
447
|
+
}
|
|
448
|
+
sink.text(") matched limit 1) ");
|
|
449
|
+
sink.text(alias);
|
|
450
|
+
sink.text(" on true");
|
|
451
|
+
}
|
|
452
|
+
function decodeMorph(include, row) {
|
|
453
|
+
const morph = include.morph;
|
|
454
|
+
if (morph === undefined)
|
|
455
|
+
return null;
|
|
456
|
+
const raw = row[include.at];
|
|
457
|
+
if (raw === null || raw === undefined)
|
|
458
|
+
return null;
|
|
459
|
+
const parsed = JSON.parse(raw);
|
|
460
|
+
if (!Array.isArray(parsed))
|
|
461
|
+
return null;
|
|
462
|
+
const type = parsed[0];
|
|
463
|
+
if (typeof type !== "string")
|
|
464
|
+
return null;
|
|
465
|
+
let target;
|
|
466
|
+
for (const item of morph.targets) {
|
|
467
|
+
if (item.type === type)
|
|
468
|
+
target = item;
|
|
469
|
+
}
|
|
470
|
+
if (target === undefined)
|
|
471
|
+
return null;
|
|
472
|
+
const child = {};
|
|
473
|
+
for (const field of target.fields) {
|
|
474
|
+
child[field.key] = jsonCell(parsed[field.at + 1], field.decode);
|
|
475
|
+
}
|
|
476
|
+
child[morph.typeKey] = type;
|
|
477
|
+
return child;
|
|
478
|
+
}
|
|
324
479
|
function decodeIncluded(plan, rows, table) {
|
|
325
480
|
return decodeResult(plan, rows, table, decodeRowIncluded);
|
|
326
481
|
}
|
|
@@ -335,6 +490,8 @@ function decodeRowIncluded(outputs, row) {
|
|
|
335
490
|
return result;
|
|
336
491
|
}
|
|
337
492
|
function decodeInclude(include, row) {
|
|
493
|
+
if (include.morph !== undefined)
|
|
494
|
+
return decodeMorph(include, row);
|
|
338
495
|
if (include.kind === "many") {
|
|
339
496
|
const raw = row[include.at];
|
|
340
497
|
if (raw === null || raw === undefined)
|
|
@@ -390,10 +547,58 @@ function jsonCell(value, decode) {
|
|
|
390
547
|
const wire = typeof value === "string" ? value : JSON.stringify(value);
|
|
391
548
|
return decode === undefined ? wire : decode(wire);
|
|
392
549
|
}
|
|
550
|
+
function emitIncludeOrder(child, orderBy, sink, alias) {
|
|
551
|
+
emitOrder(child, orderBy, sink, alias);
|
|
552
|
+
const named = isRecord(orderBy) ? Object.keys(orderBy) : [];
|
|
553
|
+
if (named.length === 0) {
|
|
554
|
+
if (child.model.primary.length > 0)
|
|
555
|
+
emitPrimaryOrder(child, sink, alias);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
for (const field of child.model.primary) {
|
|
559
|
+
if (named.includes(field))
|
|
560
|
+
continue;
|
|
561
|
+
const column = child.columns.get(field);
|
|
562
|
+
if (column === undefined)
|
|
563
|
+
continue;
|
|
564
|
+
sink.text(", ");
|
|
565
|
+
sink.text(alias);
|
|
566
|
+
sink.text(".");
|
|
567
|
+
sink.text(quote(column.sql));
|
|
568
|
+
sink.text(" asc");
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
function needsOperator(schema, call) {
|
|
572
|
+
const table = indexes(schema).get(call.table);
|
|
573
|
+
if (table === undefined)
|
|
574
|
+
return false;
|
|
575
|
+
return walkOperators(schema, table, call.include);
|
|
576
|
+
}
|
|
577
|
+
function walkOperators(schema, table, include) {
|
|
578
|
+
if (!isRecord(include))
|
|
579
|
+
return false;
|
|
580
|
+
for (const name of Object.keys(include)) {
|
|
581
|
+
const value = include[name];
|
|
582
|
+
if (!isRecord(value))
|
|
583
|
+
continue;
|
|
584
|
+
const relation = table.relations.get(name);
|
|
585
|
+
if (relation === undefined)
|
|
586
|
+
continue;
|
|
587
|
+
const child = indexes(schema).get(relation.table);
|
|
588
|
+
if (child === undefined)
|
|
589
|
+
continue;
|
|
590
|
+
if (needsOperatorSql(child, value.where) || orderHasRelevance(value.orderBy))
|
|
591
|
+
return true;
|
|
592
|
+
if (walkOperators(schema, child, value.include))
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
393
597
|
var includeHooks = {
|
|
394
598
|
read: readIncludes,
|
|
395
599
|
select: emitIncludeSelect,
|
|
396
|
-
join: emitIncludeJoin
|
|
600
|
+
join: emitIncludeJoin,
|
|
601
|
+
needsOperator
|
|
397
602
|
};
|
|
398
603
|
export {
|
|
399
604
|
decodeIncluded,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
catalogFileText2
|
|
3
|
+
} from "./qq3899ht.js";
|
|
1
4
|
import {
|
|
2
5
|
OkmError2
|
|
3
6
|
} from "./52szzakm.js";
|
|
@@ -11,7 +14,7 @@ async function assertCompatible(pool, schema, recordedHash, source, options) {
|
|
|
11
14
|
if (code.artifact !== undefined) {
|
|
12
15
|
const artifact = code.artifact;
|
|
13
16
|
await loadOnce(`text\x00${artifact.hash}`, async () => {
|
|
14
|
-
const { loadTrustedCatalog } = await import("./
|
|
17
|
+
const { loadTrustedCatalog } = await import("./dk8v79p3.js");
|
|
15
18
|
loadTrustedCatalog(artifact.text, artifact.hash);
|
|
16
19
|
});
|
|
17
20
|
} else if (code.fromFile) {
|
|
@@ -25,7 +28,7 @@ async function assertCompatible(pool, schema, recordedHash, source, options) {
|
|
|
25
28
|
}
|
|
26
29
|
});
|
|
27
30
|
}
|
|
28
|
-
const { loadTrustedCatalog } = await import("./
|
|
31
|
+
const { loadTrustedCatalog } = await import("./dk8v79p3.js");
|
|
29
32
|
loadTrustedCatalog(text, code.hash);
|
|
30
33
|
});
|
|
31
34
|
}
|
|
@@ -39,7 +42,7 @@ async function codeHash(schema, source) {
|
|
|
39
42
|
const listed = await readHashFile(source.catalogDir);
|
|
40
43
|
if (listed !== undefined)
|
|
41
44
|
return { hash: listed, fromFile: true };
|
|
42
|
-
const { catalogHash } = await import("./
|
|
45
|
+
const { catalogHash } = await import("./dk8v79p3.js");
|
|
43
46
|
return { hash: catalogHash(schemaCatalog(schema)), fromFile: false };
|
|
44
47
|
}
|
|
45
48
|
function schemaCatalog(schema) {
|
|
@@ -57,12 +60,12 @@ async function readHashFile(catalogDir) {
|
|
|
57
60
|
const text = await readText(`${artifactDir(catalogDir)}/catalog.hash`);
|
|
58
61
|
if (text === undefined)
|
|
59
62
|
return;
|
|
60
|
-
const hash = text.trim();
|
|
63
|
+
const hash = catalogFileText2(text, "catalog.hash").trim();
|
|
61
64
|
return hash.length === 0 ? undefined : hash;
|
|
62
65
|
}
|
|
63
66
|
function artifactDir(catalogDir) {
|
|
64
67
|
if (catalogDir !== undefined)
|
|
65
|
-
return catalogDir.replace(
|
|
68
|
+
return catalogDir.replace(/[/\\]+$/, "");
|
|
66
69
|
const cwd = globalThis.process?.cwd?.() ?? ".";
|
|
67
70
|
return `${cwd}/.okm`;
|
|
68
71
|
}
|