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.
Files changed (157) hide show
  1. package/README.md +100 -1131
  2. package/dist/adapters/capabilities.d.ts +3 -0
  3. package/dist/adapters/failure.d.ts +13 -2
  4. package/dist/adapters/lazy-errors.d.ts +22 -0
  5. package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
  6. package/dist/adapters/pg/bunsql.d.ts +14 -1
  7. package/dist/adapters/pg/cursor.d.ts +17 -0
  8. package/dist/adapters/pg/no-inflight-timeout.d.ts +11 -8
  9. package/dist/adapters/pg/nodepostgres-extra.d.ts +22 -1
  10. package/dist/adapters/pg/nodepostgres.d.ts +12 -0
  11. package/dist/adapters/pg/pglite-wire.d.ts +24 -0
  12. package/dist/adapters/pg/pglite.d.ts +10 -0
  13. package/dist/adapters/pg/postgres-extra.d.ts +27 -11
  14. package/dist/adapters/pg/reserved.d.ts +42 -0
  15. package/dist/adapters/pg/session.d.ts +0 -18
  16. package/dist/contracts/connection.d.ts +7 -6
  17. package/dist/dialects/pg/floor.d.ts +68 -0
  18. package/dist/dialects/pg/index.d.ts +6 -1
  19. package/dist/dialects/pg/index.js +49 -159
  20. package/dist/dialects/pg/keys.d.ts +11 -8
  21. package/dist/dialects/pg/model.d.ts +40 -0
  22. package/dist/dialects/pg/morph.d.ts +43 -0
  23. package/dist/dialects/pg/operator-fit.d.ts +2 -2
  24. package/dist/dialects/pg/operators.d.ts +14 -7
  25. package/dist/dialects/pg/ops/bucket.d.ts +65 -0
  26. package/dist/dialects/pg/ops/inc.d.ts +2 -2
  27. package/dist/dialects/pg/ops/matches.d.ts +9 -12
  28. package/dist/dialects/pg/ops/relevance.d.ts +13 -0
  29. package/dist/dialects/pg/ops/search-query.d.ts +22 -0
  30. package/dist/dialects/pg/ops/window.d.ts +103 -0
  31. package/dist/dialects/pg/preset.d.ts +1 -1
  32. package/dist/dialects/pg/relations.d.ts +100 -3
  33. package/dist/dialects/pg/schema.d.ts +31 -3
  34. package/dist/dialects/pg/view/index.js +1 -1
  35. package/dist/runtime/aggregate.d.ts +8 -2
  36. package/dist/runtime/bucket-group.d.ts +70 -0
  37. package/dist/runtime/conflict.d.ts +22 -4
  38. package/dist/runtime/include.d.ts +0 -8
  39. package/dist/runtime/inflight.d.ts +1 -1
  40. package/dist/runtime/page.d.ts +4 -1
  41. package/dist/runtime/pg/bun.js +12 -6
  42. package/dist/runtime/pg/pg.js +5 -5
  43. package/dist/runtime/pg/pglite.d.ts +1 -0
  44. package/dist/runtime/pg/pglite.js +9 -9
  45. package/dist/runtime/pg/postgresjs.js +5 -5
  46. package/dist/runtime/plan.d.ts +95 -5
  47. package/dist/runtime/read-stream.d.ts +13 -16
  48. package/dist/runtime/result-name.d.ts +17 -0
  49. package/dist/runtime/server-check.d.ts +3 -3
  50. package/dist/runtime/sort-bind.d.ts +21 -0
  51. package/dist/runtime/sort.d.ts +56 -0
  52. package/dist/runtime/sync.d.ts +70 -0
  53. package/dist/runtime/tenancy/index.js +7 -5
  54. package/dist/runtime/text-search.d.ts +20 -0
  55. package/dist/runtime/traits/index.d.ts +80 -0
  56. package/dist/runtime/traits/index.js +175 -11
  57. package/dist/runtime/tree.d.ts +38 -0
  58. package/dist/runtime/types.d.ts +218 -22
  59. package/dist/runtime/validate/index.js +2 -2
  60. package/dist/runtime/version.d.ts +39 -0
  61. package/dist/runtime/window.d.ts +21 -0
  62. package/dist/runtime/write.d.ts +54 -2
  63. package/dist/shared/{wkme6tep.js → 14vx95q4.js} +8 -16
  64. package/dist/shared/1est4ezg.js +313 -0
  65. package/dist/shared/{4az561fn.js → 1qa0qajz.js} +8 -23
  66. package/dist/shared/{2cg3wnxc.js → 1w508jbr.js} +593 -130
  67. package/dist/shared/2c13q96h.js +18 -0
  68. package/dist/shared/{b4v57v3x.js → 2d3xq4ps.js} +2 -2
  69. package/dist/shared/{1nw1f3vs.js → 2shdbn8q.js} +7 -7
  70. package/dist/shared/3v7t1yrv.js +208 -0
  71. package/dist/shared/{x3jc53kg.js → 5e3tf63j.js} +2 -2
  72. package/dist/shared/5fe3kbsh.js +10 -0
  73. package/dist/shared/5v3xf80k.js +37 -0
  74. package/dist/shared/{c58secgj.js → 63qtkrca.js} +38 -4
  75. package/dist/shared/{2z7wv5tj.js → 67txcrcw.js} +55 -34
  76. package/dist/shared/79dt02vc.js +12 -0
  77. package/dist/shared/{8x72s86k.js → 7k9grvf6.js} +10 -4
  78. package/dist/shared/7kms6fvj.js +20 -0
  79. package/dist/shared/7mnme5tn.js +8 -0
  80. package/dist/shared/7n7ddwt4.js +6 -0
  81. package/dist/shared/{5j36z8dn.js → 81ebdx9p.js} +39 -70
  82. package/dist/shared/{knmes2kh.js → 8skf0cam.js} +1 -1
  83. package/dist/shared/9a4ae4p8.js +31 -0
  84. package/dist/shared/9y3mmmh1.js +436 -0
  85. package/dist/shared/ab9gmbwy.js +213 -0
  86. package/dist/shared/{f0f1n281.js → ax7qv55k.js} +2 -2
  87. package/dist/shared/{g90m9b0g.js → aytqh5y2.js} +6 -5
  88. package/dist/shared/{vjpnzwjz.js → b5pftnn2.js} +1 -1
  89. package/dist/shared/{ag4c7516.js → b76b8d95.js} +2 -2
  90. package/dist/shared/{vmfkhszw.js → bg3rym3g.js} +33 -26
  91. package/dist/shared/{mb2ycs1p.js → bm22fvzr.js} +15 -15
  92. package/dist/shared/{q3j1tq7a.js → bz84tkzm.js} +148 -23
  93. package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
  94. package/dist/shared/cn957f8d.js +179 -0
  95. package/dist/shared/{gwn6v667.js → cnkky55j.js} +25 -14
  96. package/dist/shared/{ys0xzyaj.js → dkxgzaqd.js} +224 -19
  97. package/dist/shared/dzj09cye.js +10 -0
  98. package/dist/shared/exn3sd90.js +359 -0
  99. package/dist/shared/g6evj1j3.js +66 -0
  100. package/dist/shared/ga9j92qj.js +25 -0
  101. package/dist/shared/{t3g0k88x.js → gs74dbj5.js} +16 -12
  102. package/dist/shared/gzaveazc.js +285 -0
  103. package/dist/shared/{2jd1sn0e.js → hyh73qk6.js} +1 -1
  104. package/dist/shared/{r1fdd0f6.js → je4axnm8.js} +5 -2
  105. package/dist/shared/{1f0xa3cb.js → jvd0mqag.js} +3 -3
  106. package/dist/shared/jznfax0y.js +155 -0
  107. package/dist/shared/{cgbamx3e.js → kb2sdhfb.js} +7 -4
  108. package/dist/shared/{wt5rzv1h.js → kr0jzbw2.js} +5 -5
  109. package/dist/shared/{p6bjzq9q.js → ktz42yez.js} +12 -4
  110. package/dist/shared/{p248q79y.js → m6p12kbr.js} +2 -2
  111. package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
  112. package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
  113. package/dist/shared/{929h19xp.js → mtaszv5a.js} +40 -10
  114. package/dist/shared/{b3awxn7h.js → n816peh1.js} +1 -1
  115. package/dist/shared/nbw1z4yd.js +18 -0
  116. package/dist/shared/{nx9hh281.js → p6qc5gcp.js} +12 -11
  117. package/dist/shared/{pjr6xrm5.js → pbp1ss85.js} +20 -17
  118. package/dist/shared/pt94kz7f.js +6 -0
  119. package/dist/shared/q5c6ngn3.js +13 -0
  120. package/dist/shared/{xq0mvhts.js → rs73fca9.js} +4 -4
  121. package/dist/shared/{r11n8grd.js → sfz1ksn6.js} +7 -4
  122. package/dist/shared/{wynzeggs.js → svncdeh5.js} +6 -6
  123. package/dist/shared/{j60w0dvr.js → tbrvgw6z.js} +57 -38
  124. package/dist/shared/te5as7z7.js +622 -0
  125. package/dist/shared/{ttmg09vd.js → tsvww22q.js} +1 -1
  126. package/dist/shared/{y2t3jktd.js → ttsqgp4p.js} +19 -12
  127. package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
  128. package/dist/shared/{sbdme3vy.js → vb6qfyve.js} +60 -10
  129. package/dist/shared/{5d8t84hg.js → vczs8gd4.js} +14 -14
  130. package/dist/shared/{5yv4k6a6.js → vqrjpcqn.js} +144 -2
  131. package/dist/shared/{3fqwmr09.js → w72kgg4q.js} +4 -4
  132. package/dist/shared/{1z04fa85.js → w79hsckn.js} +12 -57
  133. package/dist/shared/{09p049xa.js → wa07eas9.js} +42 -14
  134. package/dist/shared/{32cnm7kn.js → x933k9a3.js} +74 -38
  135. package/dist/shared/{n076ydsc.js → xhfsfkgk.js} +62 -28
  136. package/dist/shared/xjk7hnn5.js +272 -0
  137. package/dist/shared/{hazqqecq.js → xnxsed62.js} +50 -21
  138. package/dist/shared/y6njgyda.js +249 -0
  139. package/dist/shared/{8etn7d8w.js → z7s6fpxv.js} +1 -1
  140. package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
  141. package/dist/shared/zm0ptry0.js +40 -0
  142. package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
  143. package/dist/shared/zp9fmend.js +145 -0
  144. package/dist/tooling/cli.js +11 -11
  145. package/dist/tooling/migrate/engine.d.ts +3 -2
  146. package/dist/tooling/migrate/index.js +7 -7
  147. package/dist/tooling/testing/index.js +1 -1
  148. package/package.json +4 -2
  149. package/dist/shared/3qnhc7w5.js +0 -38
  150. package/dist/shared/7m88x3e9.js +0 -45
  151. package/dist/shared/8dqhth8c.js +0 -12
  152. package/dist/shared/d5azex6s.js +0 -6
  153. package/dist/shared/j3rkk835.js +0 -99
  154. package/dist/shared/k68eedmy.js +0 -85
  155. package/dist/shared/venqrjna.js +0 -216
  156. package/dist/shared/wxr8cwns.js +0 -6
  157. package/dist/shared/zm0mafk4.js +0 -92
