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.
Files changed (195) hide show
  1. package/dist/adapters/capabilities.d.ts +32 -0
  2. package/dist/adapters/failure.d.ts +1 -1
  3. package/dist/adapters/pg/bun-sql.d.ts +53 -0
  4. package/dist/adapters/pg/bunsql-extra.d.ts +1 -1
  5. package/dist/adapters/pg/bunsql.d.ts +1 -1
  6. package/dist/adapters/pg/neon-extra.d.ts +18 -0
  7. package/dist/adapters/pg/neon.d.ts +104 -0
  8. package/dist/adapters/pg/no-inflight-timeout.d.ts +1 -1
  9. package/dist/contracts/error.d.ts +1 -1
  10. package/dist/dialects/pg/fn/index.d.ts +39 -1
  11. package/dist/dialects/pg/fn/index.js +118 -26
  12. package/dist/dialects/pg/index.d.ts +2 -0
  13. package/dist/dialects/pg/index.js +393 -18
  14. package/dist/dialects/pg/introspect.d.ts +11 -0
  15. package/dist/dialects/pg/operators.d.ts +1 -1
  16. package/dist/dialects/pg/ops/fragment.d.ts +119 -0
  17. package/dist/dialects/pg/ops/lane.d.ts +49 -0
  18. package/dist/dialects/pg/view/client.d.ts +14 -6
  19. package/dist/dialects/pg/view/index.d.ts +73 -1
  20. package/dist/dialects/pg/view/index.js +156 -5
  21. package/dist/dialects/pg/view/scratch.d.ts +8 -5
  22. package/dist/runtime/otel.d.ts +105 -0
  23. package/dist/runtime/otel.js +97 -0
  24. package/dist/runtime/pg/bun.js +4 -4
  25. package/dist/runtime/pg/neon.d.ts +38 -0
  26. package/dist/runtime/pg/neon.js +64 -0
  27. package/dist/runtime/pg/pg.js +4 -4
  28. package/dist/runtime/pg/pglite.js +4 -4
  29. package/dist/runtime/pg/postgresjs.js +4 -4
  30. package/dist/runtime/plan.d.ts +1 -1
  31. package/dist/runtime/sql-fragment.d.ts +43 -0
  32. package/dist/runtime/tenancy/index.js +10 -10
  33. package/dist/runtime/topology.d.ts +1 -1
  34. package/dist/runtime/traits/index.js +15 -16
  35. package/dist/runtime/types.d.ts +15 -1
  36. package/dist/runtime/validate/index.js +4 -4
  37. package/dist/shared/{mtaszv5a.js → 0wrea3jq.js} +102 -4
  38. package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
  39. package/dist/shared/{w79hsckn.js → 14x60fbf.js} +5 -5
  40. package/dist/shared/{ek2wt2dz.js → 16kvjebh.js} +4 -4
  41. package/dist/shared/{svncdeh5.js → 195pzzzz.js} +8 -8
  42. package/dist/shared/{gzaveazc.js → 1d9q9cv2.js} +29 -2
  43. package/dist/shared/{jvd0mqag.js → 3449rcae.js} +5 -5
  44. package/dist/shared/{14vx95q4.js → 35q0n9tz.js} +7 -7
  45. package/dist/shared/3bb7wsqt.js +99 -0
  46. package/dist/shared/{y6njgyda.js → 3t6kw83m.js} +2 -2
  47. package/dist/shared/{81ebdx9p.js → 4m6hskg8.js} +4 -4
  48. package/dist/shared/{xhfsfkgk.js → 4vbf83xx.js} +9 -2
  49. package/dist/shared/{bg3rym3g.js → 63f4ksbz.js} +2 -2
  50. package/dist/shared/{pt94kz7f.js → 6m78c8ss.js} +1 -1
  51. package/dist/shared/{5e3tf63j.js → 760ppr76.js} +14 -6
  52. package/dist/shared/{zm0ptry0.js → 7ghwamrf.js} +1 -1
  53. package/dist/shared/{xnxsed62.js → 9dr2qnx7.js} +14 -14
  54. package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
  55. package/dist/shared/{q5c6ngn3.js → a62rb2da.js} +1 -1
  56. package/dist/shared/{kb2sdhfb.js → ae4j5f42.js} +17 -1
  57. package/dist/shared/agsfb86s.js +233 -0
  58. package/dist/shared/{7k9grvf6.js → b6d6p0zc.js} +5 -5
  59. package/dist/shared/{tbrvgw6z.js → bah9nbg3.js} +17 -16
  60. package/dist/shared/{5fe3kbsh.js → bnby0esn.js} +1 -1
  61. package/dist/shared/bsek72fg.js +225 -0
  62. package/dist/shared/{1w508jbr.js → bxas03mq.js} +21 -17
  63. package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
  64. package/dist/shared/{tsvww22q.js → dpc2r7rb.js} +7 -7
  65. package/dist/shared/{vb6qfyve.js → e8zyaqvj.js} +2 -2
  66. package/dist/shared/{hyh73qk6.js → ecn8mfdq.js} +5 -5
  67. package/dist/shared/{gs74dbj5.js → f4jy1j7x.js} +27 -14
  68. package/dist/shared/{ttsqgp4p.js → fjpnhqan.js} +2 -2
  69. package/dist/shared/{xjk7hnn5.js → g5yc06ka.js} +2 -2
  70. package/dist/shared/{w72kgg4q.js → hfqmpasr.js} +6 -6
  71. package/dist/shared/{kr0jzbw2.js → hm5f8jby.js} +7 -7
  72. package/dist/shared/{dkxgzaqd.js → hqpxf4a4.js} +1 -1
  73. package/dist/shared/{cn957f8d.js → jebgrkeq.js} +3 -3
  74. package/dist/shared/{wa07eas9.js → jp36k7dp.js} +11 -11
  75. package/dist/shared/jx2m62cs.js +96 -0
  76. package/dist/shared/{sfz1ksn6.js → k86n8vq3.js} +2 -2
  77. package/dist/shared/{67txcrcw.js → kgwp4jdd.js} +4 -4
  78. package/dist/shared/{8skf0cam.js → kj9d8maq.js} +1 -1
  79. package/dist/shared/{aytqh5y2.js → m4xff2a6.js} +2 -2
  80. package/dist/shared/{zp9fmend.js → mfedzr74.js} +4 -4
  81. package/dist/shared/{ax7qv55k.js → mkrn359n.js} +60 -11
  82. package/dist/shared/{m6p12kbr.js → mnvjvqyp.js} +10 -10
  83. package/dist/shared/{1qa0qajz.js → mtw6jz76.js} +1 -1
  84. package/dist/shared/{1est4ezg.js → n05z9nwz.js} +3 -3
  85. package/dist/shared/{pbp1ss85.js → n0jmpgj1.js} +2 -2
  86. package/dist/shared/{ktz42yez.js → n41w4fbz.js} +5 -5
  87. package/dist/shared/{n816peh1.js → n454kcnw.js} +1 -1
  88. package/dist/shared/n7kg8mmx.js +61 -0
  89. package/dist/shared/{g6evj1j3.js → needfe47.js} +1 -1
  90. package/dist/shared/{2shdbn8q.js → njga14v4.js} +9 -9
  91. package/dist/shared/{vqrjpcqn.js → nmnsgj7x.js} +1 -1
  92. package/dist/shared/{b5pftnn2.js → p3xbdcvt.js} +14 -18
  93. package/dist/shared/{te5as7z7.js → p5nh3r8q.js} +3 -3
  94. package/dist/shared/{p6qc5gcp.js → pan0370z.js} +6 -6
  95. package/dist/shared/{79dt02vc.js → q0cqt2sp.js} +1 -1
  96. package/dist/shared/{5v3xf80k.js → qd9hhd8f.js} +1 -1
  97. package/dist/shared/{bm22fvzr.js → qfw14tna.js} +2 -2
  98. package/dist/shared/{9s0ypp87.js → sjk86yrx.js} +1 -1
  99. package/dist/shared/{3v7t1yrv.js → th3be82n.js} +2 -2
  100. package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
  101. package/dist/shared/{vczs8gd4.js → v1wad97q.js} +2 -2
  102. package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
  103. package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
  104. package/dist/shared/{bz84tkzm.js → wcrheftc.js} +2 -2
  105. package/dist/shared/{ab9gmbwy.js → wvdjznah.js} +5 -5
  106. package/dist/shared/{7mnme5tn.js → wz2a78mp.js} +1 -1
  107. package/dist/shared/{9y3mmmh1.js → xfhe73sb.js} +1 -1
  108. package/dist/shared/{je4axnm8.js → z581d7ny.js} +2 -2
  109. package/dist/shared/{x933k9a3.js → zbqbmmrp.js} +10 -10
  110. package/dist/shared/{rs73fca9.js → zgex00fd.js} +6 -6
  111. package/dist/shared/{jznfax0y.js → zq1he88x.js} +4 -4
  112. package/dist/tooling/cli.js +26 -13
  113. package/dist/tooling/driver-run.js +4971 -0
  114. package/dist/tooling/driver-test.d.ts +36 -0
  115. package/dist/tooling/migrate/commands.d.ts +2 -2
  116. package/dist/tooling/migrate/index.js +9 -9
  117. package/dist/tooling/migrate/project.d.ts +3 -0
  118. package/dist/tooling/shared/03k6res6.js +210 -0
  119. package/dist/tooling/shared/08kemxjd.js +10 -0
  120. package/dist/tooling/shared/2revefqt.js +209 -0
  121. package/dist/tooling/shared/2wtvc7rw.js +1425 -0
  122. package/dist/tooling/shared/345tbc2k.js +16 -0
  123. package/dist/tooling/shared/3m1hkg7z.js +344 -0
  124. package/dist/tooling/shared/3rrw5w8f.js +81 -0
  125. package/dist/tooling/shared/3tq8pnb8.js +131 -0
  126. package/dist/tooling/shared/417zdsk7.js +194 -0
  127. package/dist/tooling/shared/4d2w25vw.js +40 -0
  128. package/dist/tooling/shared/54tqkxja.js +51 -0
  129. package/dist/tooling/shared/5bvw2nev.js +12 -0
  130. package/dist/tooling/shared/6nyfyw70.js +231 -0
  131. package/dist/tooling/shared/72fyg4zv.js +160 -0
  132. package/dist/tooling/shared/733a1tq3.js +38 -0
  133. package/dist/tooling/shared/7ae7rjmn.js +20 -0
  134. package/dist/tooling/shared/7kms6fvj.js +20 -0
  135. package/dist/tooling/shared/8sqrsw3s.js +49 -0
  136. package/dist/tooling/shared/96ps4g1z.js +32 -0
  137. package/dist/tooling/shared/9kazs5p6.js +195 -0
  138. package/dist/tooling/shared/9xzm7hjg.js +38 -0
  139. package/dist/tooling/shared/a6pp9d12.js +49 -0
  140. package/dist/tooling/shared/a7q7t4n3.js +22 -0
  141. package/dist/tooling/shared/aftb2mwr.js +18 -0
  142. package/dist/tooling/shared/bz2dqhab.js +311 -0
  143. package/dist/tooling/shared/cmptmb4f.js +12 -0
  144. package/dist/tooling/shared/ddjtfgnx.js +177 -0
  145. package/dist/tooling/shared/djydjpqt.js +261 -0
  146. package/dist/tooling/shared/dw08f3m8.js +9 -0
  147. package/dist/tooling/shared/dy672fz6.js +16 -0
  148. package/dist/tooling/shared/dzx85q70.js +66 -0
  149. package/dist/tooling/shared/ec71zqgt.js +270 -0
  150. package/dist/tooling/shared/ep8zh3bk.js +6 -0
  151. package/dist/tooling/shared/f9mphxej.js +3789 -0
  152. package/dist/tooling/shared/fb9k2qwd.js +89 -0
  153. package/dist/tooling/shared/g9ad4n80.js +211 -0
  154. package/dist/tooling/shared/gfvtj6d0.js +94 -0
  155. package/dist/tooling/shared/gmcf9cxf.js +294 -0
  156. package/dist/tooling/shared/htnaj77v.js +17 -0
  157. package/dist/tooling/shared/j9t5s12a.js +7 -0
  158. package/dist/tooling/shared/jne7b93p.js +42 -0
  159. package/dist/tooling/shared/ma2340rx.js +118 -0
  160. package/dist/tooling/shared/mtrqn2hn.js +505 -0
  161. package/dist/tooling/shared/n4jqhpqz.js +27 -0
  162. package/dist/tooling/shared/nf7jmhfa.js +20 -0
  163. package/dist/tooling/shared/p7f08ktn.js +332 -0
  164. package/dist/tooling/shared/ppnnnvj8.js +13 -0
  165. package/dist/tooling/shared/pqy21k24.js +312 -0
  166. package/dist/tooling/shared/pw8fgahx.js +69 -0
  167. package/dist/tooling/shared/pwsytxm5.js +17 -0
  168. package/dist/tooling/shared/rf83gr2d.js +94 -0
  169. package/dist/tooling/shared/rq5kk8j6.js +401 -0
  170. package/dist/tooling/shared/rs1jb051.js +12 -0
  171. package/dist/tooling/shared/smn6kz1p.js +157 -0
  172. package/dist/tooling/shared/spk1jg3r.js +1696 -0
  173. package/dist/tooling/shared/tn8gay14.js +143 -0
  174. package/dist/tooling/shared/vraj6d74.js +42 -0
  175. package/dist/tooling/shared/vs0t6qt8.js +64 -0
  176. package/dist/tooling/shared/vx86qjv8.js +150 -0
  177. package/dist/tooling/shared/w7qe8sj1.js +140 -0
  178. package/dist/tooling/shared/wt7j7nf6.js +15 -0
  179. package/dist/tooling/shared/wwnekq5n.js +6 -0
  180. package/dist/tooling/shared/xhrnjch9.js +185 -0
  181. package/dist/tooling/shared/xjs6zqtc.js +190 -0
  182. package/dist/tooling/shared/y031jct9.js +16 -0
  183. package/dist/tooling/shared/y5656f0e.js +233 -0
  184. package/dist/tooling/shared/yfr8hzhm.js +604 -0
  185. package/dist/tooling/shared/yk9mp7vb.js +250 -0
  186. package/dist/tooling/shared/yw30vnq2.js +139 -0
  187. package/dist/tooling/shared/z8d7ptht.js +618 -0
  188. package/dist/tooling/shared/zhwnfyb2.js +9 -0
  189. package/dist/tooling/shared/zvnhh1n0.js +198 -0
  190. package/dist/tooling/testing/index.js +3 -3
  191. package/package.json +14 -2
  192. package/dist/shared/y34a8714.js +0 -150
  193. package/dist/shared/zy8r7qvz.js +0 -116
  194. package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
  195. package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
