okmodel 0.6.0 → 0.8.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 -1131
- package/dist/adapters/capabilities.d.ts +35 -0
- package/dist/adapters/failure.d.ts +13 -2
- package/dist/adapters/lazy-errors.d.ts +22 -0
- package/dist/adapters/pg/bun-sql.d.ts +53 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
- package/dist/adapters/pg/bunsql.d.ts +15 -2
- package/dist/adapters/pg/cursor.d.ts +17 -0
- 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 +11 -8
- 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 +27 -11
- package/dist/adapters/pg/reserved.d.ts +42 -0
- package/dist/adapters/pg/session.d.ts +0 -18
- package/dist/contracts/connection.d.ts +7 -6
- package/dist/contracts/error.d.ts +1 -1
- package/dist/dialects/pg/floor.d.ts +68 -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 +8 -1
- package/dist/dialects/pg/index.js +435 -170
- package/dist/dialects/pg/introspect.d.ts +11 -0
- package/dist/dialects/pg/keys.d.ts +11 -8
- package/dist/dialects/pg/model.d.ts +40 -0
- 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/fragment.d.ts +119 -0
- package/dist/dialects/pg/ops/inc.d.ts +2 -2
- package/dist/dialects/pg/ops/lane.d.ts +49 -0
- 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/preset.d.ts +1 -1
- package/dist/dialects/pg/relations.d.ts +100 -3
- package/dist/dialects/pg/schema.d.ts +31 -3
- 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 +8 -5
- package/dist/runtime/aggregate.d.ts +8 -2
- package/dist/runtime/bucket-group.d.ts +70 -0
- package/dist/runtime/conflict.d.ts +22 -4
- package/dist/runtime/include.d.ts +0 -8
- package/dist/runtime/inflight.d.ts +1 -1
- package/dist/runtime/otel.d.ts +105 -0
- package/dist/runtime/otel.js +97 -0
- package/dist/runtime/page.d.ts +4 -1
- package/dist/runtime/pg/bun.js +12 -6
- package/dist/runtime/pg/neon.d.ts +38 -0
- package/dist/runtime/pg/neon.js +64 -0
- package/dist/runtime/pg/pg.js +5 -5
- package/dist/runtime/pg/pglite.d.ts +1 -0
- package/dist/runtime/pg/pglite.js +9 -9
- package/dist/runtime/pg/postgresjs.js +5 -5
- package/dist/runtime/plan.d.ts +95 -5
- package/dist/runtime/read-stream.d.ts +13 -16
- package/dist/runtime/result-name.d.ts +17 -0
- 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/sql-fragment.d.ts +43 -0
- package/dist/runtime/sync.d.ts +70 -0
- package/dist/runtime/tenancy/index.js +15 -13
- package/dist/runtime/text-search.d.ts +20 -0
- package/dist/runtime/topology.d.ts +1 -1
- package/dist/runtime/traits/index.d.ts +80 -0
- package/dist/runtime/traits/index.js +184 -21
- package/dist/runtime/tree.d.ts +38 -0
- package/dist/runtime/types.d.ts +232 -22
- 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 +54 -2
- package/dist/shared/{929h19xp.js → 0wrea3jq.js} +141 -13
- package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
- package/dist/shared/{1z04fa85.js → 14x60fbf.js} +12 -57
- package/dist/shared/{ek2wt2dz.js → 16kvjebh.js} +4 -4
- package/dist/shared/{wynzeggs.js → 195pzzzz.js} +8 -8
- package/dist/shared/1d9q9cv2.js +312 -0
- package/dist/shared/2c13q96h.js +18 -0
- package/dist/shared/{b4v57v3x.js → 2d3xq4ps.js} +2 -2
- package/dist/shared/{1f0xa3cb.js → 3449rcae.js} +5 -5
- package/dist/shared/{wkme6tep.js → 35q0n9tz.js} +8 -16
- package/dist/shared/3bb7wsqt.js +99 -0
- package/dist/shared/3t6kw83m.js +249 -0
- package/dist/shared/{5j36z8dn.js → 4m6hskg8.js} +39 -70
- package/dist/shared/{n076ydsc.js → 4vbf83xx.js} +69 -28
- package/dist/shared/{vmfkhszw.js → 63f4ksbz.js} +33 -26
- package/dist/shared/{c58secgj.js → 63qtkrca.js} +38 -4
- package/dist/shared/6m78c8ss.js +6 -0
- package/dist/shared/{x3jc53kg.js → 760ppr76.js} +15 -7
- package/dist/shared/7ghwamrf.js +40 -0
- package/dist/shared/7kms6fvj.js +20 -0
- package/dist/shared/7n7ddwt4.js +6 -0
- package/dist/shared/9a4ae4p8.js +31 -0
- package/dist/shared/{hazqqecq.js → 9dr2qnx7.js} +63 -34
- package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
- package/dist/shared/a62rb2da.js +13 -0
- package/dist/shared/{cgbamx3e.js → ae4j5f42.js} +23 -4
- package/dist/shared/agsfb86s.js +233 -0
- package/dist/shared/{8x72s86k.js → b6d6p0zc.js} +13 -7
- package/dist/shared/{ag4c7516.js → b76b8d95.js} +2 -2
- package/dist/shared/{j60w0dvr.js → bah9nbg3.js} +58 -38
- package/dist/shared/bnby0esn.js +10 -0
- package/dist/shared/bsek72fg.js +225 -0
- package/dist/shared/{2cg3wnxc.js → bxas03mq.js} +608 -141
- package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
- package/dist/shared/{gwn6v667.js → cnkky55j.js} +25 -14
- package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
- package/dist/shared/{ttmg09vd.js → dpc2r7rb.js} +8 -8
- package/dist/shared/dzj09cye.js +10 -0
- package/dist/shared/{sbdme3vy.js → e8zyaqvj.js} +60 -10
- package/dist/shared/{2jd1sn0e.js → ecn8mfdq.js} +6 -6
- package/dist/shared/exn3sd90.js +359 -0
- package/dist/shared/{t3g0k88x.js → f4jy1j7x.js} +39 -22
- package/dist/shared/{y2t3jktd.js → fjpnhqan.js} +20 -13
- package/dist/shared/g5yc06ka.js +272 -0
- package/dist/shared/ga9j92qj.js +25 -0
- package/dist/shared/{3fqwmr09.js → hfqmpasr.js} +6 -6
- package/dist/shared/{wt5rzv1h.js → hm5f8jby.js} +7 -7
- package/dist/shared/{ys0xzyaj.js → hqpxf4a4.js} +224 -19
- package/dist/shared/jebgrkeq.js +179 -0
- package/dist/shared/{09p049xa.js → jp36k7dp.js} +44 -16
- package/dist/shared/jx2m62cs.js +96 -0
- package/dist/shared/{r11n8grd.js → k86n8vq3.js} +7 -4
- package/dist/shared/{2z7wv5tj.js → kgwp4jdd.js} +56 -35
- package/dist/shared/{knmes2kh.js → kj9d8maq.js} +1 -1
- package/dist/shared/{g90m9b0g.js → m4xff2a6.js} +6 -5
- package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
- package/dist/shared/mfedzr74.js +145 -0
- package/dist/shared/{f0f1n281.js → mkrn359n.js} +60 -11
- package/dist/shared/{p248q79y.js → mnvjvqyp.js} +10 -10
- package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
- package/dist/shared/{4az561fn.js → mtw6jz76.js} +8 -23
- package/dist/shared/n05z9nwz.js +313 -0
- package/dist/shared/{pjr6xrm5.js → n0jmpgj1.js} +20 -17
- package/dist/shared/{p6bjzq9q.js → n41w4fbz.js} +14 -6
- package/dist/shared/{b3awxn7h.js → n454kcnw.js} +1 -1
- package/dist/shared/n7kg8mmx.js +61 -0
- package/dist/shared/nbw1z4yd.js +18 -0
- package/dist/shared/needfe47.js +66 -0
- package/dist/shared/{1nw1f3vs.js → njga14v4.js} +9 -9
- package/dist/shared/{5yv4k6a6.js → nmnsgj7x.js} +145 -3
- package/dist/shared/{vjpnzwjz.js → p3xbdcvt.js} +14 -18
- package/dist/shared/p5nh3r8q.js +622 -0
- package/dist/shared/{nx9hh281.js → pan0370z.js} +13 -12
- package/dist/shared/q0cqt2sp.js +12 -0
- package/dist/shared/qd9hhd8f.js +37 -0
- package/dist/shared/{mb2ycs1p.js → qfw14tna.js} +15 -15
- package/dist/shared/{9s0ypp87.js → sjk86yrx.js} +1 -1
- package/dist/shared/th3be82n.js +208 -0
- package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
- package/dist/shared/{5d8t84hg.js → v1wad97q.js} +14 -14
- package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
- package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
- package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
- package/dist/shared/{q3j1tq7a.js → wcrheftc.js} +148 -23
- package/dist/shared/wvdjznah.js +213 -0
- package/dist/shared/wz2a78mp.js +8 -0
- package/dist/shared/xfhe73sb.js +436 -0
- package/dist/shared/{r1fdd0f6.js → z581d7ny.js} +5 -2
- package/dist/shared/{8etn7d8w.js → z7s6fpxv.js} +1 -1
- package/dist/shared/{32cnm7kn.js → zbqbmmrp.js} +76 -40
- package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
- package/dist/shared/{xq0mvhts.js → zgex00fd.js} +6 -6
- package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
- package/dist/shared/zq1he88x.js +155 -0
- package/dist/tooling/cli.js +26 -13
- package/dist/tooling/driver-run.js +4971 -0
- package/dist/tooling/driver-test.d.ts +36 -0
- package/dist/tooling/migrate/commands.d.ts +2 -2
- package/dist/tooling/migrate/engine.d.ts +3 -2
- package/dist/tooling/migrate/index.js +9 -9
- package/dist/tooling/migrate/project.d.ts +3 -0
- package/dist/tooling/shared/03k6res6.js +210 -0
- package/dist/tooling/shared/08kemxjd.js +10 -0
- package/dist/tooling/shared/2revefqt.js +209 -0
- package/dist/tooling/shared/2wtvc7rw.js +1425 -0
- package/dist/tooling/shared/345tbc2k.js +16 -0
- package/dist/tooling/shared/3m1hkg7z.js +344 -0
- package/dist/tooling/shared/3rrw5w8f.js +81 -0
- package/dist/tooling/shared/3tq8pnb8.js +131 -0
- package/dist/tooling/shared/417zdsk7.js +194 -0
- package/dist/tooling/shared/4d2w25vw.js +40 -0
- package/dist/tooling/shared/54tqkxja.js +51 -0
- package/dist/tooling/shared/5bvw2nev.js +12 -0
- package/dist/tooling/shared/6nyfyw70.js +231 -0
- package/dist/tooling/shared/72fyg4zv.js +160 -0
- package/dist/tooling/shared/733a1tq3.js +38 -0
- package/dist/tooling/shared/7ae7rjmn.js +20 -0
- package/dist/tooling/shared/7kms6fvj.js +20 -0
- package/dist/tooling/shared/8sqrsw3s.js +49 -0
- package/dist/tooling/shared/96ps4g1z.js +32 -0
- package/dist/tooling/shared/9kazs5p6.js +195 -0
- package/dist/tooling/shared/9xzm7hjg.js +38 -0
- package/dist/tooling/shared/a6pp9d12.js +49 -0
- package/dist/tooling/shared/a7q7t4n3.js +22 -0
- package/dist/tooling/shared/aftb2mwr.js +18 -0
- package/dist/tooling/shared/bz2dqhab.js +311 -0
- package/dist/tooling/shared/cmptmb4f.js +12 -0
- package/dist/tooling/shared/ddjtfgnx.js +177 -0
- package/dist/tooling/shared/djydjpqt.js +261 -0
- package/dist/tooling/shared/dw08f3m8.js +9 -0
- package/dist/tooling/shared/dy672fz6.js +16 -0
- package/dist/tooling/shared/dzx85q70.js +66 -0
- package/dist/tooling/shared/ec71zqgt.js +270 -0
- package/dist/{shared/d5azex6s.js → tooling/shared/ep8zh3bk.js} +1 -1
- package/dist/tooling/shared/f9mphxej.js +3789 -0
- package/dist/tooling/shared/fb9k2qwd.js +89 -0
- package/dist/tooling/shared/g9ad4n80.js +211 -0
- package/dist/tooling/shared/gfvtj6d0.js +94 -0
- package/dist/tooling/shared/gmcf9cxf.js +294 -0
- package/dist/tooling/shared/htnaj77v.js +17 -0
- package/dist/tooling/shared/j9t5s12a.js +7 -0
- package/dist/tooling/shared/jne7b93p.js +42 -0
- package/dist/tooling/shared/ma2340rx.js +118 -0
- package/dist/tooling/shared/mtrqn2hn.js +505 -0
- package/dist/tooling/shared/n4jqhpqz.js +27 -0
- package/dist/tooling/shared/nf7jmhfa.js +20 -0
- package/dist/tooling/shared/p7f08ktn.js +332 -0
- package/dist/tooling/shared/ppnnnvj8.js +13 -0
- package/dist/tooling/shared/pqy21k24.js +312 -0
- package/dist/tooling/shared/pw8fgahx.js +69 -0
- package/dist/tooling/shared/pwsytxm5.js +17 -0
- package/dist/tooling/shared/rf83gr2d.js +94 -0
- package/dist/tooling/shared/rq5kk8j6.js +401 -0
- package/dist/tooling/shared/rs1jb051.js +12 -0
- package/dist/tooling/shared/smn6kz1p.js +157 -0
- package/dist/tooling/shared/spk1jg3r.js +1696 -0
- package/dist/tooling/shared/tn8gay14.js +143 -0
- package/dist/tooling/shared/vraj6d74.js +42 -0
- package/dist/tooling/shared/vs0t6qt8.js +64 -0
- package/dist/tooling/shared/vx86qjv8.js +150 -0
- package/dist/tooling/shared/w7qe8sj1.js +140 -0
- package/dist/tooling/shared/wt7j7nf6.js +15 -0
- package/dist/tooling/shared/wwnekq5n.js +6 -0
- package/dist/tooling/shared/xhrnjch9.js +185 -0
- package/dist/tooling/shared/xjs6zqtc.js +190 -0
- package/dist/tooling/shared/y031jct9.js +16 -0
- package/dist/tooling/shared/y5656f0e.js +233 -0
- package/dist/tooling/shared/yfr8hzhm.js +604 -0
- package/dist/tooling/shared/yk9mp7vb.js +250 -0
- package/dist/tooling/shared/yw30vnq2.js +139 -0
- package/dist/tooling/shared/z8d7ptht.js +618 -0
- package/dist/tooling/shared/zhwnfyb2.js +9 -0
- package/dist/tooling/shared/zvnhh1n0.js +198 -0
- package/dist/tooling/testing/index.js +3 -3
- package/package.json +17 -3
- package/dist/shared/3qnhc7w5.js +0 -38
- package/dist/shared/7m88x3e9.js +0 -45
- package/dist/shared/8dqhth8c.js +0 -12
- package/dist/shared/j3rkk835.js +0 -99
- package/dist/shared/k68eedmy.js +0 -85
- package/dist/shared/venqrjna.js +0 -216
- package/dist/shared/wxr8cwns.js +0 -6
- package/dist/shared/y34a8714.js +0 -150
- package/dist/shared/zm0mafk4.js +0 -92
- 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
|
@@ -96,22 +96,21 @@ function messageOf(error) {
|
|
|
96
96
|
}
|
|
97
97
|
function driverFields(input) {
|
|
98
98
|
const fields = {};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
fields.kind = input.kind;
|
|
99
|
+
const keys = [
|
|
100
|
+
"sqlstate",
|
|
101
|
+
"constraint",
|
|
102
|
+
"table",
|
|
103
|
+
"column",
|
|
104
|
+
"detail",
|
|
105
|
+
"cause",
|
|
106
|
+
"batchIndex",
|
|
107
|
+
"kind"
|
|
108
|
+
];
|
|
109
|
+
for (const key of keys) {
|
|
110
|
+
const value = input[key];
|
|
111
|
+
if (value !== undefined)
|
|
112
|
+
fields[key] = value;
|
|
113
|
+
}
|
|
115
114
|
return fields;
|
|
116
115
|
}
|
|
117
116
|
|
|
@@ -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("CONNECT") || 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))
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
creationOrder2,
|
|
3
3
|
renameColumn2,
|
|
4
4
|
renameTable2
|
|
5
|
-
} from "./
|
|
5
|
+
} from "./12z7aznj.js";
|
|
6
6
|
import {
|
|
7
7
|
isConnectionLost
|
|
8
|
-
} from "./
|
|
8
|
+
} from "./cnkky55j.js";
|
|
9
9
|
import {
|
|
10
10
|
quoteIdent,
|
|
11
11
|
uniqueBeforeForeignKey,
|
|
@@ -21,12 +21,7 @@ import {
|
|
|
21
21
|
identitySequence,
|
|
22
22
|
createTableSql,
|
|
23
23
|
qualify
|
|
24
|
-
} from "./
|
|
25
|
-
import {
|
|
26
|
-
isExactVersion,
|
|
27
|
-
compareExtensionVersions,
|
|
28
|
-
sameExtensionDefinition
|
|
29
|
-
} from "./r3j8s5y0.js";
|
|
24
|
+
} from "./sjk86yrx.js";
|
|
30
25
|
import {
|
|
31
26
|
isDomain,
|
|
32
27
|
sameEnumLabels
|
|
@@ -34,6 +29,11 @@ import {
|
|
|
34
29
|
import {
|
|
35
30
|
quoteLiteral
|
|
36
31
|
} from "./94ez8kzh.js";
|
|
32
|
+
import {
|
|
33
|
+
isExactVersion,
|
|
34
|
+
compareExtensionVersions,
|
|
35
|
+
sameExtensionDefinition
|
|
36
|
+
} from "./r3j8s5y0.js";
|
|
37
37
|
import {
|
|
38
38
|
staticNamespace2,
|
|
39
39
|
identityKey2,
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
} from "./n4jqhpqz.js";
|
|
4
4
|
import {
|
|
5
5
|
refuseUncancellableTimeout
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./2d3xq4ps.js";
|
|
7
7
|
import {
|
|
8
8
|
withHttp,
|
|
9
9
|
settleCall
|
|
10
|
-
} from "./
|
|
10
|
+
} from "./bah9nbg3.js";
|
|
11
11
|
import {
|
|
12
12
|
rejectKeys,
|
|
13
13
|
isRecord,
|
|
14
|
-
|
|
15
|
-
} from "./
|
|
14
|
+
fail2
|
|
15
|
+
} from "./kgwp4jdd.js";
|
|
16
16
|
import {
|
|
17
17
|
OkmError2
|
|
18
18
|
} from "./52szzakm.js";
|
|
@@ -26,29 +26,29 @@ async function batch(session, ops, options, replica) {
|
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
28
28
|
if (!Array.isArray(ops))
|
|
29
|
-
|
|
29
|
+
fail2("OKM1121", "batch expects a list of write operations.");
|
|
30
30
|
const record = options ?? {};
|
|
31
31
|
if (!isRecord(record))
|
|
32
|
-
|
|
32
|
+
fail2("OKM1121", "batch options must be an object.");
|
|
33
33
|
rejectKeys(record, ["signal", "timeout"], "batch");
|
|
34
34
|
await refuseUncancellableTimeout(session.pool, typeof record["timeout"] === "number" ? record["timeout"] : undefined);
|
|
35
35
|
for (const op of ops) {
|
|
36
36
|
if (typeof op === "object" && op !== null && op["~refresh"] === true) {
|
|
37
|
-
|
|
37
|
+
fail2("OKM1121", "batch does not take refresh(). Await refresh() on its own. It is one statement and cannot share the batch.");
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
const prepared = [];
|
|
41
41
|
for (const op of ops) {
|
|
42
42
|
const plan = typeof op === "object" && op !== null ? op["~plan"] : undefined;
|
|
43
43
|
if (plan === undefined) {
|
|
44
|
-
|
|
44
|
+
fail2("OKM1121", "batch takes write operations: insert, update, delete, and archive. Pass them without awaiting.");
|
|
45
45
|
}
|
|
46
46
|
const item = await plan();
|
|
47
47
|
if (item.checked === "parent") {
|
|
48
48
|
throw new OkmError2("OKM1705", "batch does not take an update that sets a path column. The parent is checked in the statement, and a batch cannot report that after it commits. Use update({ where, set }) inside tx().", { fix: { summary: "Use update({ where, set }) inside tx()." } });
|
|
49
49
|
}
|
|
50
50
|
if (item.checked !== undefined) {
|
|
51
|
-
|
|
51
|
+
fail2("OKM1121", item.checked === "restore" ? "batch does not take restore: it is refused while its parent is archived, and a batch cannot report that after it commits. Use tx()." : "batch does not take a write with expect: the count is checked after the statement ran, and a batch cannot report that after it commits. Use tx().");
|
|
52
52
|
}
|
|
53
53
|
prepared.push(item);
|
|
54
54
|
}
|
|
@@ -73,11 +73,61 @@ async function run(session, prepared, options) {
|
|
|
73
73
|
} catch (error) {
|
|
74
74
|
throw at(error, starts);
|
|
75
75
|
}
|
|
76
|
+
const extra = await recover(session, prepared, results, starts, options);
|
|
76
77
|
return prepared.map((item, index) => {
|
|
77
78
|
const from = starts[index] ?? 0;
|
|
78
|
-
|
|
79
|
+
const slice = results.slice(from, from + item.statements.length);
|
|
80
|
+
const more = extra.get(index);
|
|
81
|
+
return item.finish(more === undefined ? slice : slice.concat(more));
|
|
79
82
|
});
|
|
80
83
|
}
|
|
84
|
+
async function recover(session, prepared, results, starts, options) {
|
|
85
|
+
const pending = [];
|
|
86
|
+
for (let index = 0;index < prepared.length; index += 1) {
|
|
87
|
+
const item = prepared[index];
|
|
88
|
+
if (item?.follow === undefined)
|
|
89
|
+
continue;
|
|
90
|
+
const from = starts[index] ?? 0;
|
|
91
|
+
const more = item.follow(results.slice(from, from + item.statements.length));
|
|
92
|
+
if (more.length === 0)
|
|
93
|
+
continue;
|
|
94
|
+
pending.push({ index, statements: more });
|
|
95
|
+
}
|
|
96
|
+
const found = new Map;
|
|
97
|
+
if (pending.length === 0)
|
|
98
|
+
return found;
|
|
99
|
+
const flat = [];
|
|
100
|
+
const extraStarts = [];
|
|
101
|
+
for (const item of pending) {
|
|
102
|
+
extraStarts.push(flat.length);
|
|
103
|
+
flat.push(...item.statements);
|
|
104
|
+
}
|
|
105
|
+
let ran;
|
|
106
|
+
try {
|
|
107
|
+
ran = await runWrite(session, flat, call(options), true);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
throw mapExtra(error, pending, extraStarts);
|
|
110
|
+
}
|
|
111
|
+
for (let index = 0;index < pending.length; index += 1) {
|
|
112
|
+
const item = pending[index];
|
|
113
|
+
if (item === undefined)
|
|
114
|
+
continue;
|
|
115
|
+
const from = extraStarts[index] ?? 0;
|
|
116
|
+
found.set(item.index, ran.slice(from, extraStarts[index + 1] ?? ran.length));
|
|
117
|
+
}
|
|
118
|
+
return found;
|
|
119
|
+
}
|
|
120
|
+
function mapExtra(error, pending, extraStarts) {
|
|
121
|
+
const failed = error?.batchIndex;
|
|
122
|
+
const move = error?.at;
|
|
123
|
+
if (typeof failed !== "number" || typeof move !== "function")
|
|
124
|
+
return error;
|
|
125
|
+
let slot = 0;
|
|
126
|
+
while (slot + 1 < extraStarts.length && (extraStarts[slot + 1] ?? Infinity) <= failed)
|
|
127
|
+
slot += 1;
|
|
128
|
+
const op = pending[slot]?.index ?? slot;
|
|
129
|
+
return op === failed ? error : move.call(error, op);
|
|
130
|
+
}
|
|
81
131
|
function call(options) {
|
|
82
132
|
const { signal, timeout } = options;
|
|
83
133
|
if (signal === undefined && timeout === undefined)
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
encodeText,
|
|
3
3
|
decodeText
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./typ3vy7t.js";
|
|
5
5
|
import {
|
|
6
6
|
required,
|
|
7
7
|
openColumn
|
|
8
|
-
} from "./
|
|
8
|
+
} from "./606g0nbf.js";
|
|
9
|
+
import {
|
|
10
|
+
readClientGenerator
|
|
11
|
+
} from "./rwmrejjz.js";
|
|
9
12
|
import {
|
|
10
13
|
definition,
|
|
11
14
|
rejected
|
|
12
15
|
} from "./tmbdywx0.js";
|
|
13
|
-
import {
|
|
14
|
-
readClientGenerator
|
|
15
|
-
} from "./rwmrejjz.js";
|
|
16
16
|
|
|
17
17
|
// src/dialects/pg/keys.ts
|
|
18
18
|
function id2(options) {
|
|
@@ -35,7 +35,7 @@ function id2(options) {
|
|
|
35
35
|
...client !== undefined ? { clientDefault: client } : {},
|
|
36
36
|
...okid ? { collation: "C" } : {},
|
|
37
37
|
idSource: chosen === undefined ? "implicit" : "column",
|
|
38
|
-
...client === undefined && !supplied ? { defaultSql: chosen === "
|
|
38
|
+
...client === undefined && !supplied ? { defaultSql: chosen === "uuidv7" ? "uuidv7()" : "gen_random_uuid()" } : {},
|
|
39
39
|
primaryKey: true,
|
|
40
40
|
encode: okid ? encodeText : encodeUuid,
|
|
41
41
|
decode: okid ? decodeText : decodeUuid,
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError2,
|
|
3
|
+
catalogError2,
|
|
4
|
+
throwNamed2
|
|
5
|
+
} from "./52szzakm.js";
|
|
6
|
+
|
|
7
|
+
// src/dialects/pg/morph.ts
|
|
8
|
+
var refuseTo = (planner, schema, relation, child, sink, parent, alias, depth) => {
|
|
9
|
+
const morph = relation.morph;
|
|
10
|
+
const typeField = morph?.typeField ?? "type";
|
|
11
|
+
const idField = morph?.idField ?? "id";
|
|
12
|
+
throw new OkmError2("OKM1120", `Relation ${relation.name} is a morph. Filter ${typeField} and ${idField}, or include it. has, none, and every are not available on it.`);
|
|
13
|
+
};
|
|
14
|
+
function resolveMorph(scope, name, targets) {
|
|
15
|
+
const label = `${scope.owner}.${scope.name}`;
|
|
16
|
+
const owner = described(scope, scope.owner, label);
|
|
17
|
+
const typeField = `${name}Type`;
|
|
18
|
+
const idField = `${name}Id`;
|
|
19
|
+
const typeColumn = requireColumn(owner, typeField, label);
|
|
20
|
+
const idColumn = requireColumn(owner, idField, label);
|
|
21
|
+
if (typeColumn.nullable !== idColumn.nullable) {
|
|
22
|
+
catalogError2("OKM1021", `Relation ${label} columns ${owner.tsName}.${typeColumn.field} and ${owner.tsName}.${idColumn.field} must both be nullable, or neither.`);
|
|
23
|
+
}
|
|
24
|
+
if (!isTextType(typeColumn.dataType)) {
|
|
25
|
+
catalogError2("OKM1022", `Relation ${label} type column ${owner.tsName}.${typeColumn.field} is ${typeColumn.dataType}. Accepted type: text.`);
|
|
26
|
+
}
|
|
27
|
+
const seen = new Set;
|
|
28
|
+
const resolved = [];
|
|
29
|
+
for (const targetName of targets) {
|
|
30
|
+
if (seen.has(targetName)) {
|
|
31
|
+
catalogError2("OKM1023", `Relation ${label} lists ${targetName} twice.`);
|
|
32
|
+
}
|
|
33
|
+
seen.add(targetName);
|
|
34
|
+
if (!scope.tables.includes(targetName)) {
|
|
35
|
+
throwNamed2("OKM1020", targetName, scope.tables, `Relation ${label} names ${targetName}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
|
|
36
|
+
}
|
|
37
|
+
const target = described(scope, targetName, label);
|
|
38
|
+
const key = requireKey(target, label, scope.scopeFields);
|
|
39
|
+
if (idColumn.dataType !== key.dataType) {
|
|
40
|
+
catalogError2("OKM1022", `Relation ${label} id column ${owner.tsName}.${idColumn.field} is ${idColumn.dataType} and ${target.tsName}.${key.field} is ${key.dataType}. Accepted type: ${key.dataType}.`);
|
|
41
|
+
}
|
|
42
|
+
const limit = textLimit(typeColumn.dataType);
|
|
43
|
+
if (limit !== undefined && targetName.length > limit) {
|
|
44
|
+
catalogError2("OKM1022", `Relation ${label} type column ${owner.tsName}.${typeColumn.field} is ${typeColumn.dataType} and ${target.tsName} does not fit. Accepted type: text.`);
|
|
45
|
+
}
|
|
46
|
+
resolved.push({
|
|
47
|
+
type: target.tsName,
|
|
48
|
+
table: target.tsName,
|
|
49
|
+
sql: target.sqlName,
|
|
50
|
+
keySql: key.sql
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const first = resolved[0];
|
|
54
|
+
if (first === undefined) {
|
|
55
|
+
catalogError2("OKM1020", `Relation ${label} needs a target table.`);
|
|
56
|
+
}
|
|
57
|
+
const morph = {
|
|
58
|
+
direction: "to",
|
|
59
|
+
name,
|
|
60
|
+
typeField,
|
|
61
|
+
idField,
|
|
62
|
+
typeSql: typeColumn.sqlName,
|
|
63
|
+
idSql: idColumn.sqlName,
|
|
64
|
+
targets: resolved
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
name: scope.name,
|
|
68
|
+
kind: "one",
|
|
69
|
+
table: first.table,
|
|
70
|
+
local: [idColumn.sqlName],
|
|
71
|
+
remote: [first.keySql],
|
|
72
|
+
morph,
|
|
73
|
+
through: {
|
|
74
|
+
table: first.table,
|
|
75
|
+
local: [idColumn.sqlName],
|
|
76
|
+
remote: [first.keySql],
|
|
77
|
+
emit: refuseTo
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function resolveMorphMany(scope, table, name) {
|
|
82
|
+
const label = `${scope.owner}.${scope.name}`;
|
|
83
|
+
if (!scope.tables.includes(table)) {
|
|
84
|
+
throwNamed2("OKM1020", table, scope.tables, `Relation ${label} names ${table}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
|
|
85
|
+
}
|
|
86
|
+
const owner = described(scope, table, label);
|
|
87
|
+
const here = described(scope, scope.owner, label);
|
|
88
|
+
const targets = declaredTargets(owner.relationOptions, name);
|
|
89
|
+
if (targets === undefined) {
|
|
90
|
+
catalogError2("OKM1021", `Relation ${label} needs morph("${name}", [...]) on ${owner.tsName}. ${owner.tsName} has no morph named ${name}.`);
|
|
91
|
+
}
|
|
92
|
+
if (!targets.includes(scope.owner)) {
|
|
93
|
+
catalogError2("OKM1020", `Relation ${label} is not a target of ${owner.tsName}.${name}. Accepted tables: ${targets.join(", ")}.`);
|
|
94
|
+
}
|
|
95
|
+
const typeField = `${name}Type`;
|
|
96
|
+
const idField = `${name}Id`;
|
|
97
|
+
const typeColumn = requireColumn(owner, typeField, label);
|
|
98
|
+
const idColumn = requireColumn(owner, idField, label);
|
|
99
|
+
const key = requireKey(here, label, scope.scopeFields);
|
|
100
|
+
if (idColumn.dataType !== key.dataType) {
|
|
101
|
+
catalogError2("OKM1022", `Relation ${label} id column ${owner.tsName}.${idColumn.field} is ${idColumn.dataType} and ${here.tsName}.${key.field} is ${key.dataType}. Accepted type: ${key.dataType}.`);
|
|
102
|
+
}
|
|
103
|
+
const morph = {
|
|
104
|
+
direction: "many",
|
|
105
|
+
name,
|
|
106
|
+
typeField,
|
|
107
|
+
idField,
|
|
108
|
+
typeSql: typeColumn.sqlName,
|
|
109
|
+
idSql: idColumn.sqlName,
|
|
110
|
+
typeValue: here.tsName,
|
|
111
|
+
targets: [
|
|
112
|
+
{
|
|
113
|
+
type: here.tsName,
|
|
114
|
+
table: here.tsName,
|
|
115
|
+
sql: here.sqlName,
|
|
116
|
+
keySql: key.sql
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
name: scope.name,
|
|
122
|
+
kind: "many",
|
|
123
|
+
table: owner.tsName,
|
|
124
|
+
local: [key.sql],
|
|
125
|
+
remote: [idColumn.sqlName],
|
|
126
|
+
morph,
|
|
127
|
+
through: {
|
|
128
|
+
table: owner.tsName,
|
|
129
|
+
local: [idColumn.sqlName],
|
|
130
|
+
remote: [key.sql],
|
|
131
|
+
emit: morphManyEmit(here.tsName)
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function morphManyEmit(typeValue) {
|
|
136
|
+
return (planner, schema, relation, child, sink, parent, alias) => {
|
|
137
|
+
const pair = relation.morph;
|
|
138
|
+
const local = relation.local[0];
|
|
139
|
+
if (pair === undefined || local === undefined) {
|
|
140
|
+
throw new OkmError2("OKM1120", `Relation ${relation.name} is not a morph many.`);
|
|
141
|
+
}
|
|
142
|
+
const { quote } = planner;
|
|
143
|
+
sink.text(quote(child.model.sql));
|
|
144
|
+
sink.text(" ");
|
|
145
|
+
sink.text(alias);
|
|
146
|
+
sink.text(" where ");
|
|
147
|
+
sink.text(alias);
|
|
148
|
+
sink.text(".");
|
|
149
|
+
sink.text(quote(pair.typeSql));
|
|
150
|
+
sink.text(" = ");
|
|
151
|
+
sink.param(typeValue);
|
|
152
|
+
sink.text("::text");
|
|
153
|
+
sink.text(" and ");
|
|
154
|
+
sink.text(alias);
|
|
155
|
+
sink.text(".");
|
|
156
|
+
sink.text(quote(pair.idSql));
|
|
157
|
+
sink.text(" = ");
|
|
158
|
+
sink.text(parent);
|
|
159
|
+
sink.text(".");
|
|
160
|
+
sink.text(quote(local));
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function described(scope, table, label) {
|
|
164
|
+
const found = scope.describe?.(table);
|
|
165
|
+
if (!isDescribed(found)) {
|
|
166
|
+
catalogError2("OKM1020", `Relation ${label} names ${table}, which is not in the schema.`);
|
|
167
|
+
}
|
|
168
|
+
return found;
|
|
169
|
+
}
|
|
170
|
+
function isDescribed(value) {
|
|
171
|
+
if (typeof value !== "object" || value === null)
|
|
172
|
+
return false;
|
|
173
|
+
if (!("tsName" in value) || typeof value.tsName !== "string")
|
|
174
|
+
return false;
|
|
175
|
+
if (!("sqlName" in value) || typeof value.sqlName !== "string")
|
|
176
|
+
return false;
|
|
177
|
+
if (!("primary" in value) || !Array.isArray(value.primary))
|
|
178
|
+
return false;
|
|
179
|
+
if (!("byField" in value) || !(value.byField instanceof Map))
|
|
180
|
+
return false;
|
|
181
|
+
if (!("bySql" in value) || !(value.bySql instanceof Map))
|
|
182
|
+
return false;
|
|
183
|
+
return "relationOptions" in value;
|
|
184
|
+
}
|
|
185
|
+
function requireColumn(table, field, label) {
|
|
186
|
+
const column = table.byField.get(field);
|
|
187
|
+
if (column === undefined) {
|
|
188
|
+
catalogError2("OKM1021", `Relation ${label} needs column ${field} on ${table.tsName}.`);
|
|
189
|
+
}
|
|
190
|
+
return column;
|
|
191
|
+
}
|
|
192
|
+
function requireKey(table, label, scopeFields) {
|
|
193
|
+
const skip = scopeFields ?? [];
|
|
194
|
+
const keys = [];
|
|
195
|
+
for (const sql of table.primary) {
|
|
196
|
+
const column = table.bySql.get(sql);
|
|
197
|
+
if (column === undefined || skip.includes(column.field))
|
|
198
|
+
continue;
|
|
199
|
+
keys.push({ field: column.field, sql, dataType: column.dataType });
|
|
200
|
+
}
|
|
201
|
+
const only = keys.length === 1 ? keys[0] : undefined;
|
|
202
|
+
if (only !== undefined)
|
|
203
|
+
return only;
|
|
204
|
+
const names = keys.map((key) => key.field);
|
|
205
|
+
catalogError2("OKM1021", `Relation ${label} cannot use ${table.tsName} as a target. Its primary key is ${names.length === 0 ? "(none)" : names.join(", ")}. A morph id matches one column.`);
|
|
206
|
+
}
|
|
207
|
+
function declaredTargets(options, name) {
|
|
208
|
+
if (typeof options !== "object" || options === null)
|
|
209
|
+
return;
|
|
210
|
+
for (const value of Object.values(options)) {
|
|
211
|
+
if (typeof value !== "object" || value === null || !("morph" in value))
|
|
212
|
+
continue;
|
|
213
|
+
const morph = value.morph;
|
|
214
|
+
if (morph === undefined || morph.name !== name || !Array.isArray(morph.targets))
|
|
215
|
+
continue;
|
|
216
|
+
const names = [];
|
|
217
|
+
for (const target of morph.targets) {
|
|
218
|
+
if (typeof target === "string")
|
|
219
|
+
names.push(target);
|
|
220
|
+
}
|
|
221
|
+
return names;
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
function assertMorphTo(name, type, id) {
|
|
226
|
+
if (name === null || type === null || typeof id !== "string" || id.length === 0) {
|
|
227
|
+
throw new OkmError2("OKM1120", "morphTo() needs a morph name, a target table, and that table's id.");
|
|
228
|
+
}
|
|
229
|
+
if (typeof name !== "string" || name.length === 0 || typeof type !== "string" || type.length === 0) {
|
|
230
|
+
throw new OkmError2("OKM1020", "morphTo() needs a morph name and a target table.");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function isTextType(dataType) {
|
|
234
|
+
return dataType === "text" || dataType === "citext" || dataType.startsWith("varchar(") || dataType.startsWith("character varying(") || dataType.startsWith("char(") || dataType.startsWith("character(");
|
|
235
|
+
}
|
|
236
|
+
function textLimit(dataType) {
|
|
237
|
+
const match = /^(?:varchar|character varying|char|character)\((\d+)\)$/.exec(dataType);
|
|
238
|
+
if (match?.[1] === undefined)
|
|
239
|
+
return;
|
|
240
|
+
return Number(match[1]);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/dialects/pg/through.ts
|
|
244
|
+
var emit = (planner, schema, relation, child, sink, parent, alias, depth) => {
|
|
245
|
+
const through = relation.through;
|
|
246
|
+
const join = through === undefined ? undefined : planner.indexes(schema).get(through.table);
|
|
247
|
+
if (through === undefined || join === undefined) {
|
|
248
|
+
return catalogError2("OKM1020", `Relation ${relation.name} names a join table that is not in the schema.`);
|
|
249
|
+
}
|
|
250
|
+
const { quote } = planner;
|
|
251
|
+
const joinAlias = `j${alias}`;
|
|
252
|
+
sink.mark(`via:${through.table}`);
|
|
253
|
+
sink.text(`${quote(join.model.sql)} ${joinAlias} join ${quote(child.model.sql)} ${alias} on `);
|
|
254
|
+
for (let index = 0;index < through.local.length; index += 1) {
|
|
255
|
+
const local = through.local[index];
|
|
256
|
+
const remote = through.remote[index];
|
|
257
|
+
if (local === undefined || remote === undefined)
|
|
258
|
+
continue;
|
|
259
|
+
if (index > 0)
|
|
260
|
+
sink.text(" and ");
|
|
261
|
+
sink.text(`${alias}.${quote(remote)} = ${joinAlias}.${quote(local)}`);
|
|
262
|
+
}
|
|
263
|
+
sink.text(" where ");
|
|
264
|
+
planner.join(sink, parent, joinAlias, relation);
|
|
265
|
+
planner.where(schema, join, undefined, sink, joinAlias, depth + 1, true);
|
|
266
|
+
};
|
|
267
|
+
function resolveThrough(scope, table, through, from, to) {
|
|
268
|
+
for (const name of [table, through]) {
|
|
269
|
+
if (!scope.tables.includes(name)) {
|
|
270
|
+
throwNamed2("OKM1020", name, scope.tables, `Relation ${scope.owner}.${scope.name} names ${name}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const toOwner = pick(scope, through, scope.owner, from, `${scope.owner}.${scope.name}`, "from");
|
|
274
|
+
const toTable = pick(scope, through, table, to, `${scope.owner}.${scope.name}`, "to");
|
|
275
|
+
if (toOwner === toTable) {
|
|
276
|
+
catalogError2("OKM1021", `Relation ${scope.owner}.${scope.name} uses ${toOwner.fromField} on ${through} for both ends. Pass from and to.`);
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
name: scope.name,
|
|
280
|
+
kind: "many",
|
|
281
|
+
table,
|
|
282
|
+
local: toOwner.remote,
|
|
283
|
+
remote: toOwner.local,
|
|
284
|
+
through: { table: through, local: toTable.local, remote: toTable.remote, emit }
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function pick(scope, through, target, field, label, end) {
|
|
288
|
+
const matches = scope.edges.filter((edge) => edge.fromTable === through && edge.toTable === target && (field === undefined || edge.fromField === field));
|
|
289
|
+
const [only] = matches;
|
|
290
|
+
if (matches.length === 1 && only !== undefined)
|
|
291
|
+
return only;
|
|
292
|
+
const fields = matches.map((edge) => edge.fromField).sort();
|
|
293
|
+
catalogError2("OKM1021", `Relation ${label} through ${through} is ambiguous at ${end}. Accepted columns: ${fields.length === 0 ? "(none)" : fields.join(", ")}.`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/dialects/pg/relations.ts
|
|
297
|
+
function one2(table, field) {
|
|
298
|
+
return { kind: "one", table, field };
|
|
299
|
+
}
|
|
300
|
+
function many2(table, field) {
|
|
301
|
+
return { kind: "many", table, field };
|
|
302
|
+
}
|
|
303
|
+
function isRelationCall(value) {
|
|
304
|
+
if (typeof value !== "object" || value === null)
|
|
305
|
+
return false;
|
|
306
|
+
if (!("kind" in value) || !("table" in value))
|
|
307
|
+
return false;
|
|
308
|
+
const kind = value.kind;
|
|
309
|
+
return (kind === "one" || kind === "many") && typeof value.table === "string";
|
|
310
|
+
}
|
|
311
|
+
function manyThrough2(table, options) {
|
|
312
|
+
const { through, from, to } = options;
|
|
313
|
+
return {
|
|
314
|
+
kind: "many",
|
|
315
|
+
table,
|
|
316
|
+
field: undefined,
|
|
317
|
+
through,
|
|
318
|
+
resolve: (scope) => resolveThrough(scope, table, through, from, to)
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
function morph2(name, targets) {
|
|
322
|
+
if (name.length === 0)
|
|
323
|
+
throw new OkmError2("OKM1020", "morph() needs a name.");
|
|
324
|
+
if (targets.length === 0)
|
|
325
|
+
throw new OkmError2("OKM1020", "morph() needs a target table.");
|
|
326
|
+
for (const target of targets) {
|
|
327
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
328
|
+
throw new OkmError2("OKM1020", "morph() targets must be table names.");
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const list = targets;
|
|
332
|
+
return {
|
|
333
|
+
kind: "one",
|
|
334
|
+
table: targets[0],
|
|
335
|
+
field: undefined,
|
|
336
|
+
morph: { name, targets, typeField: `${name}Type` },
|
|
337
|
+
resolve: (scope) => resolveMorph(scope, name, list)
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function morphMany2(table, name) {
|
|
341
|
+
if (table.length === 0 || name.length === 0) {
|
|
342
|
+
throw new OkmError2("OKM1020", "morphMany() needs a table and a morph name.");
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
kind: "many",
|
|
346
|
+
table,
|
|
347
|
+
field: undefined,
|
|
348
|
+
resolve: (scope) => resolveMorphMany(scope, table, name)
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function morphTo2(name, type, id) {
|
|
352
|
+
assertMorphTo(name, type, id);
|
|
353
|
+
const row = {};
|
|
354
|
+
row[`${name}Type`] = type;
|
|
355
|
+
row[`${name}Id`] = id;
|
|
356
|
+
return row;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export { one2, many2, isRelationCall, manyThrough2, morph2, morphMany2, morphTo2 };
|