@@ -2,10 +2,10 @@ import {
2
2
  DriverError2,
3
3
  outcomeUnknown2,
4
4
  mapDriverError2
5
- } from "./31vm914h.js";
5
+ } from "./cm3w0ywp.js";
6
6
  import {
7
7
  isConnectionLost
8
- } from "./gwn6v667.js";
8
+ } from "./cnkky55j.js";
9
9
 
10
10
  // src/adapters/pg/batch.ts
11
11
  var savepointIds = 0;
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  touchFields,
3
3
  fieldSealed
4
- } from "./7m88x3e9.js";
4
+ } from "./1w508jbr.js";
5
5
  import {
6
6
  projectExpr,
7
7
  quote,
8
8
  list,
9
9
  isRecord,
10
10
  registerFailFix,
11
- fail
12
- } from "./2z7wv5tj.js";
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
- fail("OKM1120", 'onConflict must be "error", "ignore", { on, update }, or { on, return: true }.');
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
- fail("OKM1120", "onConflict takes update or return, not both.");
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
- fail("OKM1120", 'onConflict must be "error", "ignore", { on, update }, or { on, return: true }.');
47
+ fail2("OKM1120", 'onConflict must be "error", "ignore", { on, update }, or { on, return: true }.');
48
48
  }
49
- function finishInsert(head, returning, params, plan, table, returningColumns, keys) {
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 firstOrCreate(head, returning, params, plan.columns, table, returningColumns, keys);
69
+ return {
70
+ text: `${head} on conflict (${target})${conflictWhere(table, plan.columns)} do nothing${returning}`,
71
+ params: [...params]
72
+ };
70
73
  }
