okmodel 0.7.0 → 0.9.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 (258) hide show
  1. package/README.md +14 -0
  2. package/dist/adapters/capabilities.d.ts +32 -0
  3. package/dist/adapters/failure.d.ts +1 -1
  4. package/dist/adapters/pg/bun-sql.d.ts +53 -0
  5. package/dist/adapters/pg/bunsql-extra.d.ts +1 -1
  6. package/dist/adapters/pg/bunsql.d.ts +1 -1
  7. package/dist/adapters/pg/neon-extra.d.ts +18 -0
  8. package/dist/adapters/pg/neon.d.ts +104 -0
  9. package/dist/adapters/pg/no-inflight-timeout.d.ts +1 -1
  10. package/dist/contracts/error.d.ts +1 -1
  11. package/dist/dialects/pg/ext/btree-gin.d.ts +26 -0
  12. package/dist/dialects/pg/ext/btree-gin.js +20 -0
  13. package/dist/dialects/pg/ext/btree-gist.d.ts +26 -0
  14. package/dist/dialects/pg/ext/btree-gist.js +20 -0
  15. package/dist/dialects/pg/ext/call.d.ts +53 -0
  16. package/dist/dialects/pg/ext/citext.js +1 -1
  17. package/dist/dialects/pg/ext/feature.d.ts +26 -0
  18. package/dist/dialects/pg/ext/fuzzystrmatch.d.ts +34 -0
  19. package/dist/dialects/pg/ext/fuzzystrmatch.js +33 -0
  20. package/dist/dialects/pg/ext/hstore.d.ts +41 -0
  21. package/dist/dialects/pg/ext/hstore.js +29 -0
  22. package/dist/dialects/pg/ext/index.d.ts +56 -0
  23. package/dist/dialects/pg/ext/index.js +1 -1
  24. package/dist/dialects/pg/ext/ltree.d.ts +41 -0
  25. package/dist/dialects/pg/ext/ltree.js +29 -0
  26. package/dist/dialects/pg/ext/pg-trgm.js +4 -13
  27. package/dist/dialects/pg/ext/pgcrypto.d.ts +33 -0
  28. package/dist/dialects/pg/ext/pgcrypto.js +33 -0
  29. package/dist/dialects/pg/ext/unaccent.d.ts +26 -0
  30. package/dist/dialects/pg/ext/unaccent.js +21 -0
  31. package/dist/dialects/pg/ext/using.d.ts +23 -0
  32. package/dist/dialects/pg/ext/versions.d.ts +36 -0
  33. package/dist/dialects/pg/external.d.ts +19 -0
  34. package/dist/dialects/pg/fn/index.d.ts +39 -1
  35. package/dist/dialects/pg/fn/index.js +118 -26
  36. package/dist/dialects/pg/index.d.ts +3 -0
  37. package/dist/dialects/pg/index.js +394 -14
  38. package/dist/dialects/pg/introspect.d.ts +11 -0
  39. package/dist/dialects/pg/operators.d.ts +1 -1
  40. package/dist/dialects/pg/ops/fragment.d.ts +119 -0
  41. package/dist/dialects/pg/ops/lane.d.ts +49 -0
  42. package/dist/dialects/pg/view/client.d.ts +14 -6
  43. package/dist/dialects/pg/view/index.d.ts +73 -1
  44. package/dist/dialects/pg/view/index.js +156 -5
  45. package/dist/dialects/pg/view/scratch.d.ts +11 -5
  46. package/dist/runtime/artifact-file.d.ts +22 -0
  47. package/dist/runtime/client.d.ts +10 -0
  48. package/dist/runtime/drift-detail.d.ts +2 -1
  49. package/dist/runtime/drift.d.ts +3 -10
  50. package/dist/runtime/otel.d.ts +105 -0
  51. package/dist/runtime/otel.js +97 -0
  52. package/dist/runtime/pg/bun.js +4 -4
  53. package/dist/runtime/pg/neon.d.ts +38 -0
  54. package/dist/runtime/pg/neon.js +64 -0
  55. package/dist/runtime/pg/pg.js +4 -4
  56. package/dist/runtime/pg/pglite.js +4 -4
  57. package/dist/runtime/pg/postgresjs.js +4 -4
  58. package/dist/runtime/plan.d.ts +1 -1
  59. package/dist/runtime/server-check.d.ts +36 -6
  60. package/dist/runtime/sql-fragment.d.ts +43 -0
  61. package/dist/runtime/tenancy/index.js +10 -10
  62. package/dist/runtime/topology.d.ts +1 -1
  63. package/dist/runtime/traits/index.js +16 -17
  64. package/dist/runtime/types.d.ts +15 -1
  65. package/dist/runtime/validate/index.js +4 -4
  66. package/dist/shared/{81ebdx9p.js → 0j6qe91y.js} +4 -4
  67. package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
  68. package/dist/shared/{gzaveazc.js → 1d9q9cv2.js} +29 -2
  69. package/dist/shared/{w79hsckn.js → 1mxm04fy.js} +5 -5
  70. package/dist/shared/{7k9grvf6.js → 2szgv6yj.js} +5 -5
  71. package/dist/shared/{gs74dbj5.js → 2zdxkt7b.js} +933 -111
  72. package/dist/shared/{m6p12kbr.js → 3456242y.js} +23 -23
  73. package/dist/shared/3bb7wsqt.js +99 -0
  74. package/dist/shared/{y6njgyda.js → 3t6kw83m.js} +2 -2
  75. package/dist/shared/{xhfsfkgk.js → 4vbf83xx.js} +9 -2
  76. package/dist/shared/{pt94kz7f.js → 5kyb3tqx.js} +1 -1
  77. package/dist/shared/61bmrmhr.js +35 -0
  78. package/dist/shared/{x933k9a3.js → 62b603gr.js} +10 -10
  79. package/dist/shared/{jgqj11w4.js → 6f0z3hzh.js} +4 -0
  80. package/dist/shared/{tsvww22q.js → 6nae0spm.js} +156 -95
  81. package/dist/shared/{mtaszv5a.js → 71n0jmhc.js} +102 -4
  82. package/dist/shared/{5e3tf63j.js → 760ppr76.js} +14 -6
  83. package/dist/shared/7ba5h6pb.js +17 -0
  84. package/dist/shared/{sfz1ksn6.js → 8jesqsrk.js} +2 -2
  85. package/dist/shared/{5v3xf80k.js → 8n688yjg.js} +1 -1
  86. package/dist/shared/{rs73fca9.js → 8qzkd9f3.js} +6 -6
  87. package/dist/shared/{ax7qv55k.js → 90sg0w5a.js} +202 -25
  88. package/dist/shared/{zm0ptry0.js → 99qp9vtg.js} +1 -1
  89. package/dist/shared/{xnxsed62.js → 9dr2qnx7.js} +14 -14
  90. package/dist/shared/{1w508jbr.js → 9dtgn1z2.js} +21 -17
  91. package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
  92. package/dist/shared/{q5c6ngn3.js → a62rb2da.js} +1 -1
  93. package/dist/shared/{te5as7z7.js → aksb89mn.js} +3 -3
  94. package/dist/shared/{bz84tkzm.js → bphrgwz9.js} +2 -2
  95. package/dist/shared/bsek72fg.js +225 -0
  96. package/dist/shared/{7mnme5tn.js → c3mvnq7a.js} +1 -1
  97. package/dist/shared/{p6qc5gcp.js → ccsmhv9r.js} +25 -7
  98. package/dist/shared/{pbp1ss85.js → cexb7z6b.js} +2 -2
  99. package/dist/shared/{ab9gmbwy.js → cf8zdz5p.js} +5 -5
  100. package/dist/shared/{jvd0mqag.js → ckz05z15.js} +5 -5
  101. package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
  102. package/dist/shared/{14vx95q4.js → dd5pmnky.js} +7 -7
  103. package/dist/shared/{vb6qfyve.js → ds229x4r.js} +2 -2
  104. package/dist/shared/{1qa0qajz.js → e275q7sd.js} +1 -1
  105. package/dist/shared/{zp9fmend.js → ebhz8vh6.js} +4 -4
  106. package/dist/shared/{hyh73qk6.js → ecn8mfdq.js} +5 -5
  107. package/dist/shared/{je4axnm8.js → fdsz3w80.js} +2 -2
  108. package/dist/shared/{9s0ypp87.js → fk9vef30.js} +85 -74
  109. package/dist/shared/{g6evj1j3.js → g89fmz5s.js} +1 -1
  110. package/dist/shared/{aytqh5y2.js → ghqzdp94.js} +2 -2
  111. package/dist/shared/h9811jjm.js +17 -0
  112. package/dist/shared/{dkxgzaqd.js → hqpxf4a4.js} +1 -1
  113. package/dist/shared/{8skf0cam.js → jpybhf98.js} +1 -1
  114. package/dist/shared/{67txcrcw.js → kgwp4jdd.js} +4 -4
  115. package/dist/shared/kzgrnckd.js +29 -0
  116. package/dist/shared/mazpbcdj.js +233 -0
  117. package/dist/shared/{kb2sdhfb.js → mfvx6kjx.js} +17 -1
  118. package/dist/shared/{svncdeh5.js → mgaq2sd3.js} +11 -8
  119. package/dist/shared/{5mtf6cj3.js → mvmm3xpb.js} +5 -2
  120. package/dist/shared/{b5pftnn2.js → myk8fswx.js} +66 -21
  121. package/dist/shared/{2shdbn8q.js → n306gqkd.js} +9 -9
  122. package/dist/shared/{n816peh1.js → n454kcnw.js} +1 -1
  123. package/dist/shared/n5whk3mt.js +665 -0
  124. package/dist/shared/n7kg8mmx.js +61 -0
  125. package/dist/shared/{vqrjpcqn.js → nmnsgj7x.js} +1 -1
  126. package/dist/shared/{tbrvgw6z.js → npdftanb.js} +19 -26
  127. package/dist/shared/{ek2wt2dz.js → pg4ezgyf.js} +11 -30
  128. package/dist/shared/{5fe3kbsh.js → pgsak1yw.js} +1 -1
  129. package/dist/shared/{bm22fvzr.js → qfw14tna.js} +2 -2
  130. package/dist/shared/{wa07eas9.js → qvwwp1mp.js} +62 -41
  131. package/dist/shared/rbxt795q.js +1766 -0
  132. package/dist/shared/{xjk7hnn5.js → s7he5e5d.js} +2 -2
  133. package/dist/shared/{w72kgg4q.js → ss2kv2rs.js} +6 -6
  134. package/dist/shared/stfa9xcw.js +450 -0
  135. package/dist/shared/{3v7t1yrv.js → th3be82n.js} +2 -2
  136. package/dist/shared/{79dt02vc.js → tr64w5p0.js} +1 -1
  137. package/dist/shared/{cn957f8d.js → tw1nvvfj.js} +3 -3
  138. package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
  139. package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
  140. package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
  141. package/dist/shared/{vczs8gd4.js → wvtjg5m3.js} +2 -2
  142. package/dist/shared/{9y3mmmh1.js → xfhe73sb.js} +1 -1
  143. package/dist/shared/xqacq37x.js +61 -0
  144. package/dist/shared/{1est4ezg.js → xtsydxjg.js} +3 -3
  145. package/dist/shared/xv8qj97g.js +96 -0
  146. package/dist/shared/{bg3rym3g.js → xwhdcrm4.js} +2 -2
  147. package/dist/shared/{kr0jzbw2.js → yvabyg9k.js} +7 -7
  148. package/dist/shared/yybhre6n.js +136 -0
  149. package/dist/shared/zdqf8k5d.js +8 -0
  150. package/dist/shared/{jznfax0y.js → zq1he88x.js} +4 -4
  151. package/dist/tooling/cli.js +108 -23
  152. package/dist/tooling/driver-run.js +4654 -0
  153. package/dist/tooling/driver-test.d.ts +36 -0
  154. package/dist/tooling/github/comment.d.ts +50 -0
  155. package/dist/tooling/github/post-comment.d.ts +17 -0
  156. package/dist/tooling/migrate/commands.d.ts +3 -2
  157. package/dist/tooling/migrate/config.d.ts +13 -0
  158. package/dist/tooling/migrate/export.d.ts +165 -0
  159. package/dist/tooling/migrate/ext-surface.d.ts +80 -0
  160. package/dist/tooling/migrate/ext.d.ts +31 -4
  161. package/dist/tooling/migrate/import-drizzle.d.ts +40 -0
  162. package/dist/tooling/migrate/index.d.ts +3 -0
  163. package/dist/tooling/migrate/index.js +55 -10
  164. package/dist/tooling/migrate/lint-rules.d.ts +18 -1
  165. package/dist/tooling/migrate/lint.d.ts +14 -1
  166. package/dist/tooling/migrate/place.d.ts +18 -0
  167. package/dist/tooling/migrate/plan-json.d.ts +65 -0
  168. package/dist/tooling/migrate/project.d.ts +13 -1
  169. package/dist/tooling/migrate/pull-emit.d.ts +98 -0
  170. package/dist/tooling/migrate/pull-routines.d.ts +126 -0
  171. package/dist/tooling/migrate/pull-verify.d.ts +26 -0
  172. package/dist/tooling/migrate/pull.d.ts +62 -0
  173. package/dist/tooling/migrate/reprint.d.ts +32 -0
  174. package/dist/tooling/migrate/sandbox.d.ts +8 -2
  175. package/dist/tooling/migrate/schema-api.d.ts +43 -0
  176. package/dist/tooling/migrate/sql-lex.d.ts +18 -0
  177. package/dist/tooling/shared/04svnxxj.js +344 -0
  178. package/dist/tooling/shared/0j0jtse1.js +13 -0
  179. package/dist/tooling/shared/0r05zhyq.js +618 -0
  180. package/dist/tooling/shared/1800eymw.js +49 -0
  181. package/dist/tooling/shared/35zemrmf.js +12 -0
  182. package/dist/tooling/shared/3rmaz3pq.js +140 -0
  183. package/dist/tooling/shared/3yn79q5m.js +12 -0
  184. package/dist/tooling/shared/54tqkxja.js +51 -0
  185. package/dist/tooling/shared/57btdkgm.js +209 -0
  186. package/dist/tooling/shared/5bmksndh.js +118 -0
  187. package/dist/tooling/shared/5p8km5jb.js +38 -0
  188. package/dist/tooling/shared/5x3pf400.js +185 -0
  189. package/dist/tooling/shared/5zrzffnk.js +6 -0
  190. package/dist/tooling/shared/62fxpc1p.js +332 -0
  191. package/dist/tooling/shared/68tf18v4.js +20 -0
  192. package/dist/tooling/shared/6vk28rjp.js +98 -0
  193. package/dist/tooling/shared/76pv6qff.js +9 -0
  194. package/dist/tooling/shared/7aews1zg.js +311 -0
  195. package/dist/tooling/shared/7b3xp9gc.js +195 -0
  196. package/dist/tooling/shared/7kms6fvj.js +20 -0
  197. package/dist/tooling/shared/7pxncnzs.js +40 -0
  198. package/dist/tooling/shared/829fjxyw.js +198 -0
  199. package/dist/tooling/shared/8m5znpdt.js +66 -0
  200. package/dist/tooling/shared/8yr7ges1.js +211 -0
  201. package/dist/tooling/shared/96ps4g1z.js +32 -0
  202. package/dist/tooling/shared/9qr9rkbh.js +143 -0
  203. package/dist/tooling/shared/9sfbtwsk.js +49 -0
  204. package/dist/tooling/shared/9wsnsvbf.js +10 -0
  205. package/dist/tooling/shared/a2xe04bm.js +18 -0
  206. package/dist/tooling/shared/a4pzghha.js +20 -0
  207. package/dist/tooling/shared/am04v8na.js +233 -0
  208. package/dist/tooling/shared/asgr07mp.js +194 -0
  209. package/dist/tooling/shared/c0xevn1h.js +312 -0
  210. package/dist/tooling/shared/dhatassp.js +134 -0
  211. package/dist/tooling/shared/ezqn88nj.js +1696 -0
  212. package/dist/tooling/shared/f77nnfqy.js +231 -0
  213. package/dist/tooling/shared/fh07z1dt.js +15 -0
  214. package/dist/tooling/shared/gqwevek4.js +81 -0
  215. package/dist/tooling/shared/hfq3n3bd.js +4116 -0
  216. package/dist/tooling/shared/htnaj77v.js +17 -0
  217. package/dist/tooling/shared/j664qjrt.js +64 -0
  218. package/dist/tooling/shared/jpgmjsx3.js +38 -0
  219. package/dist/tooling/shared/jr2nmr81.js +497 -0
  220. package/dist/tooling/shared/jsjjz875.js +139 -0
  221. package/dist/tooling/shared/kbqnrs1x.js +1425 -0
  222. package/dist/tooling/shared/kz715295.js +94 -0
  223. package/dist/tooling/shared/m3xt8b1h.js +22 -0
  224. package/dist/tooling/shared/m4hhb8aa.js +9 -0
  225. package/dist/tooling/shared/mw5npye0.js +16 -0
  226. package/dist/tooling/shared/n4jqhpqz.js +27 -0
  227. package/dist/tooling/shared/nxq95eb6.js +42 -0
  228. package/dist/tooling/shared/qartgazh.js +70 -0
  229. package/dist/tooling/shared/rcywj2w8.js +190 -0
  230. package/dist/tooling/shared/s6qha57m.js +16 -0
  231. package/dist/tooling/shared/shjs0379.js +150 -0
  232. package/dist/tooling/shared/sjwkt1pg.js +16 -0
  233. package/dist/tooling/shared/stebqyyd.js +401 -0
  234. package/dist/tooling/shared/t4xveemq.js +250 -0
  235. package/dist/tooling/shared/t6zjeake.js +261 -0
  236. package/dist/tooling/shared/tcwpjvxe.js +9 -0
  237. package/dist/tooling/shared/tpssp7ac.js +160 -0
  238. package/dist/tooling/shared/v6j1ep6w.js +42 -0
  239. package/dist/tooling/shared/vwr2y833.js +270 -0
  240. package/dist/tooling/shared/w17sj05d.js +7 -0
  241. package/dist/tooling/shared/w5d89rb4.js +131 -0
  242. package/dist/tooling/shared/wbwq1jsa.js +157 -0
  243. package/dist/tooling/shared/wezxf3h8.js +17 -0
  244. package/dist/tooling/shared/yb4kd19s.js +12 -0
  245. package/dist/tooling/shared/ybdew6j7.js +294 -0
  246. package/dist/tooling/shared/yfedr1zb.js +6 -0
  247. package/dist/tooling/shared/yhp829bx.js +177 -0
  248. package/dist/tooling/shared/ytk1tjs0.js +604 -0
  249. package/dist/tooling/shared/zs9aymcp.js +210 -0
  250. package/dist/tooling/shared/zx3v9phv.js +8 -0
  251. package/dist/tooling/testing/index.js +3 -3
  252. package/package.json +50 -9
  253. package/dist/shared/ktz42yez.js +0 -113
  254. package/dist/shared/ttsqgp4p.js +0 -71
  255. package/dist/shared/y34a8714.js +0 -150
  256. package/dist/shared/zy8r7qvz.js +0 -116
  257. package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
  258. package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