@@ -0,0 +1,250 @@
1
+ import {
2
+ stack2
3
+ } from "./cmptmb4f.js";
4
+ import {
5
+ updateSliceBody2,
6
+ rejectDuplicateTargets2,
7
+ emitSet2,
8
+ Sql2,
9
+ writeSet2,
10
+ rejectMixedSets2,
11
+ readClaim2,
12
+ rejectUpdateKeys2,
13
+ requireFilter2,
14
+ returningOption2,
15
+ expectOf2,
16
+ allowSet2,
17
+ noteGuarded2
18
+ } from "./spk1jg3r.js";
19
+ import"./3tq8pnb8.js";
20
+ import {
21
+ emitWhere,
22
+ projectExpr,
23
+ quote,
24
+ isRecord,
25
+ fail2
26
+ } from "./f9mphxej.js";
27
+
28
+ // src/runtime/version.ts
29
+ function planVersioned(schema, table, input, options, mods) {
30
+ if (mods.all !== undefined) {
31
+ fail2("OKM1120", `update on ${table.model.name} cannot use .all() with versioned().`, "Pass a per-row list with the version you read for each row.");
32
+ }
33
+ const allow = allowSet2(table, options.allow);
34
+ noteGuarded2(table, allow, "update");
35
+ const column = versionColumn(table);
36
+ const returning = returningOption2(table, options.returning);
37
+ const expect = expectOf2(options, mods);
38
+ if (Array.isArray(input) && input.length === 0) {
39
+ return {
40
+ statements: [],
41
+ outputs: outputsOf(undefined),
42
+ shape: "count",
43
+ expect,
44
+ versioned: { fields: [], sent: [] }
45
+ };
46
+ }
47
+ const rows = readRows(schema, table, input, allow, mods, column);
48
+ const fields = writtenFields(rows);
49
+ const sent = rows.map((row) => row.version);
50
+ const claim = Array.isArray(input) ? undefined : isRecord(input) ? readClaim2(input) : undefined;
51
+ const statement = claim !== undefined ? claimStatement(schema, table, rows[0], claim, column, returning) : targetStatement(schema, table, rows, column, returning);
52
+ const width = statement.params?.length ?? 0;
53
+ if (width > 30000) {
54
+ fail2("OKM1120", `update on ${table.model.name} is too large to check version in one statement.`, "Split the list.");
55
+ }
56
+ return {
57
+ statements: [statement],
58
+ outputs: outputsOf(returning),
59
+ shape: returning === undefined ? "count" : "rows",
60
+ expect,
61
+ versioned: { fields, sent }
62
+ };
63
+ }
64
+ function versionColumn(table) {
65
+ const column = table.columns.get("version");
66
+ if (column === undefined) {
67
+ fail2("OKM1120", `Table ${table.model.name} is versioned and has no version column.`);
68
+ }
69
+ return column;
70
+ }
71
+ function readRows(schema, table, input, allow, mods, column) {
72
+ if (Array.isArray(input)) {
73
+ if (input.length === 0)
74
+ fail2("OKM1120", "update set is empty.");
75
+ const rows = input.map((item) => readRow(schema, table, item, allow, mods, column, true));
76
+ rejectDuplicateTargets2(table, rows);
77
+ rejectMixedSets2(rows);
78
+ return rows;
79
+ }
80
+ return [readRow(schema, table, input, allow, mods, column, false)];
81
+ }
82
+ function readRow(schema, table, input, allow, mods, column, row) {
83
+ if (!isRecord(input))
84
+ fail2("OKM1121", "update expects { where, set, version } or a list of rows.");
85
+ rejectUpdateKeys2(input, row);
86
+ if (!Object.hasOwn(input, "version")) {
87
+ fail2("OKM1120", `update on ${table.model.name} needs the version you read.`, "Pass version from the row you read. If this write conflicts, reread and retry.");
88
+ }
89
+ const version = readVersion(input.version, table.model.name, column);
90
+ const set = writeSet2(table, input.set, allow, schema.tenancy);
91
+ if (Object.keys(set).length === 0)
92
+ fail2("OKM1120", "update set is empty.");
93
+ refusePath(schema, table, set);
94
+ const where = input.where !== undefined ? input.where : input.id !== undefined ? { id: input.id } : undefined;
95
+ requireFilter2(table, where, mods, "update");
96
+ return { where: stack2(where, mods.presets), set, version };
97
+ }
98
+ function readVersion(value, table, column) {
99
+ if (typeof value !== "number" || !Number.isSafeInteger(value)) {
100
+ fail2("OKM1121", `version on ${table} must be an integer.`, "Pass the version you read.");
101
+ }
102
+ column.encode(value);
103
+ return value;
104
+ }
105
+ function refusePath(schema, table, set) {
106
+ if (schema.tenancy?.isPath?.(table.model.name) !== true)
107
+ return;
108
+ const field = schema.tenancy.pathOf?.(table.model.name)?.[0]?.localField;
109
+ if (field === undefined || !Object.hasOwn(set, field))
110
+ return;
111
+ fail2("OKM1120", `update on ${table.model.name} cannot change ${field} and check version in one write.`, "Point it at a parent in a later update.");
112
+ }
113
+ function writtenFields(rows) {
114
+ const names = [];
115
+ for (const row of rows) {
116
+ for (const key of Object.keys(row.set))
117
+ if (!names.includes(key))
118
+ names.push(key);
119
+ }
120
+ return names;
121
+ }
122
+ function targetStatement(schema, table, rows, column, returning) {
123
+ const sql = new Sql2;
124
+ sql.text("with ");
125
+ for (let index = 0;index < rows.length; index += 1) {
126
+ const row = rows[index];
127
+ if (row === undefined)
128
+ continue;
129
+ if (index > 0)
130
+ sql.text(", ");
131
+ sql.text("m");
132
+ sql.text(String(index));
133
+ sql.text(" as (select s.ctid as tid, s.tableoid as toid, s.");
134
+ sql.text(quote(column.sql));
135
+ sql.text(" as okm_version from ");
136
+ sql.text(quote(table.model.sql));
137
+ sql.text(" as s");
138
+ emitWhere(schema, table, row.where, sql.sink(), "s", 0);
139
+ sql.text(" for update of s)");
140
+ }
141
+ sql.text(", gate as (select count(*)::int as n from (");
142
+ for (let index = 0;index < rows.length; index += 1) {
143
+ const row = rows[index];
144
+ if (row === undefined)
145
+ continue;
146
+ if (index > 0)
147
+ sql.text(" union all ");
148
+ sql.text("select 1 from m");
149
+ sql.text(String(index));
150
+ sql.text(" where okm_version is distinct from ");
151
+ sql.param(column.encode(row.version), column.dataType);
152
+ }
153
+ sql.text(") as okm_diff), updated as (");
154
+ updateSliceBody2(schema, table, rows, sql, true, {
155
+ afterWhere(body, index) {
156
+ const row = rows[index];
157
+ if (row === undefined)
158
+ return;
159
+ body.text(" and t.");
160
+ body.text(quote(column.sql));
161
+ body.text(" = ");
162
+ body.param(column.encode(row.version), column.dataType);
163
+ },
164
+ afterSet(body) {
165
+ bump(body, column);
166
+ }
167
+ });
168
+ sql.text(" and (select n from gate) = 0");
169
+ closeUpdated(sql, returning, "gate");
170
+ return sql.statement();
171
+ }
172
+ function claimStatement(schema, table, row, limit, column, returning) {
173
+ if (row === undefined)
174
+ fail2("OKM1120", "update set is empty.");
175
+ const sql = new Sql2;
176
+ sql.text("with claimed as (select s.tableoid as toid, s.ctid as tid from ");
177
+ sql.text(quote(table.model.sql));
178
+ sql.text(" as s");
179
+ emitWhere(schema, table, row.where, sql.sink(), "s", 0);
180
+ sql.text(" and s.");
181
+ sql.text(quote(column.sql));
182
+ sql.text(" = ");
183
+ sql.param(column.encode(row.version), column.dataType);
184
+ sql.text(" for update of s skip locked limit ");
185
+ sql.param(String(limit), "integer");
186
+ sql.text("), stale_free as (select 1 as hit from ");
187
+ sql.text(quote(table.model.sql));
188
+ sql.text(" as s");
189
+ emitWhere(schema, table, row.where, sql.sink(), "s", 0);
190
+ sql.text(" and s.");
191
+ sql.text(quote(column.sql));
192
+ sql.text(" is distinct from ");
193
+ sql.param(column.encode(row.version), column.dataType);
194
+ sql.text(" for update of s skip locked limit 1), updated as (update ");
195
+ sql.text(quote(table.model.sql));
196
+ sql.text(" as t set ");
197
+ emitSet2(sql, table, row.set, "t");
198
+ bump(sql, column);
199
+ sql.text(" where (t.tableoid, t.ctid) in (select toid, tid from claimed)");
200
+ closeUpdated(sql, returning, "claim");
201
+ return sql.statement();
202
+ }
203
+ function bump(sql, column) {
204
+ sql.text(", ");
205
+ sql.text(quote(column.sql));
206
+ sql.text(" = t.");
207
+ sql.text(quote(column.sql));
208
+ sql.text(" + 1");
209
+ }
210
+ function closeUpdated(sql, returning, source) {
211
+ const stale = source === "gate" ? "(select n from gate)" : "(case when (select count(*) from updated) > 0 then 0 else (select count(*)::int from stale_free) end)";
212
+ if (returning === undefined || returning.length === 0) {
213
+ sql.text(" returning 1) select ");
214
+ sql.text(stale);
215
+ sql.text(", (select count(*)::int from updated)");
216
+ return;
217
+ }
218
+ sql.text(" returning t.ctid as okm_tid");
219
+ for (let index = 0;index < returning.length; index += 1) {
220
+ const column = returning[index];
221
+ if (column === undefined)
222
+ continue;
223
+ sql.text(", ");
224
+ sql.text(projectExpr(`t.${quote(column.sql)}`, column.dataType));
225
+ sql.text(" as okm_");
226
+ sql.text(String(index));
227
+ }
228
+ sql.text(") select ");
229
+ sql.text(stale);
230
+ sql.text(", case when u.okm_tid is null then 0 else 1 end");
231
+ for (let index = 0;index < returning.length; index += 1) {
232
+ sql.text(", u.okm_");
233
+ sql.text(String(index));
234
+ }
235
+ sql.text(" from (select 1) as okm_one left join updated u on true");
236
+ }
237
+ function outputsOf(columns) {
238
+ const list = columns ?? [];
239
+ return {
240
+ fields: list.map((column, index) => ({
241
+ key: column.field,
242
+ at: index + 2,
243
+ decode: column.decode
244
+ })),
245
+ includes: []
246
+ };
247
+ }
248
+ export {
249
+ planVersioned
250
+ };
@@ -0,0 +1,139 @@
1
+ import {
2
+ driverErrors,
3
+ rejectClosed,
4
+ nextTransactionDepth,
5
+ EMPTY_NOTICES,
6
+ resultFrom
7
+ } from "./xhrnjch9.js";
8
+
9
+ // src/adapters/pg/session.ts
10
+ function noticeBuffer() {
11
+ let notices;
12
+ return {
13
+ push(notice) {
14
+ const severity = notice.severity ?? "";
15
+ const message = notice.message ?? "";
16
+ const code = notice.code !== undefined && notice.code.length > 0 ? notice.code : undefined;
17
+ const entry = code === undefined ? { severity, message } : { severity, message, code };
18
+ (notices ??= []).push(entry);
19
+ },
20
+ start() {
21
+ return notices?.length ?? 0;
22
+ },
23
+ since(start) {
24
+ if (notices === undefined || notices.length === start)
25
+ return EMPTY_NOTICES;
26
+ return notices.slice(start);
27
+ }
28
+ };
29
+ }
30
+
31
+ class WireSession {
32
+ canCancel;
33
+ transactionDepth = 0;
34
+ local = new Set;
35
+ send;
36
+ notices;
37
+ isClosed;
38
+ onEnter;
39
+ onLeave;
40
+ shared;
41
+ constructor(send, notices, isClosed, canCancel, onEnter, onLeave, shared) {
42
+ this.send = send;
43
+ this.notices = notices;
44
+ this.isClosed = isClosed;
45
+ this.canCancel = canCancel;
46
+ this.onEnter = onEnter;
47
+ this.onLeave = onLeave;
48
+ this.shared = shared;
49
+ }
50
+ query(text, params, watch) {
51
+ if (this.isClosed())
52
+ return rejectClosed();
53
+ const start = this.notices.start();
54
+ this.onEnter();
55
+ const pending = this.send(text, params);
56
+ if (watch === undefined) {
57
+ return pending.then((result) => {
58
+ this.onLeave();
59
+ this.note(text);
60
+ return resultFrom(result, this.notices.since(start));
61
+ }, (error) => {
62
+ this.onLeave();
63
+ return driverErrors().then((errors) => Promise.reject(errors.mapDriverError(stampQuery(error, text))));
64
+ });
65
+ }
66
+ return this.watched(pending, watch, start, text);
67
+ }
68
+ inTransaction() {
69
+ return this.transactionDepth > 0;
70
+ }
71
+ abandon() {
72
+ this.transactionDepth = 0;
73
+ }
74
+ depth() {
75
+ return this.transactionDepth;
76
+ }
77
+ cancel() {
78
+ for (const pending of this.local)
79
+ pending.cancel?.();
80
+ }
81
+ note(text) {
82
+ this.transactionDepth = nextTransactionDepth(this.transactionDepth, text);
83
+ }
84
+ track(pending) {
85
+ this.local.add(pending);
86
+ this.shared?.add(pending);
87
+ }
88
+ untrack(pending) {
89
+ this.local.delete(pending);
90
+ this.shared?.delete(pending);
91
+ }
92
+ watched(pending, watch, start, text) {
93
+ this.track(pending);
94
+ const onAbort = () => {
95
+ pending.cancel?.();
96
+ };
97
+ if (watch.signal.aborted)
98
+ onAbort();
99
+ else
100
+ watch.signal.addEventListener("abort", onAbort, { once: true });
101
+ return pending.then((result) => {
102
+ this.finishWatched(pending, watch, onAbort);
103
+ const why = watch.reason();
104
+ if (why === "timeout" || why === "cancelled")
105
+ return classify(why, watch);
106
+ this.note(text);
107
+ return resultFrom(result, this.notices.since(start));
108
+ }, (error) => {
109
+ this.finishWatched(pending, watch, onAbort);
110
+ return classify(stampQuery(error, text), watch);
111
+ });
112
+ }
113
+ finishWatched(pending, watch, onAbort) {
114
+ this.onLeave();
115
+ this.untrack(pending);
116
+ watch.signal.removeEventListener("abort", onAbort);
117
+ }
118
+ }
119
+ function stampQuery(error, text) {
120
+ if (typeof error === "object" && error !== null && !("query" in error))
121
+ Reflect.set(error, "query", text);
122
+ return error;
123
+ }
124
+ async function classify(error, watch) {
125
+ const errors = await driverErrors();
126
+ if (error instanceof errors.DriverError)
127
+ return Promise.reject(error);
128
+ const why = typeof error === "string" ? error : watch.reason();
129
+ if (why === "timeout") {
130
+ return Promise.reject(errors.timedOut(typeof error === "string" ? undefined : error));
131
+ }
132
+ const code = errors.errorField(error, "code") ?? errors.errorField(error, "errno");
133
+ if (why === "cancelled" || code === "57014") {
134
+ return Promise.reject(errors.cancelled(typeof error === "string" ? undefined : error));
135
+ }
136
+ return Promise.reject(errors.mapDriverError(error));
137
+ }
138
+
139
+ export { noticeBuffer, WireSession };