71
- function firstOrCreate(head, returning, params, keys, table, returningColumns, keyRows) {
72
- const next = [...params];
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
- next.push(row[index] ?? null);
81
- slots.push(`$${String(next.length)}::${column.dataType}`);
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 names = returningColumns.map((column) => quote(column.field)).join(", ");
88
- const fromTable = returningColumns.map((column) => projectExpr(`t.${quote(column.sql)}`, column.dataType)).join(", ");
89
- const match = keys.map((column) => `ins.${quote(column.field)} = t.${quote(column.sql)}`).join(" and ");
90
- const text = `with ins(${names}) as (${head} on conflict (${keyList})${conflictWhere(table, keys)} do nothing${returning}) select ${names} from ins union all select ${fromTable} from ${quote(table.model.sql)} t where ${left} in (${tuples.join(", ")}) and not exists (select 1 from ins where ${match})`;
91
- return { text, params: next };
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
- fail("OKM1104", `onConflict column ${name} is not on ${table.model.name}.`);
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
- fail("OKM1120", "onConflict update must name at least one column.");
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
- fail("OKM1120", "onConflict update must name columns.");
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
- fail("OKM1104", "onConflict on must name a unique constraint's columns.");
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
- fail("OKM1190", `Field ${table.model.name}.${column.field} is set by a trait. Input cannot set it.`);
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
- fail("OKM1190", `Field ${table.model.name}.${column.field} is a primary key. Input cannot change it.`);
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
- fail("OKM1190", `Field ${table.model.name}.${column.field} is guarded. Input cannot set it.`);
225
+ fail2("OKM1190", `Field ${table.model.name}.${column.field} is guarded. Input cannot set it.`);
220
226
  }
