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
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runWrite
|
|
3
|
+
} from "./n4jqhpqz.js";
|
|
4
|
+
import {
|
|
5
|
+
withRowFilters,
|
|
6
|
+
emitWhere,
|
|
7
|
+
indexes,
|
|
8
|
+
quote,
|
|
9
|
+
isRecord,
|
|
10
|
+
fail2
|
|
11
|
+
} from "./kgwp4jdd.js";
|
|
12
|
+
import {
|
|
13
|
+
OkmError2
|
|
14
|
+
} from "./52szzakm.js";
|
|
15
|
+
|
|
16
|
+
// src/runtime/sort.ts
|
|
17
|
+
function insertAtEnd(table, columns, rows, group, tenantFields) {
|
|
18
|
+
const position = requiredColumn(table, "position");
|
|
19
|
+
const groupColumn = group === undefined ? undefined : requiredColumn(table, group);
|
|
20
|
+
const tenants = tenantColumns(table, tenantFields);
|
|
21
|
+
const planned = [];
|
|
22
|
+
const countOf = new Map;
|
|
23
|
+
const firstOf = new Map;
|
|
24
|
+
for (const row of rows) {
|
|
25
|
+
if (groupColumn !== undefined && !Object.hasOwn(row, groupColumn.field)) {
|
|
26
|
+
fail2("OKM1121", `insert on ${table.model.name} needs ${groupColumn.field} so position has a group.`, "Pass the group on the row. Position is assigned for you.");
|
|
27
|
+
}
|
|
28
|
+
const key = lockText(table.model.sql, wires(tenants, row), groupColumn === undefined ? null : cellWire(groupColumn, row[groupColumn.field]));
|
|
29
|
+
if (!firstOf.has(key))
|
|
30
|
+
firstOf.set(key, row);
|
|
31
|
+
const n = (countOf.get(key) ?? 0) + 1;
|
|
32
|
+
countOf.set(key, n);
|
|
33
|
+
planned.push({ key, n, row });
|
|
34
|
+
}
|
|
35
|
+
const params = [];
|
|
36
|
+
const bind = (wire, dataType) => {
|
|
37
|
+
params.push(wire);
|
|
38
|
+
return `$${String(params.length)}::${dataType}`;
|
|
39
|
+
};
|
|
40
|
+
const slotOf = new Map;
|
|
41
|
+
for (const key of firstOf.keys())
|
|
42
|
+
slotOf.set(key, bind(key, "text"));
|
|
43
|
+
const baseRows = [];
|
|
44
|
+
for (const [key, row] of firstOf) {
|
|
45
|
+
const parts = [slotOf.get(key) ?? bind(key, "text")];
|
|
46
|
+
if (groupColumn !== undefined)
|
|
47
|
+
parts.push(bind(cellWire(groupColumn, row[groupColumn.field]), groupColumn.dataType));
|
|
48
|
+
for (const column of tenants)
|
|
49
|
+
parts.push(bind(cellWire(column, row[column.field]), column.dataType));
|
|
50
|
+
baseRows.push(`(${parts.join(", ")})`);
|
|
51
|
+
}
|
|
52
|
+
const baseNames = ["okm_lock"];
|
|
53
|
+
if (groupColumn !== undefined)
|
|
54
|
+
baseNames.push("okm_g");
|
|
55
|
+
for (let index = 0;index < tenants.length; index += 1)
|
|
56
|
+
baseNames.push(`okm_t${String(index)}`);
|
|
57
|
+
const lists = planned.map((item) => {
|
|
58
|
+
const slot = slotOf.get(item.key) ?? bind(item.key, "text");
|
|
59
|
+
const slots = columns.map((column) => cell(column, item.row[column.field], bind));
|
|
60
|
+
slots.push(`((select b.pos from base b where b.okm_lock = ${slot}) + ${String(item.n)})::integer`);
|
|
61
|
+
return `(${slots.join(", ")})`;
|
|
62
|
+
});
|
|
63
|
+
const insertColumns = [...columns.map((column) => quote(column.sql)), quote(position.sql)];
|
|
64
|
+
const text = [
|
|
65
|
+
"with base as (",
|
|
66
|
+
"select i.okm_lock, coalesce(max(t.",
|
|
67
|
+
quote(position.sql),
|
|
68
|
+
"), 0) as pos from (values ",
|
|
69
|
+
baseRows.join(", "),
|
|
70
|
+
") as i(",
|
|
71
|
+
baseNames.join(", "),
|
|
72
|
+
") left join ",
|
|
73
|
+
quote(table.model.sql),
|
|
74
|
+
" as t on ",
|
|
75
|
+
joinOn(groupColumn, tenants),
|
|
76
|
+
" group by i.okm_lock",
|
|
77
|
+
") insert into ",
|
|
78
|
+
quote(table.model.sql),
|
|
79
|
+
" (",
|
|
80
|
+
insertColumns.join(", "),
|
|
81
|
+
") values ",
|
|
82
|
+
lists.join(", ")
|
|
83
|
+
].join("");
|
|
84
|
+
return { lock: groupLock([...firstOf.keys()]), text, params };
|
|
85
|
+
}
|
|
86
|
+
async function move(host, tableName, id, place, view) {
|
|
87
|
+
await host.connected;
|
|
88
|
+
const table = indexes(host.schema).get(tableName);
|
|
89
|
+
if (table === undefined)
|
|
90
|
+
fail2("OKM1120", `Table ${tableName} is not in the schema.`);
|
|
91
|
+
const group = groupField(table);
|
|
92
|
+
if (!sortable(table)) {
|
|
93
|
+
fail2("OKM1120", `move on ${tableName} needs sortable().`, "Add sortable() from okmodel/traits.");
|
|
94
|
+
}
|
|
95
|
+
const anchor = readPlace(place, tableName);
|
|
96
|
+
const key = moveColumn(host.schema, table);
|
|
97
|
+
if (sameId(id, anchor.id)) {
|
|
98
|
+
const current = await readOne(host, table, key, id, group, view);
|
|
99
|
+
if (current === undefined)
|
|
100
|
+
missing(tableName, id);
|
|
101
|
+
return { position: current.position };
|
|
102
|
+
}
|
|
103
|
+
const moved = await readOne(host, table, key, id, group, view);
|
|
104
|
+
if (moved === undefined)
|
|
105
|
+
missing(tableName, id);
|
|
106
|
+
const other = await readOne(host, table, key, anchor.id, group, view);
|
|
107
|
+
if (other === undefined)
|
|
108
|
+
missing(tableName, anchor.id);
|
|
109
|
+
if (moved.groupWire !== other.groupWire) {
|
|
110
|
+
const which = group ?? "group";
|
|
111
|
+
throw new OkmError2("OKM1120", `move on ${tableName} cannot place ${show(id)} ${anchor.side} ${show(anchor.id)}. ${show(anchor.id)} is in another ${which}.`, { fix: { summary: `Choose an anchor in the same ${which}.` } });
|
|
112
|
+
}
|
|
113
|
+
const statements = withRowFilters(host.scope, view, () => moveStatements(host.schema, table, key, id, anchor.id, moved, anchor.side, group));
|
|
114
|
+
const results = await runWrite(host, statements, callOptions(host));
|
|
115
|
+
const row = results[1]?.rows[0];
|
|
116
|
+
if (count(row?.[0]) !== 1)
|
|
117
|
+
missing(tableName, id);
|
|
118
|
+
if (count(row?.[1]) !== 1)
|
|
119
|
+
missing(tableName, anchor.id);
|
|
120
|
+
return { position: count(row?.[2]) };
|
|
121
|
+
}
|
|
122
|
+
function sortable(table) {
|
|
123
|
+
const traits = table.model.traits;
|
|
124
|
+
if (traits === undefined)
|
|
125
|
+
return false;
|
|
126
|
+
for (const trait of traits)
|
|
127
|
+
if (trait.name === "sortable")
|
|
128
|
+
return true;
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
function groupField(table) {
|
|
132
|
+
const traits = table.model.traits;
|
|
133
|
+
if (traits === undefined)
|
|
134
|
+
return;
|
|
135
|
+
for (const trait of traits) {
|
|
136
|
+
if (trait.name !== "sortable")
|
|
137
|
+
continue;
|
|
138
|
+
const group = trait.group;
|
|
139
|
+
return typeof group === "string" ? group : undefined;
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
function readPlace(place, table) {
|
|
144
|
+
if (!isRecord(place))
|
|
145
|
+
fail2("OKM1120", `move on ${table} needs { before } or { after }.`);
|
|
146
|
+
const before = Object.hasOwn(place, "before");
|
|
147
|
+
const after = Object.hasOwn(place, "after");
|
|
148
|
+
if (before === after) {
|
|
149
|
+
fail2("OKM1120", `move on ${table} needs before or after, not both.`, "Pass one anchor.");
|
|
150
|
+
}
|
|
151
|
+
for (const key of Object.keys(place)) {
|
|
152
|
+
if (key === "before" || key === "after")
|
|
153
|
+
continue;
|
|
154
|
+
fail2("OKM1120", `move on ${table} does not accept ${key}. Accepted options: before, after.`);
|
|
155
|
+
}
|
|
156
|
+
return { side: before ? "before" : "after", id: before ? place.before : place.after };
|
|
157
|
+
}
|
|
158
|
+
function moveColumn(schema, table) {
|
|
159
|
+
const tenants = new Set(tenantFieldNames(schema.tenancy, table));
|
|
160
|
+
const fields = table.model.primary.filter((field) => !tenants.has(field));
|
|
161
|
+
if (fields.length !== 1) {
|
|
162
|
+
fail2("OKM1120", `move on ${table.model.name} needs one primary key column besides the tenant key.`);
|
|
163
|
+
}
|
|
164
|
+
return requiredColumn(table, fields[0] ?? "");
|
|
165
|
+
}
|
|
166
|
+
function tenantFieldNames(tenancy, table) {
|
|
167
|
+
if (tenancy === undefined)
|
|
168
|
+
return [];
|
|
169
|
+
const keys = tenancy.keys ?? [tenancy.key];
|
|
170
|
+
return keys.filter((key) => table.columns.has(key));
|
|
171
|
+
}
|
|
172
|
+
async function readOne(host, table, key, id, group, view) {
|
|
173
|
+
const position = requiredColumn(table, "position");
|
|
174
|
+
const groupColumn = group === undefined ? undefined : requiredColumn(table, group);
|
|
175
|
+
const tenants = tenantColumns(table, tenantFieldNames(host.schema.tenancy, table));
|
|
176
|
+
const statement = withRowFilters(host.scope, view, () => {
|
|
177
|
+
const parts = [];
|
|
178
|
+
const params = [];
|
|
179
|
+
parts.push("select ");
|
|
180
|
+
parts.push(quote(position.sql));
|
|
181
|
+
if (groupColumn !== undefined) {
|
|
182
|
+
parts.push(", ");
|
|
183
|
+
parts.push(quote(groupColumn.sql));
|
|
184
|
+
}
|
|
185
|
+
for (const column of tenants) {
|
|
186
|
+
parts.push(", ");
|
|
187
|
+
parts.push(quote(column.sql));
|
|
188
|
+
}
|
|
189
|
+
parts.push(" from ");
|
|
190
|
+
parts.push(quote(table.model.sql));
|
|
191
|
+
parts.push(" as t where t.");
|
|
192
|
+
parts.push(quote(key.sql));
|
|
193
|
+
parts.push(" = $1::");
|
|
194
|
+
parts.push(key.dataType);
|
|
195
|
+
params.push(key.encode(id));
|
|
196
|
+
emitWhere(host.schema, table, undefined, sink(parts, params), "t", 0, true);
|
|
197
|
+
return { text: parts.join(""), params };
|
|
198
|
+
});
|
|
199
|
+
const result = await host.pool.execute(statement.text, statement.params, callOptions(host));
|
|
200
|
+
const found = result.rows[0];
|
|
201
|
+
if (found === undefined)
|
|
202
|
+
return;
|
|
203
|
+
let at = 1;
|
|
204
|
+
const groupWire = groupColumn === undefined ? null : decodeWire(groupColumn, found[at]);
|
|
205
|
+
if (groupColumn !== undefined)
|
|
206
|
+
at += 1;
|
|
207
|
+
const tenantWires = [];
|
|
208
|
+
for (const column of tenants) {
|
|
209
|
+
tenantWires.push(decodeWire(column, found[at]));
|
|
210
|
+
at += 1;
|
|
211
|
+
}
|
|
212
|
+
return { position: count(found[0]), groupWire, tenants: tenantWires };
|
|
213
|
+
}
|
|
214
|
+
function moveStatements(schema, table, key, id, anchor, moved, side, group) {
|
|
215
|
+
const lock = groupLock([lockText(table.model.sql, moved.tenants, moved.groupWire)]);
|
|
216
|
+
const place = moveStatement(schema, table, key, id, anchor, moved, side, group);
|
|
217
|
+
const tenants = tenantColumns(table, tenantFieldNames(schema.tenancy, table));
|
|
218
|
+
return [lock, place, flipStatement(table, moved, group, tenants)];
|
|
219
|
+
}
|
|
220
|
+
function moveStatement(schema, table, key, id, anchor, moved, side, group) {
|
|
221
|
+
const position = requiredColumn(table, "position");
|
|
222
|
+
const groupColumn = group === undefined ? undefined : requiredColumn(table, group);
|
|
223
|
+
const tenants = tenantColumns(table, tenantFieldNames(schema.tenancy, table));
|
|
224
|
+
const params = [];
|
|
225
|
+
const bind = (wire, dataType) => {
|
|
226
|
+
params.push(wire);
|
|
227
|
+
return `$${String(params.length)}::${dataType}`;
|
|
228
|
+
};
|
|
229
|
+
const groupSlot = groupColumn === undefined ? "" : bind(moved.groupWire, groupColumn.dataType);
|
|
230
|
+
const tenantSlots = tenants.map((column, index) => bind(moved.tenants[index] ?? null, column.dataType));
|
|
231
|
+
const movedSlot = bind(key.encode(id), key.dataType);
|
|
232
|
+
const anchorSlot = bind(key.encode(anchor), key.dataType);
|
|
233
|
+
const delta = bind(side === "before" ? "-0.5" : "0.5", "numeric");
|
|
234
|
+
const parts = [];
|
|
235
|
+
parts.push("with members as (select t.ctid as tid, t.tableoid as toid, t.");
|
|
236
|
+
parts.push(quote(position.sql));
|
|
237
|
+
parts.push(" as pos, t.");
|
|
238
|
+
parts.push(quote(key.sql));
|
|
239
|
+
parts.push(" as ident from ");
|
|
240
|
+
parts.push(quote(table.model.sql));
|
|
241
|
+
parts.push(" as t");
|
|
242
|
+
let filtered = false;
|
|
243
|
+
if (groupColumn !== undefined) {
|
|
244
|
+
parts.push(" where t.");
|
|
245
|
+
parts.push(quote(groupColumn.sql));
|
|
246
|
+
parts.push(" is not distinct from ");
|
|
247
|
+
parts.push(groupSlot);
|
|
248
|
+
filtered = true;
|
|
249
|
+
}
|
|
250
|
+
for (let index = 0;index < tenants.length; index += 1) {
|
|
251
|
+
const column = tenants[index];
|
|
252
|
+
if (column === undefined)
|
|
253
|
+
continue;
|
|
254
|
+
parts.push(filtered ? " and t." : " where t.");
|
|
255
|
+
parts.push(quote(column.sql));
|
|
256
|
+
parts.push(" is not distinct from ");
|
|
257
|
+
parts.push(tenantSlots[index] ?? "null");
|
|
258
|
+
filtered = true;
|
|
259
|
+
}
|
|
260
|
+
emitWhere(schema, table, undefined, sink(parts, params), "t", 0, filtered);
|
|
261
|
+
parts.push(" for update of t), numbered as (select ident, pos, tid, toid, row_number() over (order by pos, ident) as ord from members), placed as (select ident, pos, tid, toid, row_number() over (order by case when ident = ");
|
|
262
|
+
parts.push(movedSlot);
|
|
263
|
+
parts.push(" then (select ord from numbered where ident = ");
|
|
264
|
+
parts.push(anchorSlot);
|
|
265
|
+
parts.push(") + ");
|
|
266
|
+
parts.push(delta);
|
|
267
|
+
parts.push(" else ord end, case when ident = ");
|
|
268
|
+
parts.push(movedSlot);
|
|
269
|
+
parts.push(" then 0 else 1 end) as new_pos from numbered where (select count(*) from numbered where ident = ");
|
|
270
|
+
parts.push(movedSlot);
|
|
271
|
+
parts.push(") = 1 and (select count(*) from numbered where ident = ");
|
|
272
|
+
parts.push(anchorSlot);
|
|
273
|
+
parts.push(") = 1), changed as (update ");
|
|
274
|
+
parts.push(quote(table.model.sql));
|
|
275
|
+
parts.push(" as t set ");
|
|
276
|
+
parts.push(quote(position.sql));
|
|
277
|
+
parts.push(" = (-p.new_pos)::integer from placed as p where t.ctid = p.tid and t.tableoid = p.toid returning t.ctid) select (select count(*)::int from numbered where ident = ");
|
|
278
|
+
parts.push(movedSlot);
|
|
279
|
+
parts.push("), (select count(*)::int from numbered where ident = ");
|
|
280
|
+
parts.push(anchorSlot);
|
|
281
|
+
parts.push("), coalesce((select new_pos::int from placed where ident = ");
|
|
282
|
+
parts.push(movedSlot);
|
|
283
|
+
parts.push("), 0), (select count(*)::int from changed)");
|
|
284
|
+
return { text: parts.join(""), ...params.length > 0 ? { params } : {} };
|
|
285
|
+
}
|
|
286
|
+
function flipStatement(table, moved, group, tenants) {
|
|
287
|
+
const position = requiredColumn(table, "position");
|
|
288
|
+
const groupColumn = group === undefined ? undefined : requiredColumn(table, group);
|
|
289
|
+
const params = [];
|
|
290
|
+
const bind = (wire, dataType) => {
|
|
291
|
+
params.push(wire);
|
|
292
|
+
return `$${String(params.length)}::${dataType}`;
|
|
293
|
+
};
|
|
294
|
+
const parts = [
|
|
295
|
+
"update ",
|
|
296
|
+
quote(table.model.sql),
|
|
297
|
+
" as t set ",
|
|
298
|
+
quote(position.sql),
|
|
299
|
+
" = (-t.",
|
|
300
|
+
quote(position.sql),
|
|
301
|
+
")::integer where t.",
|
|
302
|
+
quote(position.sql),
|
|
303
|
+
" < 0"
|
|
304
|
+
];
|
|
305
|
+
if (groupColumn !== undefined) {
|
|
306
|
+
parts.push(" and t.");
|
|
307
|
+
parts.push(quote(groupColumn.sql));
|
|
308
|
+
parts.push(" is not distinct from ");
|
|
309
|
+
parts.push(bind(moved.groupWire, groupColumn.dataType));
|
|
310
|
+
}
|
|
311
|
+
for (let index = 0;index < tenants.length; index += 1) {
|
|
312
|
+
const column = tenants[index];
|
|
313
|
+
if (column === undefined)
|
|
314
|
+
continue;
|
|
315
|
+
parts.push(" and t.");
|
|
316
|
+
parts.push(quote(column.sql));
|
|
317
|
+
parts.push(" is not distinct from ");
|
|
318
|
+
parts.push(bind(moved.tenants[index] ?? null, column.dataType));
|
|
319
|
+
}
|
|
320
|
+
return { text: parts.join(""), ...params.length > 0 ? { params } : {} };
|
|
321
|
+
}
|
|
322
|
+
function joinOn(group, tenants) {
|
|
323
|
+
const parts = [];
|
|
324
|
+
if (group !== undefined)
|
|
325
|
+
parts.push(`t.${quote(group.sql)} is not distinct from i.okm_g`);
|
|
326
|
+
for (let index = 0;index < tenants.length; index += 1) {
|
|
327
|
+
const column = tenants[index];
|
|
328
|
+
if (column === undefined)
|
|
329
|
+
continue;
|
|
330
|
+
parts.push(`t.${quote(column.sql)} is not distinct from i.okm_t${String(index)}`);
|
|
331
|
+
}
|
|
332
|
+
return parts.length === 0 ? "true" : parts.join(" and ");
|
|
333
|
+
}
|
|
334
|
+
function lockText(sqlName, tenants, group) {
|
|
335
|
+
return JSON.stringify([sqlName, tenants, group]);
|
|
336
|
+
}
|
|
337
|
+
function groupLock(keys) {
|
|
338
|
+
const ordered = [...keys].sort(compareText);
|
|
339
|
+
const values = ordered.map((_, index) => `($${String(index + 1)}::text)`).join(", ");
|
|
340
|
+
return {
|
|
341
|
+
text: `select pg_advisory_xact_lock(hashtextextended(k.okm_lock, 0::bigint)) from (select v.okm_lock from (values ${values}) as v(okm_lock) order by v.okm_lock) as k`,
|
|
342
|
+
params: ordered
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function compareText(left, right) {
|
|
346
|
+
if (left < right)
|
|
347
|
+
return -1;
|
|
348
|
+
if (left > right)
|
|
349
|
+
return 1;
|
|
350
|
+
return 0;
|
|
351
|
+
}
|
|
352
|
+
function wires(columns, row) {
|
|
353
|
+
return columns.map((column) => cellWire(column, row[column.field]));
|
|
354
|
+
}
|
|
355
|
+
function cellWire(column, value) {
|
|
356
|
+
if (value === undefined || value === null)
|
|
357
|
+
return null;
|
|
358
|
+
return column.encode(value);
|
|
359
|
+
}
|
|
360
|
+
function cell(column, value, bind) {
|
|
361
|
+
if (value === undefined)
|
|
362
|
+
return "default";
|
|
363
|
+
if (value === null)
|
|
364
|
+
return bind(null, column.dataType);
|
|
365
|
+
return bind(column.encode(value), column.dataType);
|
|
366
|
+
}
|
|
367
|
+
function decodeWire(column, value) {
|
|
368
|
+
if (value === null || value === undefined)
|
|
369
|
+
return null;
|
|
370
|
+
if (typeof value === "string") {
|
|
371
|
+
const decode = column.decode;
|
|
372
|
+
return column.encode(decode === undefined ? value : decode(value));
|
|
373
|
+
}
|
|
374
|
+
return column.encode(value);
|
|
375
|
+
}
|
|
376
|
+
function tenantColumns(table, fields) {
|
|
377
|
+
if (fields === undefined)
|
|
378
|
+
return [];
|
|
379
|
+
const columns = [];
|
|
380
|
+
for (const field of fields) {
|
|
381
|
+
const column = table.columns.get(field);
|
|
382
|
+
if (column !== undefined)
|
|
383
|
+
columns.push(column);
|
|
384
|
+
}
|
|
385
|
+
return columns;
|
|
386
|
+
}
|
|
387
|
+
function requiredColumn(table, field) {
|
|
388
|
+
const column = table.columns.get(field);
|
|
389
|
+
if (column === undefined)
|
|
390
|
+
fail2("OKM1120", `Table ${table.model.name} has no column ${field}.`);
|
|
391
|
+
return column;
|
|
392
|
+
}
|
|
393
|
+
function missing(table, id) {
|
|
394
|
+
throw new OkmError2("not_found", `move on ${table} could not find ${show(id)}.`, {
|
|
395
|
+
kind: "not_found",
|
|
396
|
+
table,
|
|
397
|
+
fix: { summary: "Pass the id of a row in this table." }
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
function show(id) {
|
|
401
|
+
if (typeof id === "string" || typeof id === "number")
|
|
402
|
+
return String(id);
|
|
403
|
+
return "that id";
|
|
404
|
+
}
|
|
405
|
+
function sameId(left, right) {
|
|
406
|
+
return left === right;
|
|
407
|
+
}
|
|
408
|
+
function count(value) {
|
|
409
|
+
if (typeof value === "number")
|
|
410
|
+
return value;
|
|
411
|
+
if (typeof value === "bigint")
|
|
412
|
+
return Number(value);
|
|
413
|
+
if (typeof value === "string" && value.length > 0)
|
|
414
|
+
return Number(value);
|
|
415
|
+
return 0;
|
|
416
|
+
}
|
|
417
|
+
function sink(parts, params) {
|
|
418
|
+
return {
|
|
419
|
+
text(value) {
|
|
420
|
+
parts.push(value);
|
|
421
|
+
},
|
|
422
|
+
param(encoded) {
|
|
423
|
+
params.push(encoded);
|
|
424
|
+
parts.push(`$${String(params.length)}`);
|
|
425
|
+
},
|
|
426
|
+
mark() {}
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
function callOptions(host) {
|
|
430
|
+
const limit = host.timeouts?.statement;
|
|
431
|
+
return limit === undefined ? undefined : { timeout: limit };
|
|
432
|
+
}
|
|
433
|
+
export {
|
|
434
|
+
insertAtEnd,
|
|
435
|
+
move
|
|
436
|
+
};
|
|
@@ -2,17 +2,20 @@ import {
|
|
|
2
2
|
checkout2,
|
|
3
3
|
describe2,
|
|
4
4
|
stream2,
|
|
5
|
+
runBatch2,
|
|
5
6
|
watchReserved2,
|
|
6
7
|
holdCheckout2,
|
|
7
8
|
holdListener2,
|
|
8
9
|
watchQuery2
|
|
9
|
-
} from "./
|
|
10
|
-
import"./
|
|
10
|
+
} from "./wcrheftc.js";
|
|
11
|
+
import"./35q0n9tz.js";
|
|
12
|
+
import"./cm3w0ywp.js";
|
|
11
13
|
export {
|
|
12
14
|
checkout2 as checkout,
|
|
13
15
|
describe2 as describe,
|
|
14
16
|
holdCheckout2 as holdCheckout,
|
|
15
17
|
holdListener2 as holdListener,
|
|
18
|
+
runBatch2 as runBatch,
|
|
16
19
|
stream2 as stream,
|
|
17
20
|
watchQuery2 as watchQuery,
|
|
18
21
|
watchReserved2 as watchReserved
|
|
@@ -39,7 +39,7 @@ async function refreshView(session, name, concurrently) {
|
|
|
39
39
|
throw error;
|
|
40
40
|
}
|
|
41
41
|
} catch (error) {
|
|
42
|
-
const { mapPostgresError } = await import("./
|
|
42
|
+
const { mapPostgresError } = await import("./63qtkrca.js");
|
|
43
43
|
const mapped = mapPostgresError(error, {
|
|
44
44
|
...host.http !== undefined ? { http: host.http } : {},
|
|
45
45
|
...host.includeValues === true ? { includeValues: true } : {},
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./
|
|
2
|
+
DriverError2
|
|
3
|
+
} from "./cm3w0ywp.js";
|
|
4
|
+
import {
|
|
5
|
+
noTimeout
|
|
6
|
+
} from "./q0cqt2sp.js";
|
|
4
7
|
import {
|
|
5
8
|
noticeBuffer,
|
|
6
|
-
WireSession
|
|
7
|
-
|
|
8
|
-
} from "./4az561fn.js";
|
|
9
|
+
WireSession
|
|
10
|
+
} from "./mtw6jz76.js";
|
|
9
11
|
import {
|
|
10
12
|
BUNSQL_CAPABILITIES,
|
|
11
13
|
driverErrors,
|
|
12
14
|
rejectClosed,
|
|
13
15
|
mapFailure,
|
|
14
16
|
runCall
|
|
15
|
-
} from "./
|
|
17
|
+
} from "./ae4j5f42.js";
|
|
16
18
|
|
|
17
19
|
// src/adapters/pg/bunsql.ts
|
|
18
|
-
import { SQL } from "bun";
|
|
20
|
+
import { SQL as BunSQL } from "bun";
|
|
21
|
+
var clientPools = new WeakSet;
|
|
22
|
+
function markClientPool(pool) {
|
|
23
|
+
clientPools.add(pool);
|
|
24
|
+
}
|
|
19
25
|
function open5(config) {
|
|
20
26
|
const max = config.max ?? 10;
|
|
21
27
|
const acquireMs = config.timeouts?.acquire;
|
|
@@ -25,7 +31,9 @@ function open5(config) {
|
|
|
25
31
|
const isClosed = () => closed;
|
|
26
32
|
const named = config.prepared === "named";
|
|
27
33
|
const parked = [];
|
|
28
|
-
|
|
34
|
+
let dropped = 0;
|
|
35
|
+
let closures = 0;
|
|
36
|
+
const sql = new BunSQL(config.url, {
|
|
29
37
|
max,
|
|
30
38
|
idleTimeout: 0,
|
|
31
39
|
maxLifetime: 0,
|
|
@@ -36,26 +44,53 @@ function open5(config) {
|
|
|
36
44
|
application_name: "okmodel",
|
|
37
45
|
...config.searchPath !== undefined ? { search_path: config.searchPath } : {}
|
|
38
46
|
},
|
|
39
|
-
...config.ssl !== undefined ? { tls: config.ssl } : {}
|
|
47
|
+
...config.ssl !== undefined ? { tls: config.ssl } : {},
|
|
48
|
+
onclose() {
|
|
49
|
+
dropped += 1;
|
|
50
|
+
closures += 1;
|
|
51
|
+
}
|
|
40
52
|
});
|
|
41
53
|
const root = new WireSession((text, params) => send2(sql, text, params), notices, isClosed, false, () => {
|
|
42
54
|
counters.busy += 1;
|
|
43
55
|
}, () => {
|
|
44
56
|
counters.busy = Math.max(0, counters.busy - 1);
|
|
45
57
|
});
|
|
46
|
-
const held = {
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
const held = {
|
|
59
|
+
sql,
|
|
60
|
+
parked,
|
|
61
|
+
acquireMs,
|
|
62
|
+
counters,
|
|
63
|
+
notices,
|
|
64
|
+
isClosed,
|
|
65
|
+
closures: () => closures
|
|
66
|
+
};
|
|
67
|
+
const run = (text, params, watch) => {
|
|
68
|
+
const sent = dropped;
|
|
69
|
+
return root.query(text, params, watch).catch((error) => import("./wvdjznah.js").then((mod) => mod.recover(sql, error, text, root.depth(), clientPools.has(pool), dropped > sent, () => root.query(text, params, watch))));
|
|
70
|
+
};
|
|
71
|
+
const afterDrop = (text, params, watch) => {
|
|
72
|
+
if (dropped === 0)
|
|
73
|
+
return run(text, params, watch);
|
|
74
|
+
const seen = dropped;
|
|
75
|
+
return import("./wvdjznah.js").then((mod) => mod.drainClosed(sql).then(() => {
|
|
76
|
+
if (dropped === seen)
|
|
77
|
+
dropped = 0;
|
|
78
|
+
return run(text, params, watch);
|
|
79
|
+
}));
|
|
80
|
+
};
|
|
81
|
+
const checkout = () => closed ? rejectClosed() : import("./wvdjznah.js").then((mod) => mod.checkout(held));
|
|
82
|
+
const pool = {
|
|
49
83
|
capabilities: BUNSQL_CAPABILITIES,
|
|
50
84
|
execute(text, params, options) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
85
|
+
const refused = noTimeout(options);
|
|
86
|
+
if (refused !== undefined)
|
|
87
|
+
return refused;
|
|
88
|
+
return runCall(closed, options, (watch) => releaseParked(parked).then(() => afterDrop(text, params, watch)));
|
|
56
89
|
},
|
|
57
90
|
async batch(statements, options) {
|
|
58
|
-
|
|
91
|
+
const refused = noTimeout(options);
|
|
92
|
+
if (refused !== undefined)
|
|
93
|
+
return refused;
|
|
59
94
|
const connection = await checkout();
|
|
60
95
|
try {
|
|
61
96
|
return await connection.batch(statements, options);
|
|
@@ -65,10 +100,13 @@ function open5(config) {
|
|
|
65
100
|
},
|
|
66
101
|
reserve: () => checkout(),
|
|
67
102
|
stream(text, params) {
|
|
68
|
-
return
|
|
103
|
+
return async function* () {
|
|
104
|
+
const { streamRows } = await import("./wvdjznah.js");
|
|
105
|
+
yield* streamRows(checkout, text, params);
|
|
106
|
+
}();
|
|
69
107
|
},
|
|
70
108
|
listen(channel, onNotify) {
|
|
71
|
-
return listen(channel, onNotify);
|
|
109
|
+
return import("./wvdjznah.js").then((mod) => mod.listen(sql, parked, closed, channel, onNotify));
|
|
72
110
|
},
|
|
73
111
|
stats: () => statsOf(counters, max),
|
|
74
112
|
async close() {
|
|
@@ -77,31 +115,29 @@ function open5(config) {
|
|
|
77
115
|
await sql.close();
|
|
78
116
|
}
|
|
79
117
|
};
|
|
80
|
-
|
|
81
|
-
return async function* () {
|
|
82
|
-
const connection = await checkout();
|
|
83
|
-
try {
|
|
84
|
-
yield* cursorStream((statement, values) => connection.execute(statement, values), text, params);
|
|
85
|
-
} finally {
|
|
86
|
-
await connection.release();
|
|
87
|
-
}
|
|
88
|
-
}();
|
|
89
|
-
}
|
|
90
|
-
async function listen(channel, onNotify) {
|
|
91
|
-
if (closed)
|
|
92
|
-
return rejectClosed();
|
|
93
|
-
await releaseParked(parked);
|
|
94
|
-
const subscription = await sql.listen(channel, onNotify);
|
|
95
|
-
return async () => {
|
|
96
|
-
await subscription.unlisten();
|
|
97
|
-
};
|
|
98
|
-
}
|
|
118
|
+
return pool;
|
|
99
119
|
}
|
|
100
120
|
function send2(sql, text, params) {
|
|
121
|
+
const refused = refuseInt8(params);
|
|
122
|
+
if (refused !== undefined)
|
|
123
|
+
return refused;
|
|
101
124
|
if (params === undefined || params.length === 0)
|
|
102
125
|
return sql.unsafe(text).raw();
|
|
103
126
|
return sql.unsafe(text, [...params]).raw();
|
|
104
127
|
}
|
|
128
|
+
function refuseInt8(params) {
|
|
129
|
+
if (params === undefined)
|
|
130
|
+
return;
|
|
131
|
+
for (const value of params) {
|
|
132
|
+
if (value === null || value.length < 19 || !/^-?(?:0|[1-9]\d*)$/.test(value))
|
|
133
|
+
continue;
|
|
134
|
+
const parsed = BigInt(value);
|
|
135
|
+
if (parsed > 9223372036854775807n || parsed < -9223372036854775808n) {
|
|
136
|
+
return Promise.reject(new DriverError2("bigint out of range", { sqlstate: "22003" }));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
105
141
|
async function reserve(sql, acquireMs, counters) {
|
|
106
142
|
counters.waiting += 1;
|
|
107
143
|
try {
|
|
@@ -151,4 +187,4 @@ function statsOf(counters, size) {
|
|
|
151
187
|
};
|
|
152
188
|
}
|
|
153
189
|
|
|
154
|
-
export { open5, send2, reserve, park };
|
|
190
|
+
export { markClientPool, open5, send2, reserve, park };
|
|
@@ -18,6 +18,7 @@ var FAMILIES = {
|
|
|
18
18
|
hasAnyKey: ["jsonb"],
|
|
19
19
|
path: ["json", "jsonb"],
|
|
20
20
|
matches: ["tsvector"],
|
|
21
|
+
relevance: ["tsvector"],
|
|
21
22
|
"json.set": ["json", "jsonb"],
|
|
22
23
|
"arr.append": ["array"],
|
|
23
24
|
"arr.remove": ["array"]
|
|
@@ -53,7 +54,7 @@ var ACCEPTED = {
|
|
|
53
54
|
jsonb: ["eq", "not", "contains", "containedBy", "hasKey", "hasAnyKey", "path", "json.set"],
|
|
54
55
|
json: ["eq", "not", "path", "json.set"],
|
|
55
56
|
range: ["eq", "not", "lt", "lte", "gt", "gte", "contains", "containedBy", "overlaps"],
|
|
56
|
-
tsvector: ["eq", "not", "matches"],
|
|
57
|
+
tsvector: ["eq", "not", "matches", "relevance"],
|
|
57
58
|
scalar: ["eq", "not", "lt", "lte", "gt", "gte", "between", "inList", "notIn", "inc"]
|
|
58
59
|
};
|
|
59
60
|
var SAFE_TYPE = /^[A-Za-z_][A-Za-z0-9_]*(\(\d+\))?(\[\])*$/;
|
|
@@ -81,7 +82,7 @@ function assertOperatorFits(column, name) {
|
|
|
81
82
|
if (families.includes(columnFamily(column.dataType)))
|
|
82
83
|
return;
|
|
83
84
|
const accepted = ACCEPTED[columnFamily(column.dataType)];
|
|
84
|
-
const search = name === "matches" && columnFamily(column.dataType) === "text" ? "
|
|
85
|
+
const search = (name === "matches" || name === "relevance") && columnFamily(column.dataType) === "text" ? " Search needs a column built for search, not a plain text column." : "";
|
|
85
86
|
throw new OkmError2("OKM1124", `Operator ${name} does not apply to ${column.dataType} column ${column.field}. Accepted operators: ${accepted.join(", ")}.${search}`, { fix: { summary: `Use one of: ${accepted.join(", ")}.` } });
|
|
86
87
|
}
|
|
87
88
|
function sqlType(dataType, column) {
|
|
@@ -110,7 +111,7 @@ function assertBoundText(value, role) {
|
|
|
110
111
|
}
|
|
111
112
|
function assertRegconfig(config) {
|
|
112
113
|
if (!REGCONFIG.test(config)) {
|
|
113
|
-
throw new OkmError2("OKM1122", `
|
|
114
|
+
throw new OkmError2("OKM1122", `Language ${config} is not a text search language. Pass a name such as english.`, { fix: { summary: "Pass a language name such as english." } });
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
117
|
function textArray(values, role) {
|