@@ -0,0 +1,311 @@
1
+ import {
2
+ queryHandle,
3
+ readHandle,
4
+ readCall,
5
+ attachHttp
6
+ } from "./jr2nmr81.js";
7
+ import {
8
+ OkmError,
9
+ throwNamed,
10
+ emitWhere,
11
+ emitOrder,
12
+ refuseHidden,
13
+ rejectKeys,
14
+ readLimit,
15
+ projectExpr,
16
+ cell,
17
+ indexes,
18
+ quote,
19
+ list,
20
+ isRecord,
21
+ fail2
22
+ } from "./hfq3n3bd.js";
23
+
24
+ // src/runtime/aggregate.ts
25
+ var BUCKET = Symbol.for("okmodel.bucket");
26
+ var bucketChunk;
27
+ function loadBucketGroup() {
28
+ return bucketChunk ??= import("./57btdkgm.js");
29
+ }
30
+ var OPTIONS = [
31
+ "where",
32
+ "groupBy",
33
+ "count",
34
+ "sum",
35
+ "avg",
36
+ "min",
37
+ "max",
38
+ "orderBy",
39
+ "limit",
40
+ "route",
41
+ "signal",
42
+ "timeout"
43
+ ];
44
+ var NUMERIC = /^(smallint|integer|bigint|real|double precision|numeric|decimal)\b/;
45
+ var AS_NUMBER = (wire) => Number(wire);
46
+ var AS_TEXT = (wire) => wire;
47
+ var UNORDERED = /^(json|jsonb|bytea|point|line|tsvector)\b|\[\]$/;
48
+ var FUNCTIONS = [
49
+ { option: "sum", tag: "s", numeric: true },
50
+ { option: "avg", tag: "a", numeric: true },
51
+ { option: "min", tag: "n", numeric: false },
52
+ { option: "max", tag: "x", numeric: false }
53
+ ];
54
+ function build(session, table, options, mods, view) {
55
+ try {
56
+ if (seesBucket(options))
57
+ return bucketHandle(session, table, options, mods, view);
58
+ return plan(session, table, options, mods, view);
59
+ } catch (error) {
60
+ throw error instanceof OkmError ? attachHttp(session.http, error) : error;
61
+ }
62
+ }
63
+ function bucketHandle(session, table, options, mods, view) {
64
+ const open = () => loadBucketGroup().then((mod) => {
65
+ try {
66
+ return { it: plan(session, table, options, mods, view, mod) };
67
+ } catch (error) {
68
+ throw error instanceof OkmError ? attachHttp(session.http, error) : error;
69
+ }
70
+ });
71
+ return queryHandle(() => open().then((box) => box.it), {
72
+ inspect: () => open().then((box) => box.it.inspect()),
73
+ sql: () => open().then((box) => box.it.sql()),
74
+ all: (reason) => build(session, table, options, { ...mods, all: reason }, view)
75
+ });
76
+ }
77
+ function seesBucket(options) {
78
+ if (!isRecord(options))
79
+ return false;
80
+ const groupBy = options.groupBy;
81
+ if (!Array.isArray(groupBy))
82
+ return false;
83
+ for (const item of groupBy) {
84
+ if (typeof item === "object" && item !== null && BUCKET in item)
85
+ return true;
86
+ }
87
+ return false;
88
+ }
89
+ function plan(session, table, options, mods, view, buckets) {
90
+ const record = isRecord(options) ? options : {};
91
+ rejectKeys(record, OPTIONS, "aggregate");
92
+ const indexed = indexes(session.schema).get(table);
93
+ if (indexed === undefined)
94
+ fail2("OKM1120", `Table ${table} is not in the schema.`);
95
+ const spec = parse(indexed, record, buckets);
96
+ if (spec.groups.length > 0 && record.limit === undefined && mods.all === undefined) {
97
+ fail2("OKM1101", "aggregate() with groupBy needs a limit, or .all(reason) for every group.");
98
+ }
99
+ const names = groupNames(spec.groups);
100
+ const orderBy = record.orderBy;
101
+ if (orderBy !== undefined) {
102
+ if (!isRecord(orderBy))
103
+ fail2("OKM1120", "orderBy must be an object of fields.");
104
+ for (const field of Object.keys(orderBy)) {
105
+ if (!names.includes(field)) {
106
+ const column = indexed.columns.get(field);
107
+ if (column !== undefined)
108
+ refuseHidden(column);
109
+ throwNamed("OKM1120", field, names, `aggregate() orders by a groupBy field. Accepted names: ${list(names)}.`);
110
+ }
111
+ }
112
+ }
113
+ if (record.limit !== undefined)
114
+ readLimit(record.limit);
115
+ const base = readCall("find", table, {
116
+ where: record.where,
117
+ orderBy,
118
+ limit: record.limit,
119
+ signal: record.signal,
120
+ timeout: record.timeout,
121
+ route: record.route
122
+ }, mods.all, session.scope, session.schema.model[table], session.schema, view);
123
+ const call = { ...base, op: "aggregate", build: statement(spec, buckets) };
124
+ return readHandle(session, table, call, mods, (compiled, rows) => decode(compiled, rows));
125
+ }
126
+ function parse(table, record, buckets) {
127
+ const grouped = readGroups(table, record.groupBy, buckets);
128
+ const count = record.count === true;
129
+ if (record.count !== undefined && typeof record.count !== "boolean") {
130
+ fail2("OKM1120", "count is true when you want a row count.");
131
+ }
132
+ const calls = [];
133
+ for (const { option, tag, numeric } of FUNCTIONS) {
134
+ for (const column of columns(table, record[option], option)) {
135
+ const fits = numeric ? NUMERIC.test(column.dataType) : !UNORDERED.test(column.dataType);
136
+ if (!fits) {
137
+ fail2("OKM1124", `${option} does not apply to ${column.dataType} column ${column.field}. ${numeric ? "sum and avg take integer, real, and numeric columns." : "min and max need an ordered type."}`);
138
+ }
139
+ calls.push({ option, tag, column, decode: numeric ? sumDecode(column) : column.decode });
140
+ }
141
+ }
142
+ if (!count && calls.length === 0 && grouped.groups.length === 0) {
143
+ fail2("OKM1120", "aggregate() needs count, sum, avg, min, max, or groupBy.");
144
+ }
145
+ return { groups: grouped.groups, bucketed: grouped.bucketed, count, calls };
146
+ }
147
+ function sumDecode(column) {
148
+ const kind = typeof (column.decode?.("0") ?? "");
149
+ if (kind === "string")
150
+ return AS_TEXT;
151
+ if (kind === "number")
152
+ return AS_NUMBER;
153
+ return fail2("OKM1124", `sum and avg need a column whose value is a number or a string. ${column.field} reads as ${kind}.`);
154
+ }
155
+ function columns(table, value, option) {
156
+ if (value === undefined)
157
+ return [];
158
+ if (!Array.isArray(value))
159
+ fail2("OKM1120", `${option} must be a list of field names.`);
160
+ const out = [];
161
+ for (const name of value) {
162
+ const column = typeof name === "string" ? table.columns.get(name) : undefined;
163
+ if (typeof name !== "string" || column === undefined) {
164
+ throwNamed("OKM1120", String(name), table.names, `Field ${String(name)} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
165
+ }
166
+ if (column.hidden) {
167
+ fail2("OKM1120", `Field ${column.field} is hidden, so ${option} cannot read it.`);
168
+ }
169
+ out.push(column);
170
+ }
171
+ return out;
172
+ }
173
+ function groupNames(groups) {
174
+ const names = [];
175
+ for (const group of groups)
176
+ names.push(group.kind === "field" ? group.column.field : group.as);
177
+ return names;
178
+ }
179
+ function readGroups(table, value, buckets) {
180
+ if (value === undefined)
181
+ return { groups: [], bucketed: false };
182
+ if (!Array.isArray(value))
183
+ fail2("OKM1120", "groupBy must be a list of field names.");
184
+ const fields = new Set;
185
+ const aliases = new Set;
186
+ const groups = [];
187
+ let bucketed = false;
188
+ for (const item of value) {
189
+ if (typeof item === "object" && item !== null && BUCKET in item) {
190
+ if (buckets === undefined)
191
+ fail2("OKM1120", "bucket group");
192
+ groups.push(buckets.readBucket(table, item, fields, aliases));
193
+ bucketed = true;
194
+ continue;
195
+ }
196
+ const column = typeof item === "string" ? table.columns.get(item) : undefined;
197
+ if (typeof item !== "string" || column === undefined) {
198
+ throwNamed("OKM1120", String(item), table.names, `Field ${String(item)} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
199
+ }
200
+ if (column.hidden) {
201
+ fail2("OKM1120", `Field ${column.field} is hidden, so groupBy cannot read it.`);
202
+ }
203
+ if (aliases.has(column.field)) {
204
+ fail2("OKM1120", `group field ${column.field} clashes with a bucket as.`);
205
+ }
206
+ fields.add(column.field);
207
+ groups.push({ kind: "field", column });
208
+ }
209
+ return { groups, bucketed };
210
+ }
211
+ function statement(spec, buckets) {
212
+ return (schema, table, sink, outputs, call) => {
213
+ sink.mark(`aggregate|${table.model.name}|g:${groupMark(spec.groups)}|c:${String(spec.count)}|${spec.calls.map((item) => `${item.tag}:${item.column.field}`).join(",")}|`);
214
+ sink.text("select ");
215
+ const wrote = { at: 0 };
216
+ for (const group of spec.groups) {
217
+ if (group.kind === "field") {
218
+ put(sink, outputs, wrote, projectExpr(`t.${quote(group.column.sql)}`, group.column.dataType), {
219
+ key: `g:${group.column.field}`,
220
+ decode: group.column.decode
221
+ });
222
+ } else {
223
+ if (buckets === undefined)
224
+ fail2("OKM1120", "bucket group");
225
+ buckets.writeBucket(sink, outputs, wrote, group);
226
+ }
227
+ }
228
+ if (spec.count)
229
+ put(sink, outputs, wrote, "count(*)::text", { key: "c:", decode: undefined });
230
+ for (const item of spec.calls) {
231
+ const ref = `t.${quote(item.column.sql)}`;
232
+ const expr = item.option === "sum" || item.option === "avg" ? `${item.option}(${ref})::text` : projectExpr(`${item.option}(${ref})`, item.column.dataType);
233
+ put(sink, outputs, wrote, expr, {
234
+ key: `${item.tag}:${item.column.field}`,
235
+ decode: item.decode
236
+ });
237
+ }
238
+ sink.text(" from ");
239
+ sink.text(quote(table.model.sql));
240
+ sink.text(" t");
241
+ emitWhere(schema, table, call.where, sink, "t", 0);
242
+ if (spec.groups.length > 0) {
243
+ sink.text(" group by ");
244
+ if (spec.bucketed) {
245
+ if (buckets === undefined)
246
+ fail2("OKM1120", "bucket group");
247
+ buckets.writeGrouped(sink, groupNames(spec.groups), call.orderBy);
248
+ } else {
249
+ sink.text(spec.groups.map((group) => fieldRef(group)).join(", "));
250
+ if (isRecord(call.orderBy) && Object.keys(call.orderBy).length > 0) {
251
+ emitOrder(table, call.orderBy, sink, "t");
252
+ } else {
253
+ sink.text(" order by ");
254
+ sink.text(spec.groups.map((group) => `${fieldRef(group)} asc nulls last`).join(", "));
255
+ }
256
+ }
257
+ }
258
+ if (call.limit !== undefined) {
259
+ const limit = String(call.limit);
260
+ sink.text(" limit ");
261
+ sink.param(limit);
262
+ sink.mark(`l:${limit}`);
263
+ }
264
+ if (typeof call.all === "string")
265
+ sink.mark(`all:${call.all}`);
266
+ };
267
+ }
268
+ function groupMark(groups) {
269
+ const parts = [];
270
+ for (const group of groups) {
271
+ parts.push(group.kind === "field" ? group.column.field : `b:${group.column.field}:${group.as}:${group.unit}:${String(group.shift)}`);
272
+ }
273
+ return parts.join(",");
274
+ }
275
+ function fieldRef(group) {
276
+ if (group.kind !== "field")
277
+ return fail2("OKM1120", "bucket group");
278
+ return `t.${quote(group.column.sql)}`;
279
+ }
280
+ function put(sink, outputs, wrote, expr, out) {
281
+ if (wrote.at > 0)
282
+ sink.text(", ");
283
+ sink.text(expr);
284
+ outputs?.fields.push({ key: out.key, at: wrote.at, decode: out.decode });
285
+ wrote.at += 1;
286
+ }
287
+ function decode(compiled, rows) {
288
+ const items = [];
289
+ for (const row of rows) {
290
+ const item = {};
291
+ for (const field of compiled.outputs.fields) {
292
+ const value = row[field.at];
293
+ const tag = field.key.slice(0, 2);
294
+ const name = field.key.slice(2);
295
+ if (tag === "g:") {
296
+ item[name] = cell(value, field.decode);
297
+ } else if (tag === "c:") {
298
+ item.count = Number(value ?? 0);
299
+ } else {
300
+ const group = tag === "s:" ? "sum" : tag === "a:" ? "avg" : tag === "n:" ? "min" : "max";
301
+ const into = item[group] ??= {};
302
+ into[name] = cell(value, field.decode);
303
+ }
304
+ }
305
+ items.push(item);
306
+ }
307
+ return items;
308
+ }
309
+ export {
310
+ build
311
+ };
@@ -0,0 +1,195 @@
1
+ import {
2
+ emitSqlValue
3
+ } from "./ybdew6j7.js";
4
+ import {
5
+ assertOperatorFits,
6
+ sqlType,
7
+ assertNoControl,
8
+ assertBoundText,
9
+ assertRegconfig,
10
+ textArray
11
+ } from "./w5d89rb4.js";
12
+ import {
13
+ isOperator,
14
+ operatorName,
15
+ operatorValue,
16
+ installOperatorSql,
17
+ quote,
18
+ isRecord,
19
+ fail2
20
+ } from "./hfq3n3bd.js";
21
+
22
+ // src/runtime/operator-sql.ts
23
+ function emitStructured(table, column, ref, name, value, sink, order) {
24
+ if (name === "sql") {
25
+ emitSqlValue(table, ref, value, sink);
26
+ return;
27
+ }
28
+ if (name === "contains" || name === "containedBy" || name === "overlaps") {
29
+ emitContainment(column, ref, name, value, sink);
30
+ return;
31
+ }
32
+ if (name === "hasKey" || name === "hasAnyKey") {
33
+ emitJsonKey(column, ref, name, value, sink);
34
+ return;
35
+ }
36
+ if (name === "path") {
37
+ emitPath(column, ref, value, sink);
38
+ return;
39
+ }
40
+ if (name === "matches") {
41
+ emitMatches(column, ref, value, sink);
42
+ return;
43
+ }
44
+ if (name === "relevance") {
45
+ if (order !== true)
46
+ fail2("OKM1121", `relevance on ${column.field} belongs in orderBy.`);
47
+ emitRelevance(column, ref, value, sink);
48
+ sink.text(" desc");
49
+ sink.mark(`o:${column.field}:relevance`);
50
+ return;
51
+ }
52
+ if (name === "similar" || name === "wordSimilar") {
53
+ emitTrigram(column, ref, name, value, sink);
54
+ return;
55
+ }
56
+ assertOperatorFits(column, name);
57
+ fail2("OKM1121", `${name} is not a value operator on ${column.field}. Use has, none, or every on a relation.`);
58
+ }
59
+ function emitContainment(column, ref, name, value, sink) {
60
+ assertOperatorFits(column, name);
61
+ const op = name === "contains" ? " @> " : name === "containedBy" ? " <@ " : " && ";
62
+ sink.text(ref);
63
+ sink.text(op);
64
+ sink.param(column.encode(value));
65
+ sink.text("::");
66
+ sink.text(sqlType(column.dataType, column));
67
+ }
68
+ function emitJsonKey(column, ref, name, value, sink) {
69
+ assertOperatorFits(column, name);
70
+ if (name === "hasKey") {
71
+ if (typeof value !== "string")
72
+ fail2("OKM1121", `hasKey on ${column.field} needs a key.`);
73
+ assertBoundText(value, `key on ${column.field}`);
74
+ sink.text("jsonb_exists(");
75
+ sink.text(ref);
76
+ sink.text(", ");
77
+ sink.param(value);
78
+ sink.text(")");
79
+ return;
80
+ }
81
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
82
+ fail2("OKM1121", `hasAnyKey on ${column.field} needs a list of keys.`);
83
+ }
84
+ sink.text("jsonb_exists_any(");
85
+ sink.text(ref);
86
+ sink.text(", ");
87
+ sink.param(textArray(value, `key on ${column.field}`));
88
+ sink.text("::text[])");
89
+ }
90
+ function emitPath(column, ref, value, sink) {
91
+ assertOperatorFits(column, "path");
92
+ if (!isRecord(value) || !Array.isArray(value.segments) || !isOperator(value.op)) {
93
+ fail2("OKM1121", `path on ${column.field} needs segments and a comparison.`);
94
+ }
95
+ const segments = value.segments;
96
+ if (segments.length === 0 || segments.some((item) => typeof item !== "string")) {
97
+ fail2("OKM1121", `path on ${column.field} needs a list of segments.`);
98
+ }
99
+ const opName = operatorName(value.op);
100
+ if (opName !== "eq" && opName !== "lt" && opName !== "lte" && opName !== "gt" && opName !== "gte") {
101
+ fail2("OKM1121", `path on ${column.field} compares with eq, lt, lte, gt, or gte.`);
102
+ }
103
+ const operand = operatorValue(value.op);
104
+ const cast = pathCast(column, operand);
105
+ const sql = opName === "eq" ? " = " : opName === "lt" ? " < " : opName === "lte" ? " <= " : opName === "gt" ? " > " : " >= ";
106
+ sink.text("(");
107
+ sink.text(ref);
108
+ sink.text(" #>> ");
109
+ sink.param(textArray(segments, `path on ${column.field}`));
110
+ sink.text("::text[])::");
111
+ sink.text(cast);
112
+ sink.text(sql);
113
+ sink.param(pathParam(operand));
114
+ }
115
+ function pathCast(column, operand) {
116
+ if (typeof operand === "number")
117
+ return "numeric";
118
+ if (typeof operand === "boolean")
119
+ return "boolean";
120
+ if (typeof operand === "string")
121
+ return "text";
122
+ fail2("OKM1121", `path on ${column.field} compares a string, number, or boolean.`);
123
+ }
124
+ function pathParam(operand) {
125
+ if (typeof operand === "number")
126
+ return String(operand);
127
+ if (typeof operand === "boolean")
128
+ return operand ? "true" : "false";
129
+ if (typeof operand === "string")
130
+ return operand;
131
+ return "";
132
+ }
133
+ var MATCH_FN = {
134
+ natural: "websearch_to_tsquery",
135
+ "all-words": "plainto_tsquery",
136
+ phrase: "phraseto_tsquery",
137
+ advanced: "to_tsquery"
138
+ };
139
+ function readMatch(column, value, label) {
140
+ if (!isRecord(value) || typeof value.query !== "string" || value.query.length === 0) {
141
+ fail2("OKM1121", `${label} on ${column.field} needs text to look for.`);
142
+ }
143
+ assertNoControl(value.query, `${label} on ${column.field}`);
144
+ const match = value.match ?? "natural";
145
+ const fn = typeof match === "string" ? MATCH_FN[match] : undefined;
146
+ if (fn === undefined) {
147
+ fail2("OKM1121", `${label} on ${column.field} match must be natural, all-words, phrase, or advanced.`);
148
+ }
149
+ if (value.language === undefined)
150
+ return { fn, language: undefined, query: value.query };
151
+ if (typeof value.language !== "string") {
152
+ fail2("OKM1121", `${label} on ${column.field} language must be a name such as english.`);
153
+ }
154
+ assertRegconfig(value.language);
155
+ return { fn, language: value.language, query: value.query };
156
+ }
157
+ function emitTsquery(sink, query) {
158
+ sink.mark(query.language === undefined ? `:${query.fn}` : `:${query.fn}:lang`);
159
+ sink.text(query.fn);
160
+ sink.text("(");
161
+ if (query.language !== undefined) {
162
+ sink.param(query.language);
163
+ sink.text("::regconfig, ");
164
+ }
165
+ sink.param(query.query);
166
+ sink.text(")");
167
+ }
168
+ function emitMatches(column, ref, value, sink) {
169
+ assertOperatorFits(column, "matches");
170
+ sink.text(ref);
171
+ sink.text(" @@ ");
172
+ emitTsquery(sink, readMatch(column, value, "matches"));
173
+ }
174
+ function emitRelevance(column, ref, value, sink) {
175
+ assertOperatorFits(column, "relevance");
176
+ sink.text("ts_rank(");
177
+ sink.text(ref);
178
+ sink.text(", ");
179
+ emitTsquery(sink, readMatch(column, value, "relevance"));
180
+ sink.text(")");
181
+ }
182
+ function emitTrigram(column, ref, name, value, sink) {
183
+ if (!isRecord(value) || typeof value.query !== "string" || typeof value.schema !== "string") {
184
+ fail2("OKM1121", `${name} on ${column.field} needs query text.`);
185
+ }
186
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.schema)) {
187
+ fail2("OKM1121", `${name} on ${column.field} needs an extension schema name.`);
188
+ }
189
+ sink.text(ref);
190
+ sink.text(" operator(");
191
+ sink.text(quote(value.schema));
192
+ sink.text(name === "similar" ? ".%) " : ".<%) ");
193
+ sink.param(value.query);
194
+ }
195
+ installOperatorSql(emitStructured);
@@ -0,0 +1,20 @@
1
+ // src/adapters/pg/cursor.ts
2
+ async function* cursorStream(run, text, params) {
3
+ const name = "okm_stream";
4
+ await run("BEGIN");
5
+ try {
6
+ await run(`DECLARE ${name} NO SCROLL CURSOR FOR ${text}`, params);
7
+ for (;; ) {
8
+ const chunk = await run(`FETCH 64 FROM ${name}`);
9
+ if (chunk.rows.length === 0)
10
+ break;
11
+ yield chunk.rows;
12
+ }
13
+ } finally {
14
+ await run("ROLLBACK").catch(() => {
15
+ return;
16
+ });
17
+ }
18
+ }
19
+
20
+ export { cursorStream };
@@ -0,0 +1,40 @@
1
+ import {
2
+ rejectClosed
3
+ } from "./5x3pf400.js";
4
+ import {
5
+ isConnectionLost
6
+ } from "./hfq3n3bd.js";
7
+
8
+ // src/adapters/pg/reserved.ts
9
+ var RESET_ALL = "RESET ALL";
10
+ var UNLOCK = "SELECT pg_advisory_unlock_all()";
11
+ async function resetSession2(depth, run) {
12
+ if (depth > 0)
13
+ await run("ROLLBACK").catch(() => {
14
+ return;
15
+ });
16
+ try {
17
+ await run(RESET_ALL);
18
+ await run(UNLOCK);
19
+ } catch {
20
+ await run("ROLLBACK").catch(() => {
21
+ return;
22
+ });
23
+ await run(RESET_ALL);
24
+ await run(UNLOCK);
25
+ }
26
+ }
27
+ async function resetQueried2(session) {
28
+ await resetSession2(session.inTransaction() ? 1 : 0, (text) => text === "ROLLBACK" ? session.rollback() : session.query(text, undefined, undefined));
29
+ }
30
+ function refuseWhenLost2(lost, run) {
31
+ if (lost.on)
32
+ return rejectClosed();
33
+ return run().catch((error) => {
34
+ if (isConnectionLost(error))
35
+ lost.on = true;
36
+ throw error;
37
+ });
38
+ }
39
+
40
+ export { resetSession2, resetQueried2, refuseWhenLost2 };