221
- fail("OKM1120", `Field ${table.model.name}.${column.field} cannot be written.`);
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
- effectivePredicate
3
- } from "./b3awxn7h.js";
2
+ stack2
3
+ } from "./mss6ctgv.js";
4
4
  import {
5
- stack
6
- } from "./672t5vym.js";
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
- fail
20
- } from "./2z7wv5tj.js";
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
- fail("OKM1120", `Table ${tableName} is not in the schema.`);
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: stack(read.where, mods.presets) };
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
- fail("OKM1121", `${op} expects { where }.`);
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
- fail("OKM1120", "restore takes where or archiveId, not both.");
90
+ fail2("OKM1120", "restore takes where or archiveId, not both.");
91
91
  for (const key of keys) {
92
92
  if (key !== "archiveId") {
93
- fail("OKM1120", "restore accepts where or archiveId.");
93
+ fail2("OKM1120", "restore accepts where or archiveId.");
94
94
  }
95
95
  }
96
96
  if (typeof input.archiveId !== "string" || input.archiveId.length === 0) {
97
- fail("OKM1121", "restore archiveId must be a uuid.");
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
- fail("OKM1120", `${op} accepts where.`);
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
- fail("OKM1102", `${op} on ${table.model.name} needs a where. .all needs a reason.`);
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
- fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
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 "./wkme6tep.js";
7
+ } from "./14vx95q4.js";
4
8
  import {
5
9
  isConnectionLost
6
- } from "./gwn6v667.js";
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 "./cgbamx3e.js";
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
- const guard = (run) => lost.on ? rejectClosed("CONNECTION_CLOSED") : run().catch((error) => {
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) => guard(() => runCall(pool.isClosed(), options, (watch) => session.query(text, params, watch))),
36
- batch: (statements, options) => guard(() => runCall(pool.isClosed(), options, async (watch) => {
37
- const { runAtomicBatch } = await import("./ag4c7516.js");
38
- return runAtomicBatch(session, statements, watch);
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 reserveConnection(sql, acquireMs, counters) {
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
- counters.waiting = Math.max(0, counters.waiting - 1);
203
+ finish();
85
204
  driverErrors().then((errors) => {
86
205
  reject(errors.acquireTimeout());
87
206
  });
88
207
  }, acquireMs);
89
208
  }
90
- sql.reserve().then((connection) => {
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).finally(() => {
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
- counters.waiting = Math.max(0, counters.waiting - 1);
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
- counters.waiting = Math.max(0, counters.waiting - 1);
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((result) => {
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(result, ctx.notices.since(ctx.start));
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
- if (input.sqlstate !== undefined)
100
- fields.sqlstate = input.sqlstate;
101
- if (input.constraint !== undefined)
102
- fields.constraint = input.constraint;
103
- if (input.table !== undefined)
104
- fields.table = input.table;
105
- if (input.column !== undefined)
106
- fields.column = input.column;
107
- if (input.detail !== undefined)
108
- fields.detail = input.detail;
109
- if (input.cause !== undefined)
110
- fields.cause = input.cause;
111
- if (input.batchIndex !== undefined)
112
- fields.batchIndex = input.batchIndex;
113
- if (input.kind !== undefined)
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