okmodel 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -1131
- package/dist/adapters/capabilities.d.ts +3 -0
- package/dist/adapters/failure.d.ts +13 -2
- package/dist/adapters/lazy-errors.d.ts +22 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
- package/dist/adapters/pg/bunsql.d.ts +14 -1
- package/dist/adapters/pg/cursor.d.ts +17 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +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/dialects/pg/floor.d.ts +68 -0
- package/dist/dialects/pg/index.d.ts +6 -1
- package/dist/dialects/pg/index.js +49 -159
- 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/inc.d.ts +2 -2
- package/dist/dialects/pg/ops/matches.d.ts +9 -12
- package/dist/dialects/pg/ops/relevance.d.ts +13 -0
- package/dist/dialects/pg/ops/search-query.d.ts +22 -0
- package/dist/dialects/pg/ops/window.d.ts +103 -0
- package/dist/dialects/pg/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/index.js +1 -1
- 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/page.d.ts +4 -1
- package/dist/runtime/pg/bun.js +12 -6
- 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/sync.d.ts +70 -0
- package/dist/runtime/tenancy/index.js +7 -5
- package/dist/runtime/text-search.d.ts +20 -0
- package/dist/runtime/traits/index.d.ts +80 -0
- package/dist/runtime/traits/index.js +175 -11
- package/dist/runtime/tree.d.ts +38 -0
- package/dist/runtime/types.d.ts +218 -22
- package/dist/runtime/validate/index.js +2 -2
- 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/{wkme6tep.js → 14vx95q4.js} +8 -16
- package/dist/shared/1est4ezg.js +313 -0
- package/dist/shared/{4az561fn.js → 1qa0qajz.js} +8 -23
- package/dist/shared/{2cg3wnxc.js → 1w508jbr.js} +593 -130
- package/dist/shared/2c13q96h.js +18 -0
- package/dist/shared/{b4v57v3x.js → 2d3xq4ps.js} +2 -2
- package/dist/shared/{1nw1f3vs.js → 2shdbn8q.js} +7 -7
- package/dist/shared/3v7t1yrv.js +208 -0
- package/dist/shared/{x3jc53kg.js → 5e3tf63j.js} +2 -2
- package/dist/shared/5fe3kbsh.js +10 -0
- package/dist/shared/5v3xf80k.js +37 -0
- package/dist/shared/{c58secgj.js → 63qtkrca.js} +38 -4
- package/dist/shared/{2z7wv5tj.js → 67txcrcw.js} +55 -34
- package/dist/shared/79dt02vc.js +12 -0
- package/dist/shared/{8x72s86k.js → 7k9grvf6.js} +10 -4
- package/dist/shared/7kms6fvj.js +20 -0
- package/dist/shared/7mnme5tn.js +8 -0
- package/dist/shared/7n7ddwt4.js +6 -0
- package/dist/shared/{5j36z8dn.js → 81ebdx9p.js} +39 -70
- package/dist/shared/{knmes2kh.js → 8skf0cam.js} +1 -1
- package/dist/shared/9a4ae4p8.js +31 -0
- package/dist/shared/9y3mmmh1.js +436 -0
- package/dist/shared/ab9gmbwy.js +213 -0
- package/dist/shared/{f0f1n281.js → ax7qv55k.js} +2 -2
- package/dist/shared/{g90m9b0g.js → aytqh5y2.js} +6 -5
- package/dist/shared/{vjpnzwjz.js → b5pftnn2.js} +1 -1
- package/dist/shared/{ag4c7516.js → b76b8d95.js} +2 -2
- package/dist/shared/{vmfkhszw.js → bg3rym3g.js} +33 -26
- package/dist/shared/{mb2ycs1p.js → bm22fvzr.js} +15 -15
- package/dist/shared/{q3j1tq7a.js → bz84tkzm.js} +148 -23
- package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
- package/dist/shared/cn957f8d.js +179 -0
- package/dist/shared/{gwn6v667.js → cnkky55j.js} +25 -14
- package/dist/shared/{ys0xzyaj.js → dkxgzaqd.js} +224 -19
- package/dist/shared/dzj09cye.js +10 -0
- package/dist/shared/exn3sd90.js +359 -0
- package/dist/shared/g6evj1j3.js +66 -0
- package/dist/shared/ga9j92qj.js +25 -0
- package/dist/shared/{t3g0k88x.js → gs74dbj5.js} +16 -12
- package/dist/shared/gzaveazc.js +285 -0
- package/dist/shared/{2jd1sn0e.js → hyh73qk6.js} +1 -1
- package/dist/shared/{r1fdd0f6.js → je4axnm8.js} +5 -2
- package/dist/shared/{1f0xa3cb.js → jvd0mqag.js} +3 -3
- package/dist/shared/jznfax0y.js +155 -0
- package/dist/shared/{cgbamx3e.js → kb2sdhfb.js} +7 -4
- package/dist/shared/{wt5rzv1h.js → kr0jzbw2.js} +5 -5
- package/dist/shared/{p6bjzq9q.js → ktz42yez.js} +12 -4
- package/dist/shared/{p248q79y.js → m6p12kbr.js} +2 -2
- package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
- package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
- package/dist/shared/{929h19xp.js → mtaszv5a.js} +40 -10
- package/dist/shared/{b3awxn7h.js → n816peh1.js} +1 -1
- package/dist/shared/nbw1z4yd.js +18 -0
- package/dist/shared/{nx9hh281.js → p6qc5gcp.js} +12 -11
- package/dist/shared/{pjr6xrm5.js → pbp1ss85.js} +20 -17
- package/dist/shared/pt94kz7f.js +6 -0
- package/dist/shared/q5c6ngn3.js +13 -0
- package/dist/shared/{xq0mvhts.js → rs73fca9.js} +4 -4
- package/dist/shared/{r11n8grd.js → sfz1ksn6.js} +7 -4
- package/dist/shared/{wynzeggs.js → svncdeh5.js} +6 -6
- package/dist/shared/{j60w0dvr.js → tbrvgw6z.js} +57 -38
- package/dist/shared/te5as7z7.js +622 -0
- package/dist/shared/{ttmg09vd.js → tsvww22q.js} +1 -1
- package/dist/shared/{y2t3jktd.js → ttsqgp4p.js} +19 -12
- package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
- package/dist/shared/{sbdme3vy.js → vb6qfyve.js} +60 -10
- package/dist/shared/{5d8t84hg.js → vczs8gd4.js} +14 -14
- package/dist/shared/{5yv4k6a6.js → vqrjpcqn.js} +144 -2
- package/dist/shared/{3fqwmr09.js → w72kgg4q.js} +4 -4
- package/dist/shared/{1z04fa85.js → w79hsckn.js} +12 -57
- package/dist/shared/{09p049xa.js → wa07eas9.js} +42 -14
- package/dist/shared/{32cnm7kn.js → x933k9a3.js} +74 -38
- package/dist/shared/{n076ydsc.js → xhfsfkgk.js} +62 -28
- package/dist/shared/xjk7hnn5.js +272 -0
- package/dist/shared/{hazqqecq.js → xnxsed62.js} +50 -21
- package/dist/shared/y6njgyda.js +249 -0
- package/dist/shared/{8etn7d8w.js → z7s6fpxv.js} +1 -1
- package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
- package/dist/shared/zm0ptry0.js +40 -0
- package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
- package/dist/shared/zp9fmend.js +145 -0
- package/dist/tooling/cli.js +11 -11
- package/dist/tooling/migrate/engine.d.ts +3 -2
- package/dist/tooling/migrate/index.js +7 -7
- package/dist/tooling/testing/index.js +1 -1
- package/package.json +4 -2
- package/dist/shared/3qnhc7w5.js +0 -38
- package/dist/shared/7m88x3e9.js +0 -45
- package/dist/shared/8dqhth8c.js +0 -12
- package/dist/shared/d5azex6s.js +0 -6
- 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/zm0mafk4.js +0 -92
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
touchFields,
|
|
3
3
|
fieldSealed
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./1w508jbr.js";
|
|
5
5
|
import {
|
|
6
6
|
projectExpr,
|
|
7
7
|
quote,
|
|
8
8
|
list,
|
|
9
9
|
isRecord,
|
|
10
10
|
registerFailFix,
|
|
11
|
-
|
|
12
|
-
} from "./
|
|
11
|
+
fail2
|
|
12
|
+
} from "./67txcrcw.js";
|
|
13
13
|
import {
|
|
14
14
|
throwNamed2
|
|
15
15
|
} from "./52szzakm.js";
|
|
@@ -24,13 +24,13 @@ function readConflict(table, value, allow = NO_ALLOW, tenantKey) {
|
|
|
24
24
|
if (value === "ignore")
|
|
25
25
|
return { kind: "ignore", columns: [], update: [] };
|
|
26
26
|
if (!isRecord(value)) {
|
|
27
|
-
|
|
27
|
+
fail2("OKM1120", 'onConflict must be "error", "ignore", { on, update }, or { on, return: true }.');
|
|
28
28
|
}
|
|
29
29
|
const keys = Object.keys(value);
|
|
30
30
|
const update = value.update;
|
|
31
31
|
const ret = value.return;
|
|
32
32
|
if (update !== undefined && ret !== undefined) {
|
|
33
|
-
|
|
33
|
+
fail2("OKM1120", "onConflict takes update or return, not both.");
|
|
34
34
|
}
|
|
35
35
|
if (ret === true) {
|
|
36
36
|
rejectConflictKeys(keys, ["on", "return"]);
|
|
@@ -44,9 +44,9 @@ function readConflict(table, value, allow = NO_ALLOW, tenantKey) {
|
|
|
44
44
|
update: updateColumns(table, update, allow)
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
fail2("OKM1120", 'onConflict must be "error", "ignore", { on, update }, or { on, return: true }.');
|
|
48
48
|
}
|
|
49
|
-
function finishInsert(head, returning, params, plan, table
|
|
49
|
+
function finishInsert(head, returning, params, plan, table) {
|
|
50
50
|
if (plan.kind === "ignore") {
|
|
51
51
|
return { text: `${head} on conflict do nothing${returning}`, params: [...params] };
|
|
52
52
|
}
|
|
@@ -66,10 +66,13 @@ function finishInsert(head, returning, params, plan, table, returningColumns, ke
|
|
|
66
66
|
params: [...params]
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
-
return
|
|
69
|
+
return {
|
|
70
|
+
text: `${head} on conflict (${target})${conflictWhere(table, plan.columns)} do nothing${returning}`,
|
|
71
|
+
params: [...params]
|
|
72
|
+
};
|
|
70
73
|
}
|
|
71
|
-
function
|
|
72
|
-
const
|
|
74
|
+
function lookupExisting(table, keys, returningColumns, keyRows) {
|
|
75
|
+
const params = [];
|
|
73
76
|
const tuples = [];
|
|
74
77
|
for (const row of keyRows) {
|
|
75
78
|
const slots = [];
|
|
@@ -77,18 +80,21 @@ function firstOrCreate(head, returning, params, keys, table, returningColumns, k
|
|
|
77
80
|
const column = keys[index];
|
|
78
81
|
if (column === undefined)
|
|
79
82
|
continue;
|
|
80
|
-
|
|
81
|
-
slots.push(`$${String(
|
|
83
|
+
params.push(row[index] ?? null);
|
|
84
|
+
slots.push(`$${String(params.length)}::${column.dataType}`);
|
|
82
85
|
}
|
|
83
86
|
tuples.push(keys.length === 1 ? slots[0] ?? "null" : `(${slots.join(", ")})`);
|
|
84
87
|
}
|
|
85
|
-
const keyList = keys.map((column) => quote(column.sql)).join(", ");
|
|
86
88
|
const left = keys.length === 1 ? `t.${quote(keys[0]?.sql ?? "")}` : `(${keys.map((column) => `t.${quote(column.sql)}`).join(", ")})`;
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
const projected = returningColumns.map((column) => projectExpr(`t.${quote(column.sql)}`, column.dataType)).join(", ");
|
|
90
|
+
const text = `select ${projected} from ${quote(table.model.sql)} t where ${left} in (${tuples.join(", ")})${activeAnd(table, keys)}`;
|
|
91
|
+
return { text, params };
|
|
92
|
+
}
|
|
93
|
+
function activeAnd(table, columns) {
|
|
94
|
+
const clause = conflictWhere(table, columns);
|
|
95
|
+
if (clause === "")
|
|
96
|
+
return "";
|
|
97
|
+
return ` and t.${clause.replace(/^ where /, "")}`;
|
|
92
98
|
}
|
|
93
99
|
function conflictWhere(table, columns) {
|
|
94
100
|
const archive = table.model.archive;
|
|
@@ -121,7 +127,7 @@ function uniqueColumns(table, on, tenantKey) {
|
|
|
121
127
|
for (const name of fields) {
|
|
122
128
|
const column = table.columns.get(name);
|
|
123
129
|
if (column === undefined) {
|
|
124
|
-
|
|
130
|
+
fail2("OKM1104", `onConflict column ${name} is not on ${table.model.name}.`);
|
|
125
131
|
}
|
|
126
132
|
columns.push(column);
|
|
127
133
|
}
|
|
@@ -143,12 +149,12 @@ function acceptedConstraints(model, keys) {
|
|
|
143
149
|
}
|
|
144
150
|
function updateColumns(table, value, allow) {
|
|
145
151
|
if (!Array.isArray(value) || value.length === 0) {
|
|
146
|
-
|
|
152
|
+
fail2("OKM1120", "onConflict update must name at least one column.");
|
|
147
153
|
}
|
|
148
154
|
const columns = [];
|
|
149
155
|
for (const name of value) {
|
|
150
156
|
if (typeof name !== "string")
|
|
151
|
-
|
|
157
|
+
fail2("OKM1120", "onConflict update must name columns.");
|
|
152
158
|
const column = table.columns.get(name);
|
|
153
159
|
if (column === undefined) {
|
|
154
160
|
throwNamed2("OKM1120", name, table.names, `Field ${name} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
|
|
@@ -166,7 +172,7 @@ function conflictNames(on) {
|
|
|
166
172
|
if (Array.isArray(on) && on.length > 0 && on.every((name) => typeof name === "string")) {
|
|
167
173
|
return on;
|
|
168
174
|
}
|
|
169
|
-
|
|
175
|
+
fail2("OKM1104", "onConflict on must name a unique constraint's columns.");
|
|
170
176
|
}
|
|
171
177
|
function fieldsOf(unique, names, tenantKeys) {
|
|
172
178
|
if (tenantKeys.some((key) => unique.includes(key))) {
|
|
@@ -210,17 +216,18 @@ function rejectConflictKeys(keys, accepted) {
|
|
|
210
216
|
}
|
|
211
217
|
function refuseWrite(table, column) {
|
|
212
218
|
if (fieldSealed(table.model, column.field)) {
|
|
213
|
-
|
|
219
|
+
fail2("OKM1190", `Field ${table.model.name}.${column.field} is set by a trait. Input cannot set it.`);
|
|
214
220
|
}
|
|
215
221
|
if (column.guardUpdate) {
|
|
216
|
-
|
|
222
|
+
fail2("OKM1190", `Field ${table.model.name}.${column.field} is a primary key. Input cannot change it.`);
|
|
217
223
|
}
|
|
218
224
|
if (column.guarded) {
|
|
219
|
-
|
|
225
|
+
fail2("OKM1190", `Field ${table.model.name}.${column.field} is guarded. Input cannot set it.`);
|
|
220
226
|
}
|
|
221
|
-
|
|
227
|
+
fail2("OKM1120", `Field ${table.model.name}.${column.field} cannot be written.`);
|
|
222
228
|
}
|
|
223
229
|
export {
|
|
224
230
|
finishInsert,
|
|
231
|
+
lookupExisting,
|
|
225
232
|
readConflict
|
|
226
233
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./
|
|
2
|
+
stack2
|
|
3
|
+
} from "./mss6ctgv.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
} from "./
|
|
5
|
+
effectivePredicate
|
|
6
|
+
} from "./n816peh1.js";
|
|
7
7
|
import {
|
|
8
8
|
runWrite
|
|
9
9
|
} from "./n4jqhpqz.js";
|
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
quote,
|
|
17
17
|
isRecord,
|
|
18
18
|
registerFailFix,
|
|
19
|
-
|
|
20
|
-
} from "./
|
|
19
|
+
fail2
|
|
20
|
+
} from "./67txcrcw.js";
|
|
21
21
|
import {
|
|
22
22
|
safetyInstalled,
|
|
23
23
|
runSafety
|
|
@@ -50,7 +50,7 @@ function explainArchive(schema, op, table, input, options, mods, scope) {
|
|
|
50
50
|
function planArchive(schema, op, tableName, input, options, mods, scope) {
|
|
51
51
|
const table = indexes(schema).get(tableName);
|
|
52
52
|
if (table === undefined)
|
|
53
|
-
|
|
53
|
+
fail2("OKM1120", `Table ${tableName} is not in the schema.`);
|
|
54
54
|
const archive = table.model.archive;
|
|
55
55
|
if (archive === undefined) {
|
|
56
56
|
throw new OkmError2("OKM1052", `Table ${tableName} is not archivable.`, {
|
|
@@ -61,7 +61,7 @@ function planArchive(schema, op, tableName, input, options, mods, scope) {
|
|
|
61
61
|
rejectKeys(record, OPTIONS, op);
|
|
62
62
|
const expect = expectOf(record.expect ?? mods.expect);
|
|
63
63
|
const read = readTarget(op, table, input, mods);
|
|
64
|
-
const target = { ...read, where:
|
|
64
|
+
const target = { ...read, where: stack2(read.where, mods.presets) };
|
|
65
65
|
const view = op === "restore" ? "only" : undefined;
|
|
66
66
|
noteArchive(table, view);
|
|
67
67
|
const statement = withRowFilters(scope, view, () => op === "archive" ? archiveSql(schema, table, target.where) : restoreSql(schema, table, target));
|
|
@@ -83,25 +83,25 @@ function noteArchive(table, view) {
|
|
|
83
83
|
}
|
|
84
84
|
function readTarget(op, table, input, mods) {
|
|
85
85
|
if (!isRecord(input))
|
|
86
|
-
|
|
86
|
+
fail2("OKM1121", `${op} expects { where }.`);
|
|
87
87
|
const keys = Object.keys(input);
|
|
88
88
|
if (op === "restore" && input.archiveId !== undefined) {
|
|
89
89
|
if (input.where !== undefined)
|
|
90
|
-
|
|
90
|
+
fail2("OKM1120", "restore takes where or archiveId, not both.");
|
|
91
91
|
for (const key of keys) {
|
|
92
92
|
if (key !== "archiveId") {
|
|
93
|
-
|
|
93
|
+
fail2("OKM1120", "restore accepts where or archiveId.");
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
if (typeof input.archiveId !== "string" || input.archiveId.length === 0) {
|
|
97
|
-
|
|
97
|
+
fail2("OKM1121", "restore archiveId must be a uuid.");
|
|
98
98
|
}
|
|
99
99
|
const idField = table.model.archive?.idField ?? "archiveId";
|
|
100
100
|
return { where: { [idField]: input.archiveId }, archiveId: input.archiveId };
|
|
101
101
|
}
|
|
102
102
|
for (const key of keys) {
|
|
103
103
|
if (key !== "where")
|
|
104
|
-
|
|
104
|
+
fail2("OKM1120", `${op} accepts where.`);
|
|
105
105
|
}
|
|
106
106
|
requireFilter(table, input.where, mods, op);
|
|
107
107
|
return { where: input.where, archiveId: undefined };
|
|
@@ -358,12 +358,12 @@ function expectOf(value) {
|
|
|
358
358
|
function requireFilter(table, where, mods, op) {
|
|
359
359
|
if (mods.all !== undefined) {
|
|
360
360
|
if (mods.all.trim().length === 0) {
|
|
361
|
-
|
|
361
|
+
fail2("OKM1102", `${op} on ${table.model.name} needs a where. .all needs a reason.`);
|
|
362
362
|
}
|
|
363
363
|
return;
|
|
364
364
|
}
|
|
365
365
|
if (!effectivePredicate(where)) {
|
|
366
|
-
|
|
366
|
+
fail2("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
369
|
function callOptions(input) {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DriverError2,
|
|
3
|
+
timedOut2
|
|
4
|
+
} from "./cm3w0ywp.js";
|
|
1
5
|
import {
|
|
2
6
|
PgSession
|
|
3
|
-
} from "./
|
|
7
|
+
} from "./14vx95q4.js";
|
|
4
8
|
import {
|
|
5
9
|
isConnectionLost
|
|
6
|
-
} from "./
|
|
10
|
+
} from "./cnkky55j.js";
|
|
7
11
|
import {
|
|
8
12
|
driverErrors,
|
|
9
13
|
rejectClosed,
|
|
@@ -11,32 +15,45 @@ import {
|
|
|
11
15
|
runCall,
|
|
12
16
|
rowsFrom,
|
|
13
17
|
resultFrom
|
|
14
|
-
} from "./
|
|
18
|
+
} from "./kb2sdhfb.js";
|
|
15
19
|
|
|
16
20
|
// src/adapters/pg/postgres-extra.ts
|
|
17
21
|
var RESET_ALL = "RESET ALL";
|
|
18
22
|
var UNLOCK = "SELECT pg_advisory_unlock_all()";
|
|
19
|
-
async function checkout2(pool) {
|
|
23
|
+
async function checkout2(pool, timeoutMs) {
|
|
20
24
|
if (pool.isClosed())
|
|
21
25
|
return rejectClosed();
|
|
22
|
-
const reserved = await reserveConnection(pool.sql, pool.acquireMs, pool.counters);
|
|
26
|
+
const reserved = await reserveConnection(pool.sql, pool.acquireMs, pool.counters, timeoutMs);
|
|
23
27
|
pool.counters.reserved += 1;
|
|
24
28
|
const local = new Set;
|
|
25
29
|
const session = new PgSession(reserved, pool.counters, "reserved", local, pool.isClosed, pool.poolInflight, pool.notices, pool.named);
|
|
26
30
|
let released = false;
|
|
27
|
-
const lost = { on: false
|
|
31
|
+
const lost = { on: false, stop: () => {
|
|
32
|
+
return;
|
|
33
|
+
} };
|
|
28
34
|
arm(reserved, lost);
|
|
29
|
-
|
|
35
|
+
let limit = timeoutMs !== undefined && timeoutMs > 0 ? timeoutMs : 0;
|
|
36
|
+
const remember = (timeout) => {
|
|
37
|
+
if (timeout !== undefined && timeout > 0)
|
|
38
|
+
limit = timeout;
|
|
39
|
+
};
|
|
40
|
+
const guard = (run) => lost.on ? rejectClosed() : run().catch((error) => {
|
|
30
41
|
if (isConnectionLost(error))
|
|
31
42
|
lost.on = true;
|
|
32
43
|
throw error;
|
|
33
44
|
});
|
|
34
45
|
return {
|
|
35
|
-
execute: (text, params, options) =>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
execute: (text, params, options) => {
|
|
47
|
+
remember(options?.timeout);
|
|
48
|
+
return guard(() => runCall(pool.isClosed(), options, (watch) => session.query(text, params, watch)));
|
|
49
|
+
},
|
|
50
|
+
batch: (statements, options) => {
|
|
51
|
+
remember(options?.timeout);
|
|
52
|
+
return guard(() => runCall(pool.isClosed(), options, async (watch) => {
|
|
53
|
+
const { runAtomicBatch } = await import("./b76b8d95.js");
|
|
54
|
+
return runAtomicBatch(session, statements, watch);
|
|
55
|
+
}));
|
|
56
|
+
},
|
|
40
57
|
cancel() {
|
|
41
58
|
session.cancel();
|
|
42
59
|
},
|
|
@@ -44,13 +61,16 @@ async function checkout2(pool) {
|
|
|
44
61
|
if (released)
|
|
45
62
|
return;
|
|
46
63
|
released = true;
|
|
64
|
+
const ms = limit;
|
|
47
65
|
try {
|
|
48
66
|
if (!lost.on)
|
|
49
|
-
await resetConnection(reserved, session.depth());
|
|
67
|
+
await deadline(ms, () => resetConnection(reserved, session.depth()), lost);
|
|
68
|
+
} catch {
|
|
69
|
+
lost.on = true;
|
|
50
70
|
} finally {
|
|
51
71
|
pool.counters.reserved = Math.max(0, pool.counters.reserved - 1);
|
|
52
72
|
if (lost.on)
|
|
53
|
-
await pool.sql.unsafe("select 1").catch(() => {
|
|
73
|
+
await deadline(ms, () => pool.sql.unsafe("select 1"), pool.sql).catch(() => {
|
|
54
74
|
return;
|
|
55
75
|
});
|
|
56
76
|
else
|
|
@@ -73,37 +93,141 @@ async function* stream2(sql, text, params) {
|
|
|
73
93
|
yield rowsFrom(chunk);
|
|
74
94
|
}
|
|
75
95
|
}
|
|
76
|
-
function
|
|
96
|
+
function poolWaits(sql) {
|
|
97
|
+
const options = sql.options;
|
|
98
|
+
if (options === undefined || options.q !== undefined)
|
|
99
|
+
return options;
|
|
100
|
+
const q = new Set;
|
|
101
|
+
const n = new Set;
|
|
102
|
+
options.q = q;
|
|
103
|
+
options.n = n;
|
|
104
|
+
options.onclose = (id) => {
|
|
105
|
+
n.add(id);
|
|
106
|
+
if (n.size < options.max) {
|
|
107
|
+
queueMicrotask(() => {
|
|
108
|
+
for (const wait of q)
|
|
109
|
+
wait.a();
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
n.clear();
|
|
114
|
+
for (const wait of q)
|
|
115
|
+
wait.s();
|
|
116
|
+
q.clear();
|
|
117
|
+
};
|
|
118
|
+
return options;
|
|
119
|
+
}
|
|
120
|
+
function deadline(ms, run, link) {
|
|
121
|
+
let timer;
|
|
122
|
+
let off = () => {
|
|
123
|
+
return;
|
|
124
|
+
};
|
|
125
|
+
const slot = link !== undefined && "stop" in link ? link : undefined;
|
|
126
|
+
const pool = slot === undefined && link !== undefined ? poolWaits(link) : undefined;
|
|
127
|
+
let ended = false;
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
const fail = (error) => {
|
|
130
|
+
if (ended)
|
|
131
|
+
return;
|
|
132
|
+
ended = true;
|
|
133
|
+
reject(error);
|
|
134
|
+
};
|
|
135
|
+
const stop = () => {
|
|
136
|
+
fail(new DriverError2("Connection closed", { sqlstate: "08006" }));
|
|
137
|
+
};
|
|
138
|
+
if (slot !== undefined)
|
|
139
|
+
slot.stop = stop;
|
|
140
|
+
const go = () => {
|
|
141
|
+
const pending = run();
|
|
142
|
+
if (ms > 0 && timer === undefined) {
|
|
143
|
+
timer = setTimeout(() => {
|
|
144
|
+
pending.cancel?.();
|
|
145
|
+
fail(timedOut2());
|
|
146
|
+
}, ms);
|
|
147
|
+
}
|
|
148
|
+
pending.then((value) => {
|
|
149
|
+
if (ended) {
|
|
150
|
+
value.release?.();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
ended = true;
|
|
154
|
+
pool?.n?.clear();
|
|
155
|
+
resolve(value);
|
|
156
|
+
}, fail);
|
|
157
|
+
};
|
|
158
|
+
if (ms === 0 && pool?.q !== undefined) {
|
|
159
|
+
let used = false;
|
|
160
|
+
const wait = {
|
|
161
|
+
s: stop,
|
|
162
|
+
a() {
|
|
163
|
+
if (used || ended)
|
|
164
|
+
return;
|
|
165
|
+
used = true;
|
|
166
|
+
go();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
pool.q.add(wait);
|
|
170
|
+
off = () => pool.q?.delete(wait);
|
|
171
|
+
}
|
|
172
|
+
go();
|
|
173
|
+
}).finally(() => {
|
|
174
|
+
clearTimeout(timer);
|
|
175
|
+
if (slot !== undefined)
|
|
176
|
+
slot.stop = () => {
|
|
177
|
+
return;
|
|
178
|
+
};
|
|
179
|
+
off();
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async function runBatch2(pool, statements, options) {
|
|
183
|
+
const connection = await checkout2(pool, options?.timeout);
|
|
184
|
+
try {
|
|
185
|
+
return await connection.batch(statements, options);
|
|
186
|
+
} finally {
|
|
187
|
+
await connection.release();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function reserveConnection(sql, acquireMs, counters, callMs) {
|
|
77
191
|
counters.waiting += 1;
|
|
78
192
|
let settled = false;
|
|
193
|
+
const finish = () => {
|
|
194
|
+
counters.waiting = Math.max(0, counters.waiting - 1);
|
|
195
|
+
};
|
|
79
196
|
return new Promise((resolve, reject) => {
|
|
80
197
|
let timer;
|
|
81
198
|
if (acquireMs !== undefined) {
|
|
82
199
|
timer = setTimeout(() => {
|
|
200
|
+
if (settled)
|
|
201
|
+
return;
|
|
83
202
|
settled = true;
|
|
84
|
-
|
|
203
|
+
finish();
|
|
85
204
|
driverErrors().then((errors) => {
|
|
86
205
|
reject(errors.acquireTimeout());
|
|
87
206
|
});
|
|
88
207
|
}, acquireMs);
|
|
89
208
|
}
|
|
90
|
-
|
|
209
|
+
const ms = callMs !== undefined && callMs > 0 ? callMs : 0;
|
|
210
|
+
deadline(ms, () => sql.reserve(), sql).then((connection) => {
|
|
91
211
|
if (settled) {
|
|
92
|
-
resetConnection(connection, 0).
|
|
212
|
+
resetConnection(connection, 0).catch(() => {
|
|
213
|
+
return;
|
|
214
|
+
}).finally(() => {
|
|
93
215
|
connection.release();
|
|
94
216
|
});
|
|
95
217
|
return;
|
|
96
218
|
}
|
|
219
|
+
settled = true;
|
|
97
220
|
if (timer !== undefined)
|
|
98
221
|
clearTimeout(timer);
|
|
99
|
-
|
|
222
|
+
finish();
|
|
100
223
|
resolve(connection);
|
|
101
224
|
}, (error) => {
|
|
102
225
|
if (settled)
|
|
103
226
|
return;
|
|
227
|
+
settled = true;
|
|
104
228
|
if (timer !== undefined)
|
|
105
229
|
clearTimeout(timer);
|
|
106
|
-
|
|
230
|
+
finish();
|
|
107
231
|
mapFailure(error).then(reject);
|
|
108
232
|
});
|
|
109
233
|
});
|
|
@@ -139,6 +263,7 @@ function arm(sql, lost) {
|
|
|
139
263
|
onexecute(connection) {
|
|
140
264
|
connection.onclose = () => {
|
|
141
265
|
lost.on = true;
|
|
266
|
+
lost.stop();
|
|
142
267
|
};
|
|
143
268
|
}
|
|
144
269
|
});
|
|
@@ -182,13 +307,13 @@ async function holdListener2(gate, start) {
|
|
|
182
307
|
}
|
|
183
308
|
}
|
|
184
309
|
function watchQuery2(pending, watch, onAbort, ctx) {
|
|
185
|
-
return pending.then((
|
|
310
|
+
return pending.then((value) => {
|
|
186
311
|
finishWatch(pending, watch, onAbort, ctx);
|
|
187
312
|
const why = watch.reason();
|
|
188
313
|
if (why === "timeout" || why === "cancelled")
|
|
189
314
|
return classify(why, watch);
|
|
190
315
|
ctx.note(ctx.text);
|
|
191
|
-
return resultFrom(
|
|
316
|
+
return resultFrom(value, ctx.notices.since(ctx.start));
|
|
192
317
|
}, (error) => {
|
|
193
318
|
finishWatch(pending, watch, onAbort, ctx);
|
|
194
319
|
return classify(error, watch);
|
|
@@ -214,4 +339,4 @@ async function classify(error, watch) {
|
|
|
214
339
|
return Promise.reject(errors.mapDriverError(error));
|
|
215
340
|
}
|
|
216
341
|
|
|
217
|
-
export { checkout2, describe2, stream2, watchReserved2, holdCheckout2, holdListener2, watchQuery2 };
|
|
342
|
+
export { checkout2, describe2, stream2, runBatch2, watchReserved2, holdCheckout2, holdListener2, watchQuery2 };
|
|
@@ -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
|
|