okmodel 0.7.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/dist/adapters/capabilities.d.ts +32 -0
- package/dist/adapters/failure.d.ts +1 -1
- package/dist/adapters/pg/bun-sql.d.ts +53 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +1 -1
- package/dist/adapters/pg/bunsql.d.ts +1 -1
- package/dist/adapters/pg/neon-extra.d.ts +18 -0
- package/dist/adapters/pg/neon.d.ts +104 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +1 -1
- package/dist/contracts/error.d.ts +1 -1
- package/dist/dialects/pg/fn/index.d.ts +39 -1
- package/dist/dialects/pg/fn/index.js +118 -26
- package/dist/dialects/pg/index.d.ts +2 -0
- package/dist/dialects/pg/index.js +393 -18
- package/dist/dialects/pg/introspect.d.ts +11 -0
- package/dist/dialects/pg/operators.d.ts +1 -1
- package/dist/dialects/pg/ops/fragment.d.ts +119 -0
- package/dist/dialects/pg/ops/lane.d.ts +49 -0
- package/dist/dialects/pg/view/client.d.ts +14 -6
- package/dist/dialects/pg/view/index.d.ts +73 -1
- package/dist/dialects/pg/view/index.js +156 -5
- package/dist/dialects/pg/view/scratch.d.ts +8 -5
- package/dist/runtime/otel.d.ts +105 -0
- package/dist/runtime/otel.js +97 -0
- package/dist/runtime/pg/bun.js +4 -4
- package/dist/runtime/pg/neon.d.ts +38 -0
- package/dist/runtime/pg/neon.js +64 -0
- package/dist/runtime/pg/pg.js +4 -4
- package/dist/runtime/pg/pglite.js +4 -4
- package/dist/runtime/pg/postgresjs.js +4 -4
- package/dist/runtime/plan.d.ts +1 -1
- package/dist/runtime/sql-fragment.d.ts +43 -0
- package/dist/runtime/tenancy/index.js +10 -10
- package/dist/runtime/topology.d.ts +1 -1
- package/dist/runtime/traits/index.js +15 -16
- package/dist/runtime/types.d.ts +15 -1
- package/dist/runtime/validate/index.js +4 -4
- package/dist/shared/{mtaszv5a.js → 0wrea3jq.js} +102 -4
- package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
- package/dist/shared/{w79hsckn.js → 14x60fbf.js} +5 -5
- package/dist/shared/{ek2wt2dz.js → 16kvjebh.js} +4 -4
- package/dist/shared/{svncdeh5.js → 195pzzzz.js} +8 -8
- package/dist/shared/{gzaveazc.js → 1d9q9cv2.js} +29 -2
- package/dist/shared/{jvd0mqag.js → 3449rcae.js} +5 -5
- package/dist/shared/{14vx95q4.js → 35q0n9tz.js} +7 -7
- package/dist/shared/3bb7wsqt.js +99 -0
- package/dist/shared/{y6njgyda.js → 3t6kw83m.js} +2 -2
- package/dist/shared/{81ebdx9p.js → 4m6hskg8.js} +4 -4
- package/dist/shared/{xhfsfkgk.js → 4vbf83xx.js} +9 -2
- package/dist/shared/{bg3rym3g.js → 63f4ksbz.js} +2 -2
- package/dist/shared/{pt94kz7f.js → 6m78c8ss.js} +1 -1
- package/dist/shared/{5e3tf63j.js → 760ppr76.js} +14 -6
- package/dist/shared/{zm0ptry0.js → 7ghwamrf.js} +1 -1
- package/dist/shared/{xnxsed62.js → 9dr2qnx7.js} +14 -14
- package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
- package/dist/shared/{q5c6ngn3.js → a62rb2da.js} +1 -1
- package/dist/shared/{kb2sdhfb.js → ae4j5f42.js} +17 -1
- package/dist/shared/agsfb86s.js +233 -0
- package/dist/shared/{7k9grvf6.js → b6d6p0zc.js} +5 -5
- package/dist/shared/{tbrvgw6z.js → bah9nbg3.js} +17 -16
- package/dist/shared/{5fe3kbsh.js → bnby0esn.js} +1 -1
- package/dist/shared/bsek72fg.js +225 -0
- package/dist/shared/{1w508jbr.js → bxas03mq.js} +21 -17
- package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
- package/dist/shared/{tsvww22q.js → dpc2r7rb.js} +7 -7
- package/dist/shared/{vb6qfyve.js → e8zyaqvj.js} +2 -2
- package/dist/shared/{hyh73qk6.js → ecn8mfdq.js} +5 -5
- package/dist/shared/{gs74dbj5.js → f4jy1j7x.js} +27 -14
- package/dist/shared/{ttsqgp4p.js → fjpnhqan.js} +2 -2
- package/dist/shared/{xjk7hnn5.js → g5yc06ka.js} +2 -2
- package/dist/shared/{w72kgg4q.js → hfqmpasr.js} +6 -6
- package/dist/shared/{kr0jzbw2.js → hm5f8jby.js} +7 -7
- package/dist/shared/{dkxgzaqd.js → hqpxf4a4.js} +1 -1
- package/dist/shared/{cn957f8d.js → jebgrkeq.js} +3 -3
- package/dist/shared/{wa07eas9.js → jp36k7dp.js} +11 -11
- package/dist/shared/jx2m62cs.js +96 -0
- package/dist/shared/{sfz1ksn6.js → k86n8vq3.js} +2 -2
- package/dist/shared/{67txcrcw.js → kgwp4jdd.js} +4 -4
- package/dist/shared/{8skf0cam.js → kj9d8maq.js} +1 -1
- package/dist/shared/{aytqh5y2.js → m4xff2a6.js} +2 -2
- package/dist/shared/{zp9fmend.js → mfedzr74.js} +4 -4
- package/dist/shared/{ax7qv55k.js → mkrn359n.js} +60 -11
- package/dist/shared/{m6p12kbr.js → mnvjvqyp.js} +10 -10
- package/dist/shared/{1qa0qajz.js → mtw6jz76.js} +1 -1
- package/dist/shared/{1est4ezg.js → n05z9nwz.js} +3 -3
- package/dist/shared/{pbp1ss85.js → n0jmpgj1.js} +2 -2
- package/dist/shared/{ktz42yez.js → n41w4fbz.js} +5 -5
- package/dist/shared/{n816peh1.js → n454kcnw.js} +1 -1
- package/dist/shared/n7kg8mmx.js +61 -0
- package/dist/shared/{g6evj1j3.js → needfe47.js} +1 -1
- package/dist/shared/{2shdbn8q.js → njga14v4.js} +9 -9
- package/dist/shared/{vqrjpcqn.js → nmnsgj7x.js} +1 -1
- package/dist/shared/{b5pftnn2.js → p3xbdcvt.js} +14 -18
- package/dist/shared/{te5as7z7.js → p5nh3r8q.js} +3 -3
- package/dist/shared/{p6qc5gcp.js → pan0370z.js} +6 -6
- package/dist/shared/{79dt02vc.js → q0cqt2sp.js} +1 -1
- package/dist/shared/{5v3xf80k.js → qd9hhd8f.js} +1 -1
- package/dist/shared/{bm22fvzr.js → qfw14tna.js} +2 -2
- package/dist/shared/{9s0ypp87.js → sjk86yrx.js} +1 -1
- package/dist/shared/{3v7t1yrv.js → th3be82n.js} +2 -2
- package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
- package/dist/shared/{vczs8gd4.js → v1wad97q.js} +2 -2
- package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
- package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
- package/dist/shared/{bz84tkzm.js → wcrheftc.js} +2 -2
- package/dist/shared/{ab9gmbwy.js → wvdjznah.js} +5 -5
- package/dist/shared/{7mnme5tn.js → wz2a78mp.js} +1 -1
- package/dist/shared/{9y3mmmh1.js → xfhe73sb.js} +1 -1
- package/dist/shared/{je4axnm8.js → z581d7ny.js} +2 -2
- package/dist/shared/{x933k9a3.js → zbqbmmrp.js} +10 -10
- package/dist/shared/{rs73fca9.js → zgex00fd.js} +6 -6
- package/dist/shared/{jznfax0y.js → zq1he88x.js} +4 -4
- 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/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/tooling/shared/ep8zh3bk.js +6 -0
- 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 +14 -2
- package/dist/shared/y34a8714.js +0 -150
- package/dist/shared/zy8r7qvz.js +0 -116
- package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
- package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DriverError2,
|
|
3
|
+
isConnectionLost
|
|
4
|
+
} from "./f9mphxej.js";
|
|
5
|
+
import {
|
|
6
|
+
armDriverError2,
|
|
7
|
+
send3,
|
|
8
|
+
connectClient2
|
|
9
|
+
} from "./417zdsk7.js";
|
|
10
|
+
import {
|
|
11
|
+
resetSession2
|
|
12
|
+
} from "./4d2w25vw.js";
|
|
13
|
+
import {
|
|
14
|
+
cursorStream
|
|
15
|
+
} from "./7kms6fvj.js";
|
|
16
|
+
import {
|
|
17
|
+
WireSession
|
|
18
|
+
} from "./yw30vnq2.js";
|
|
19
|
+
import {
|
|
20
|
+
rejectClosed,
|
|
21
|
+
runCall
|
|
22
|
+
} from "./xhrnjch9.js";
|
|
23
|
+
|
|
24
|
+
// src/adapters/pg/nodepostgres-extra.ts
|
|
25
|
+
async function checkout(held) {
|
|
26
|
+
const { pool, counters, named, isClosed } = held;
|
|
27
|
+
if (isClosed())
|
|
28
|
+
return rejectClosed();
|
|
29
|
+
const client = await connectClient2(pool, held.acquireMs, counters);
|
|
30
|
+
counters.reserved += 1;
|
|
31
|
+
let lost = false;
|
|
32
|
+
const onError = () => {
|
|
33
|
+
lost = true;
|
|
34
|
+
};
|
|
35
|
+
const events = client;
|
|
36
|
+
events.on("error", onError);
|
|
37
|
+
const local = new Set;
|
|
38
|
+
const session = new WireSession((text, params) => {
|
|
39
|
+
const pending = send3(client, text, params, named, client);
|
|
40
|
+
const guarded = pending.catch((error) => {
|
|
41
|
+
if (isConnectionLost(error) || lost) {
|
|
42
|
+
lost = true;
|
|
43
|
+
if (isConnectionLost(error))
|
|
44
|
+
throw error;
|
|
45
|
+
throw Object.assign(new DriverError2("CONNECTION_CLOSED", { cause: error }), {
|
|
46
|
+
code: "CONNECTION_CLOSED"
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
});
|
|
51
|
+
guarded.cancel = () => {
|
|
52
|
+
pending.cancel?.();
|
|
53
|
+
};
|
|
54
|
+
return guarded;
|
|
55
|
+
}, held.notices, isClosed, true, () => {
|
|
56
|
+
counters.reservedBusy += 1;
|
|
57
|
+
}, () => {
|
|
58
|
+
counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
|
|
59
|
+
}, local);
|
|
60
|
+
const guard = (run) => lost ? rejectClosed() : run();
|
|
61
|
+
let released = false;
|
|
62
|
+
return {
|
|
63
|
+
execute: (text, params, options) => guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch))),
|
|
64
|
+
batch: (statements, options) => guard(() => runCall(isClosed(), options, async (watch) => {
|
|
65
|
+
const { runAtomicBatch } = await import("./3rrw5w8f.js");
|
|
66
|
+
return runAtomicBatch(session, statements, watch);
|
|
67
|
+
})),
|
|
68
|
+
cancel() {
|
|
69
|
+
session.cancel();
|
|
70
|
+
},
|
|
71
|
+
async release() {
|
|
72
|
+
if (released)
|
|
73
|
+
return;
|
|
74
|
+
released = true;
|
|
75
|
+
try {
|
|
76
|
+
if (!lost)
|
|
77
|
+
await reset(session, client);
|
|
78
|
+
} finally {
|
|
79
|
+
counters.reserved = Math.max(0, counters.reserved - 1);
|
|
80
|
+
events.removeListener("error", onError);
|
|
81
|
+
client.release(lost);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async function reset(session, client) {
|
|
87
|
+
await resetSession2(session.depth(), (text) => client.query(text));
|
|
88
|
+
}
|
|
89
|
+
async function listen(held, channel, onNotify) {
|
|
90
|
+
const { pool, counters } = held;
|
|
91
|
+
const client = await connectClient2(pool, held.acquireMs, counters);
|
|
92
|
+
counters.reserved += 1;
|
|
93
|
+
const quoted = quoteIdent(channel);
|
|
94
|
+
const onNotification = (message) => {
|
|
95
|
+
if (message.channel === channel)
|
|
96
|
+
onNotify(message.payload ?? "");
|
|
97
|
+
};
|
|
98
|
+
client.on("notification", onNotification);
|
|
99
|
+
let released = false;
|
|
100
|
+
const release = (dead) => {
|
|
101
|
+
if (released)
|
|
102
|
+
return;
|
|
103
|
+
released = true;
|
|
104
|
+
client.removeListener("notification", onNotification);
|
|
105
|
+
client.removeListener("error", release);
|
|
106
|
+
counters.reserved = Math.max(0, counters.reserved - 1);
|
|
107
|
+
client.release(Boolean(dead));
|
|
108
|
+
};
|
|
109
|
+
armDriverError2(client, release);
|
|
110
|
+
try {
|
|
111
|
+
await client.query(`LISTEN ${quoted}`);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
release(false);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
return async () => {
|
|
117
|
+
if (released)
|
|
118
|
+
return;
|
|
119
|
+
try {
|
|
120
|
+
await client.query(`UNLISTEN ${quoted}`);
|
|
121
|
+
} finally {
|
|
122
|
+
release(false);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function streamRows(checkout, text, params) {
|
|
127
|
+
return async function* () {
|
|
128
|
+
const connection = await checkout();
|
|
129
|
+
try {
|
|
130
|
+
yield* cursorStream((statement, values) => connection.execute(statement, values), text, params);
|
|
131
|
+
} finally {
|
|
132
|
+
await connection.release();
|
|
133
|
+
}
|
|
134
|
+
}();
|
|
135
|
+
}
|
|
136
|
+
function quoteIdent(name) {
|
|
137
|
+
return `"${name.replaceAll('"', '""')}"`;
|
|
138
|
+
}
|
|
139
|
+
export {
|
|
140
|
+
checkout,
|
|
141
|
+
listen,
|
|
142
|
+
streamRows
|
|
143
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
open3
|
|
3
|
+
} from "./p7f08ktn.js";
|
|
4
|
+
import {
|
|
5
|
+
createClient
|
|
6
|
+
} from "./mtrqn2hn.js";
|
|
7
|
+
|
|
8
|
+
// src/runtime/pg/postgresjs.ts
|
|
9
|
+
function connect(target, options) {
|
|
10
|
+
if (typeof target === "object" && !isPool(target)) {
|
|
11
|
+
return import("./2wtvc7rw.js").then((mod) => mod.default(target, options, open3));
|
|
12
|
+
}
|
|
13
|
+
const owned = !isPool(target);
|
|
14
|
+
const pool = isPool(target) ? target : open3({
|
|
15
|
+
url: target,
|
|
16
|
+
...options.max !== undefined ? { max: options.max } : {},
|
|
17
|
+
...options.timeouts !== undefined ? { timeouts: options.timeouts } : {},
|
|
18
|
+
...options.prepared !== undefined ? { prepared: options.prepared } : {},
|
|
19
|
+
...options.searchPath !== undefined ? { searchPath: options.searchPath } : {},
|
|
20
|
+
...options.ssl !== undefined ? { ssl: options.ssl } : {}
|
|
21
|
+
});
|
|
22
|
+
return createClient(options.schema, pool, {
|
|
23
|
+
ownsPool: owned,
|
|
24
|
+
http: options.errors?.http,
|
|
25
|
+
includeValues: options.errors?.includeValues,
|
|
26
|
+
logger: options.logger,
|
|
27
|
+
signal: options.signal,
|
|
28
|
+
timeout: options.timeout,
|
|
29
|
+
timeouts: options.timeouts,
|
|
30
|
+
hookm: options.hookm,
|
|
31
|
+
catalog: options.catalog,
|
|
32
|
+
catalogDir: options.catalogDir,
|
|
33
|
+
requireMeta: options.requireMeta,
|
|
34
|
+
generators: options.generators
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function isPool(target) {
|
|
38
|
+
return typeof target === "object" && "execute" in target && "capabilities" in target;
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
connect
|
|
42
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeRows,
|
|
3
|
+
readHandle,
|
|
4
|
+
readCall,
|
|
5
|
+
attachHttp
|
|
6
|
+
} from "./mtrqn2hn.js";
|
|
7
|
+
import {
|
|
8
|
+
OkmError,
|
|
9
|
+
throwNamed,
|
|
10
|
+
fail2
|
|
11
|
+
} from "./f9mphxej.js";
|
|
12
|
+
|
|
13
|
+
// src/runtime/lock.ts
|
|
14
|
+
var LOCKS = ["update", "share"];
|
|
15
|
+
var WAITS = ["nowait", "skip"];
|
|
16
|
+
function shown(value) {
|
|
17
|
+
return typeof value === "string" ? value : JSON.stringify(value) ?? "undefined";
|
|
18
|
+
}
|
|
19
|
+
function build(session, table, options, mods, view) {
|
|
20
|
+
try {
|
|
21
|
+
return plan(session, table, options, mods, view);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw error instanceof OkmError ? attachHttp(session.http, error) : error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function plan(session, table, options, mods, view) {
|
|
27
|
+
const { lock, wait, ...rest } = options;
|
|
28
|
+
const forced = session.pool.forcedRoute;
|
|
29
|
+
if (rest.route === "replica" || forced === "replica") {
|
|
30
|
+
throw new OkmError("OKM1840", "A locking read needs the primary.", {
|
|
31
|
+
fix: {
|
|
32
|
+
summary: "Run the operation on the primary. Writes, batch, locks, and tx() never go to a replica."
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (lock === "skip") {
|
|
37
|
+
fail2("OKM1120", 'lock: "skip" claims rows on update. A read uses lock: "update" and wait: "skip".', 'Pass lock: "update" and wait: "skip" inside tx(). An update can claim rows on its own.');
|
|
38
|
+
}
|
|
39
|
+
if (session.tx === undefined) {
|
|
40
|
+
throw new OkmError("OKM1830", "A row lock needs a transaction. find was called outside tx().", {
|
|
41
|
+
fix: { summary: "Move the find into tx(): the lock lasts until the transaction ends." }
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (lock === undefined)
|
|
45
|
+
fail2("OKM1121", "wait needs lock: pass lock: update or lock: share.");
|
|
46
|
+
if (typeof lock !== "string" || !LOCKS.includes(lock)) {
|
|
47
|
+
throwNamed("OKM1120", shown(lock), LOCKS, `lock must be one of: ${LOCKS.join(", ")}.`);
|
|
48
|
+
}
|
|
49
|
+
if (wait !== undefined && (typeof wait !== "string" || !WAITS.includes(wait))) {
|
|
50
|
+
throwNamed("OKM1120", shown(wait), WAITS, `wait must be one of: ${WAITS.join(", ")}.`);
|
|
51
|
+
}
|
|
52
|
+
const clause = ` for ${lock} of t${wait === undefined ? "" : wait === "skip" ? " skip locked" : " nowait"}`;
|
|
53
|
+
const call = {
|
|
54
|
+
...readCall("find", table, rest, mods.all, session.scope, session.schema.model[table], session.schema, view),
|
|
55
|
+
tail(sink) {
|
|
56
|
+
sink.text(clause);
|
|
57
|
+
sink.mark(`lock:${clause}`);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return readHandle(session, table, call, mods, (compiled, rows) => decodeRows(compiled, rows, table));
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
build
|
|
64
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runWrite
|
|
3
|
+
} from "./n4jqhpqz.js";
|
|
4
|
+
import {
|
|
5
|
+
refuseUncancellableTimeout
|
|
6
|
+
} from "./zhwnfyb2.js";
|
|
7
|
+
import {
|
|
8
|
+
withHttp,
|
|
9
|
+
settleCall
|
|
10
|
+
} from "./mtrqn2hn.js";
|
|
11
|
+
import {
|
|
12
|
+
OkmError,
|
|
13
|
+
rejectKeys,
|
|
14
|
+
isRecord,
|
|
15
|
+
fail2
|
|
16
|
+
} from "./f9mphxej.js";
|
|
17
|
+
|
|
18
|
+
// src/runtime/batch.ts
|
|
19
|
+
async function batch(session, ops, options, replica) {
|
|
20
|
+
try {
|
|
21
|
+
if (replica !== undefined) {
|
|
22
|
+
throw new OkmError("OKM1840", "batch() needs the primary. .replica() is not allowed on a batch.", withHttp(session.http, {
|
|
23
|
+
fix: { summary: "Remove .replica(). A batch always runs on the primary." }
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
if (!Array.isArray(ops))
|
|
27
|
+
fail2("OKM1121", "batch expects a list of write operations.");
|
|
28
|
+
const record = options ?? {};
|
|
29
|
+
if (!isRecord(record))
|
|
30
|
+
fail2("OKM1121", "batch options must be an object.");
|
|
31
|
+
rejectKeys(record, ["signal", "timeout"], "batch");
|
|
32
|
+
await refuseUncancellableTimeout(session.pool, typeof record["timeout"] === "number" ? record["timeout"] : undefined);
|
|
33
|
+
for (const op of ops) {
|
|
34
|
+
if (typeof op === "object" && op !== null && op["~refresh"] === true) {
|
|
35
|
+
fail2("OKM1121", "batch does not take refresh(). Await refresh() on its own. It is one statement and cannot share the batch.");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const prepared = [];
|
|
39
|
+
for (const op of ops) {
|
|
40
|
+
const plan = typeof op === "object" && op !== null ? op["~plan"] : undefined;
|
|
41
|
+
if (plan === undefined) {
|
|
42
|
+
fail2("OKM1121", "batch takes write operations: insert, update, delete, and archive. Pass them without awaiting.");
|
|
43
|
+
}
|
|
44
|
+
const item = await plan();
|
|
45
|
+
if (item.checked === "parent") {
|
|
46
|
+
throw new OkmError("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()." } });
|
|
47
|
+
}
|
|
48
|
+
if (item.checked !== undefined) {
|
|
49
|
+
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().");
|
|
50
|
+
}
|
|
51
|
+
prepared.push(item);
|
|
52
|
+
}
|
|
53
|
+
return await run(session, prepared, record);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return settleCall(session, error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function run(session, prepared, options) {
|
|
59
|
+
await session.connected;
|
|
60
|
+
const statements = [];
|
|
61
|
+
const starts = [];
|
|
62
|
+
for (const item of prepared) {
|
|
63
|
+
starts.push(statements.length);
|
|
64
|
+
statements.push(...item.statements);
|
|
65
|
+
}
|
|
66
|
+
if (statements.length === 0)
|
|
67
|
+
return prepared.map((item) => item.finish([]));
|
|
68
|
+
let results;
|
|
69
|
+
try {
|
|
70
|
+
results = await runWrite(session, statements, call(options), true);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
throw at(error, starts);
|
|
73
|
+
}
|
|
74
|
+
const extra = await recover(session, prepared, results, starts, options);
|
|
75
|
+
return prepared.map((item, index) => {
|
|
76
|
+
const from = starts[index] ?? 0;
|
|
77
|
+
const slice = results.slice(from, from + item.statements.length);
|
|
78
|
+
const more = extra.get(index);
|
|
79
|
+
return item.finish(more === undefined ? slice : slice.concat(more));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async function recover(session, prepared, results, starts, options) {
|
|
83
|
+
const pending = [];
|
|
84
|
+
for (let index = 0;index < prepared.length; index += 1) {
|
|
85
|
+
const item = prepared[index];
|
|
86
|
+
if (item?.follow === undefined)
|
|
87
|
+
continue;
|
|
88
|
+
const from = starts[index] ?? 0;
|
|
89
|
+
const more = item.follow(results.slice(from, from + item.statements.length));
|
|
90
|
+
if (more.length === 0)
|
|
91
|
+
continue;
|
|
92
|
+
pending.push({ index, statements: more });
|
|
93
|
+
}
|
|
94
|
+
const found = new Map;
|
|
95
|
+
if (pending.length === 0)
|
|
96
|
+
return found;
|
|
97
|
+
const flat = [];
|
|
98
|
+
const extraStarts = [];
|
|
99
|
+
for (const item of pending) {
|
|
100
|
+
extraStarts.push(flat.length);
|
|
101
|
+
flat.push(...item.statements);
|
|
102
|
+
}
|
|
103
|
+
let ran;
|
|
104
|
+
try {
|
|
105
|
+
ran = await runWrite(session, flat, call(options), true);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
throw mapExtra(error, pending, extraStarts);
|
|
108
|
+
}
|
|
109
|
+
for (let index = 0;index < pending.length; index += 1) {
|
|
110
|
+
const item = pending[index];
|
|
111
|
+
if (item === undefined)
|
|
112
|
+
continue;
|
|
113
|
+
const from = extraStarts[index] ?? 0;
|
|
114
|
+
found.set(item.index, ran.slice(from, extraStarts[index + 1] ?? ran.length));
|
|
115
|
+
}
|
|
116
|
+
return found;
|
|
117
|
+
}
|
|
118
|
+
function mapExtra(error, pending, extraStarts) {
|
|
119
|
+
const failed = error?.batchIndex;
|
|
120
|
+
const move = error?.at;
|
|
121
|
+
if (typeof failed !== "number" || typeof move !== "function")
|
|
122
|
+
return error;
|
|
123
|
+
let slot = 0;
|
|
124
|
+
while (slot + 1 < extraStarts.length && (extraStarts[slot + 1] ?? Infinity) <= failed)
|
|
125
|
+
slot += 1;
|
|
126
|
+
const op = pending[slot]?.index ?? slot;
|
|
127
|
+
return op === failed ? error : move.call(error, op);
|
|
128
|
+
}
|
|
129
|
+
function call(options) {
|
|
130
|
+
const { signal, timeout } = options;
|
|
131
|
+
if (signal === undefined && timeout === undefined)
|
|
132
|
+
return;
|
|
133
|
+
return {
|
|
134
|
+
...signal !== undefined ? { signal } : {},
|
|
135
|
+
...typeof timeout === "number" ? { timeout } : {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function at(error, starts) {
|
|
139
|
+
const failed = error?.batchIndex;
|
|
140
|
+
const move = error?.at;
|
|
141
|
+
if (typeof failed !== "number" || typeof move !== "function")
|
|
142
|
+
return error;
|
|
143
|
+
let index = 0;
|
|
144
|
+
while (index + 1 < starts.length && (starts[index + 1] ?? Infinity) <= failed)
|
|
145
|
+
index += 1;
|
|
146
|
+
return index === failed ? error : move.call(error, index);
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
batch
|
|
150
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
quote,
|
|
3
|
+
fail2
|
|
4
|
+
} from "./f9mphxej.js";
|
|
5
|
+
|
|
6
|
+
// src/runtime/sort.ts
|
|
7
|
+
function insertAtEnd(table, columns, rows, group, tenantFields) {
|
|
8
|
+
const position = requiredColumn(table, "position");
|
|
9
|
+
const groupColumn = group === undefined ? undefined : requiredColumn(table, group);
|
|
10
|
+
const tenants = tenantColumns(table, tenantFields);
|
|
11
|
+
const planned = [];
|
|
12
|
+
const countOf = new Map;
|
|
13
|
+
const firstOf = new Map;
|
|
14
|
+
for (const row of rows) {
|
|
15
|
+
if (groupColumn !== undefined && !Object.hasOwn(row, groupColumn.field)) {
|
|
16
|
+
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.");
|
|
17
|
+
}
|
|
18
|
+
const key = lockText(table.model.sql, wires(tenants, row), groupColumn === undefined ? null : cellWire(groupColumn, row[groupColumn.field]));
|
|
19
|
+
if (!firstOf.has(key))
|
|
20
|
+
firstOf.set(key, row);
|
|
21
|
+
const n = (countOf.get(key) ?? 0) + 1;
|
|
22
|
+
countOf.set(key, n);
|
|
23
|
+
planned.push({ key, n, row });
|
|
24
|
+
}
|
|
25
|
+
const params = [];
|
|
26
|
+
const bind = (wire, dataType) => {
|
|
27
|
+
params.push(wire);
|
|
28
|
+
return `$${String(params.length)}::${dataType}`;
|
|
29
|
+
};
|
|
30
|
+
const slotOf = new Map;
|
|
31
|
+
for (const key of firstOf.keys())
|
|
32
|
+
slotOf.set(key, bind(key, "text"));
|
|
33
|
+
const baseRows = [];
|
|
34
|
+
for (const [key, row] of firstOf) {
|
|
35
|
+
const parts = [slotOf.get(key) ?? bind(key, "text")];
|
|
36
|
+
if (groupColumn !== undefined)
|
|
37
|
+
parts.push(bind(cellWire(groupColumn, row[groupColumn.field]), groupColumn.dataType));
|
|
38
|
+
for (const column of tenants)
|
|
39
|
+
parts.push(bind(cellWire(column, row[column.field]), column.dataType));
|
|
40
|
+
baseRows.push(`(${parts.join(", ")})`);
|
|
41
|
+
}
|
|
42
|
+
const baseNames = ["okm_lock"];
|
|
43
|
+
if (groupColumn !== undefined)
|
|
44
|
+
baseNames.push("okm_g");
|
|
45
|
+
for (let index = 0;index < tenants.length; index += 1)
|
|
46
|
+
baseNames.push(`okm_t${String(index)}`);
|
|
47
|
+
const lists = planned.map((item) => {
|
|
48
|
+
const slot = slotOf.get(item.key) ?? bind(item.key, "text");
|
|
49
|
+
const slots = columns.map((column) => cell(column, item.row[column.field], bind));
|
|
50
|
+
slots.push(`((select b.pos from base b where b.okm_lock = ${slot}) + ${String(item.n)})::integer`);
|
|
51
|
+
return `(${slots.join(", ")})`;
|
|
52
|
+
});
|
|
53
|
+
const insertColumns = [...columns.map((column) => quote(column.sql)), quote(position.sql)];
|
|
54
|
+
const text = [
|
|
55
|
+
"with base as (",
|
|
56
|
+
"select i.okm_lock, coalesce(max(t.",
|
|
57
|
+
quote(position.sql),
|
|
58
|
+
"), 0) as pos from (values ",
|
|
59
|
+
baseRows.join(", "),
|
|
60
|
+
") as i(",
|
|
61
|
+
baseNames.join(", "),
|
|
62
|
+
") left join ",
|
|
63
|
+
quote(table.model.sql),
|
|
64
|
+
" as t on ",
|
|
65
|
+
joinOn(groupColumn, tenants),
|
|
66
|
+
" group by i.okm_lock",
|
|
67
|
+
") insert into ",
|
|
68
|
+
quote(table.model.sql),
|
|
69
|
+
" (",
|
|
70
|
+
insertColumns.join(", "),
|
|
71
|
+
") values ",
|
|
72
|
+
lists.join(", ")
|
|
73
|
+
].join("");
|
|
74
|
+
return { lock: groupLock([...firstOf.keys()]), text, params };
|
|
75
|
+
}
|
|
76
|
+
function joinOn(group, tenants) {
|
|
77
|
+
const parts = [];
|
|
78
|
+
if (group !== undefined)
|
|
79
|
+
parts.push(`t.${quote(group.sql)} is not distinct from i.okm_g`);
|
|
80
|
+
for (let index = 0;index < tenants.length; index += 1) {
|
|
81
|
+
const column = tenants[index];
|
|
82
|
+
if (column === undefined)
|
|
83
|
+
continue;
|
|
84
|
+
parts.push(`t.${quote(column.sql)} is not distinct from i.okm_t${String(index)}`);
|
|
85
|
+
}
|
|
86
|
+
return parts.length === 0 ? "true" : parts.join(" and ");
|
|
87
|
+
}
|
|
88
|
+
function lockText(sqlName, tenants, group) {
|
|
89
|
+
return JSON.stringify([sqlName, tenants, group]);
|
|
90
|
+
}
|
|
91
|
+
function groupLock(keys) {
|
|
92
|
+
const ordered = [...keys].sort(compareText);
|
|
93
|
+
const values = ordered.map((_, index) => `($${String(index + 1)}::text)`).join(", ");
|
|
94
|
+
return {
|
|
95
|
+
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`,
|
|
96
|
+
params: ordered
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function compareText(left, right) {
|
|
100
|
+
if (left < right)
|
|
101
|
+
return -1;
|
|
102
|
+
if (left > right)
|
|
103
|
+
return 1;
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
function wires(columns, row) {
|
|
107
|
+
return columns.map((column) => cellWire(column, row[column.field]));
|
|
108
|
+
}
|
|
109
|
+
function cellWire(column, value) {
|
|
110
|
+
if (value === undefined || value === null)
|
|
111
|
+
return null;
|
|
112
|
+
return column.encode(value);
|
|
113
|
+
}
|
|
114
|
+
function cell(column, value, bind) {
|
|
115
|
+
if (value === undefined)
|
|
116
|
+
return "default";
|
|
117
|
+
if (value === null)
|
|
118
|
+
return bind(null, column.dataType);
|
|
119
|
+
return bind(column.encode(value), column.dataType);
|
|
120
|
+
}
|
|
121
|
+
function tenantColumns(table, fields) {
|
|
122
|
+
if (fields === undefined)
|
|
123
|
+
return [];
|
|
124
|
+
const columns = [];
|
|
125
|
+
for (const field of fields) {
|
|
126
|
+
const column = table.columns.get(field);
|
|
127
|
+
if (column !== undefined)
|
|
128
|
+
columns.push(column);
|
|
129
|
+
}
|
|
130
|
+
return columns;
|
|
131
|
+
}
|
|
132
|
+
function requiredColumn(table, field) {
|
|
133
|
+
const column = table.columns.get(field);
|
|
134
|
+
if (column === undefined)
|
|
135
|
+
fail2("OKM1120", `Table ${table.model.name} has no column ${field}.`);
|
|
136
|
+
return column;
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
insertAtEnd
|
|
140
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError
|
|
3
|
+
} from "./f9mphxej.js";
|
|
4
|
+
|
|
5
|
+
// src/runtime/validate/closed.ts
|
|
6
|
+
var VALIDATION_NOT_IMPORTED = "Validation is enabled but `okmodel/validate` was not imported.";
|
|
7
|
+
var VALIDATION_NOT_IMPORTED_FIX = 'Import "okmodel/validate" before schema().';
|
|
8
|
+
function refuseMissingValidation() {
|
|
9
|
+
throw new OkmError("OKM1201", VALIDATION_NOT_IMPORTED, {
|
|
10
|
+
fix: { summary: VALIDATION_NOT_IMPORTED_FIX }
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
refuseMissingValidation
|
|
15
|
+
};
|