okmodel 0.0.0 → 0.1.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 (147) hide show
  1. package/README.md +44 -1
  2. package/dist/adapters/capabilities.d.ts +62 -0
  3. package/dist/adapters/error.d.ts +91 -0
  4. package/dist/adapters/failure.d.ts +39 -0
  5. package/dist/adapters/pg/batch.d.ts +36 -0
  6. package/dist/adapters/pg/call.d.ts +59 -0
  7. package/dist/adapters/pg/pglite.d.ts +21 -0
  8. package/dist/adapters/pg/postgres-extra.d.ts +43 -0
  9. package/dist/adapters/pg/postgresjs.d.ts +95 -0
  10. package/dist/adapters/pg/result.d.ts +30 -0
  11. package/dist/contracts/catalog/build.d.ts +18 -0
  12. package/dist/contracts/catalog/document.d.ts +79 -0
  13. package/dist/contracts/catalog/enum.d.ts +35 -0
  14. package/dist/contracts/catalog/identifier.d.ts +71 -0
  15. package/dist/contracts/catalog/identity.d.ts +98 -0
  16. package/dist/contracts/catalog/index.d.ts +11 -0
  17. package/dist/contracts/catalog/json.d.ts +17 -0
  18. package/dist/contracts/catalog/object.d.ts +142 -0
  19. package/dist/contracts/catalog/order.d.ts +43 -0
  20. package/dist/contracts/catalog/rewrite.d.ts +18 -0
  21. package/dist/contracts/catalog/types.d.ts +292 -0
  22. package/dist/contracts/catalog/words.d.ts +13 -0
  23. package/dist/contracts/connection.d.ts +33 -0
  24. package/dist/contracts/driver.d.ts +163 -0
  25. package/dist/contracts/error.d.ts +298 -0
  26. package/dist/contracts/index.d.ts +11 -0
  27. package/dist/contracts/index.js +16 -0
  28. package/dist/contracts/internal.d.ts +15 -0
  29. package/dist/contracts/internal.js +68 -0
  30. package/dist/contracts/nearest.d.ts +15 -0
  31. package/dist/contracts/rows.d.ts +84 -0
  32. package/dist/contracts/sha256.d.ts +14 -0
  33. package/dist/contracts/utf8.d.ts +33 -0
  34. package/dist/dialects/pg/array-literal.d.ts +25 -0
  35. package/dist/dialects/pg/bool.d.ts +46 -0
  36. package/dist/dialects/pg/column.d.ts +386 -0
  37. package/dist/dialects/pg/compile.d.ts +81 -0
  38. package/dist/dialects/pg/custom.d.ts +21 -0
  39. package/dist/dialects/pg/ddl.d.ts +70 -0
  40. package/dist/dialects/pg/decimal.d.ts +62 -0
  41. package/dist/dialects/pg/declarations.d.ts +34 -0
  42. package/dist/dialects/pg/emit.d.ts +18 -0
  43. package/dist/dialects/pg/enum.d.ts +30 -0
  44. package/dist/dialects/pg/errors.d.ts +30 -0
  45. package/dist/dialects/pg/finite.d.ts +15 -0
  46. package/dist/dialects/pg/geometry.d.ts +55 -0
  47. package/dist/dialects/pg/index.d.ts +45 -0
  48. package/dist/dialects/pg/index.js +1821 -0
  49. package/dist/dialects/pg/integer.d.ts +96 -0
  50. package/dist/dialects/pg/introspect.d.ts +43 -0
  51. package/dist/dialects/pg/json.d.ts +43 -0
  52. package/dist/dialects/pg/keys.d.ts +32 -0
  53. package/dist/dialects/pg/misuse.d.ts +31 -0
  54. package/dist/dialects/pg/model.d.ts +71 -0
  55. package/dist/dialects/pg/namespace.d.ts +63 -0
  56. package/dist/dialects/pg/network.d.ts +28 -0
  57. package/dist/dialects/pg/operators.d.ts +71 -0
  58. package/dist/dialects/pg/ops/between.d.ts +10 -0
  59. package/dist/dialects/pg/ops/contains.d.ts +8 -0
  60. package/dist/dialects/pg/ops/endsWith.d.ts +8 -0
  61. package/dist/dialects/pg/ops/eq.d.ts +9 -0
  62. package/dist/dialects/pg/ops/every.d.ts +9 -0
  63. package/dist/dialects/pg/ops/gt.d.ts +9 -0
  64. package/dist/dialects/pg/ops/gte.d.ts +9 -0
  65. package/dist/dialects/pg/ops/has.d.ts +9 -0
  66. package/dist/dialects/pg/ops/ilike.d.ts +8 -0
  67. package/dist/dialects/pg/ops/inList.d.ts +9 -0
  68. package/dist/dialects/pg/ops/inc.d.ts +13 -0
  69. package/dist/dialects/pg/ops/like.d.ts +8 -0
  70. package/dist/dialects/pg/ops/lt.d.ts +9 -0
  71. package/dist/dialects/pg/ops/lte.d.ts +9 -0
  72. package/dist/dialects/pg/ops/none.d.ts +9 -0
  73. package/dist/dialects/pg/ops/not.d.ts +9 -0
  74. package/dist/dialects/pg/ops/notIn.d.ts +9 -0
  75. package/dist/dialects/pg/ops/or.d.ts +9 -0
  76. package/dist/dialects/pg/ops/startsWith.d.ts +8 -0
  77. package/dist/dialects/pg/quote.d.ts +24 -0
  78. package/dist/dialects/pg/range.d.ts +50 -0
  79. package/dist/dialects/pg/relations.d.ts +45 -0
  80. package/dist/dialects/pg/schema.d.ts +77 -0
  81. package/dist/dialects/pg/search.d.ts +23 -0
  82. package/dist/dialects/pg/table.d.ts +201 -0
  83. package/dist/dialects/pg/temporal.d.ts +211 -0
  84. package/dist/dialects/pg/text.d.ts +44 -0
  85. package/dist/dialects/pg/time.d.ts +46 -0
  86. package/dist/okm.js +2 -0
  87. package/dist/okmodel.js +2 -0
  88. package/dist/runtime/client.d.ts +47 -0
  89. package/dist/runtime/conflict.d.ts +38 -0
  90. package/dist/runtime/drift-detail.d.ts +32 -0
  91. package/dist/runtime/drift.d.ts +29 -0
  92. package/dist/runtime/include.d.ts +15 -0
  93. package/dist/runtime/pg/pglite.d.ts +25 -0
  94. package/dist/runtime/pg/pglite.js +48 -0
  95. package/dist/runtime/pg/postgresjs.d.ts +29 -0
  96. package/dist/runtime/pg/postgresjs.js +62 -0
  97. package/dist/runtime/plan.d.ts +167 -0
  98. package/dist/runtime/tx.d.ts +29 -0
  99. package/dist/runtime/types.d.ts +369 -0
  100. package/dist/runtime/write.d.ts +48 -0
  101. package/dist/shared/4j72449d.js +37 -0
  102. package/dist/shared/79ggp945.js +148 -0
  103. package/dist/shared/7ck0dtry.js +259 -0
  104. package/dist/shared/8b04d28c.js +14 -0
  105. package/dist/shared/ax16zpvm.js +171 -0
  106. package/dist/shared/ckb1p0a4.js +566 -0
  107. package/dist/shared/cn0n68ft.js +16 -0
  108. package/dist/shared/dynq16vb.js +81 -0
  109. package/dist/shared/f5thc1s0.js +1050 -0
  110. package/dist/shared/fgqgsb5z.js +281 -0
  111. package/dist/shared/g2v6gnc8.js +347 -0
  112. package/dist/shared/g5fhqmwe.js +188 -0
  113. package/dist/shared/gk7cs7sp.js +566 -0
  114. package/dist/shared/hd293j9g.js +98 -0
  115. package/dist/shared/j5cn2963.js +701 -0
  116. package/dist/shared/kynx7vbm.js +1490 -0
  117. package/dist/shared/mkjmqjv4.js +456 -0
  118. package/dist/shared/mtkwv8wx.js +18 -0
  119. package/dist/shared/ngk8gj61.js +40 -0
  120. package/dist/shared/p0cbr3g2.js +79 -0
  121. package/dist/shared/px90pf9p.js +396 -0
  122. package/dist/shared/qk3hxfja.js +83 -0
  123. package/dist/shared/tb4ze1tr.js +119 -0
  124. package/dist/shared/vkm3q4x1.js +30 -0
  125. package/dist/shared/w8samvk1.js +18 -0
  126. package/dist/shared/xy79j5hq.js +177 -0
  127. package/dist/shared/y9m15dfv.js +888 -0
  128. package/dist/shared/ycwz42az.js +412 -0
  129. package/dist/shared/zhc5vmgf.js +257 -0
  130. package/dist/tooling/cli.d.ts +1 -0
  131. package/dist/tooling/cli.js +193 -0
  132. package/dist/tooling/errors/registry.d.ts +33 -0
  133. package/dist/tooling/migrate/apply.d.ts +86 -0
  134. package/dist/tooling/migrate/commands.d.ts +21 -0
  135. package/dist/tooling/migrate/config.d.ts +48 -0
  136. package/dist/tooling/migrate/dev.d.ts +16 -0
  137. package/dist/tooling/migrate/equal.d.ts +15 -0
  138. package/dist/tooling/migrate/files.d.ts +19 -0
  139. package/dist/tooling/migrate/index.d.ts +7 -0
  140. package/dist/tooling/migrate/index.js +7 -0
  141. package/dist/tooling/migrate/plan.d.ts +76 -0
  142. package/dist/tooling/migrate/policy.d.ts +78 -0
  143. package/dist/tooling/migrate/project.d.ts +69 -0
  144. package/dist/tooling/migrate/status.d.ts +74 -0
  145. package/dist/tooling/migrate/values.d.ts +29 -0
  146. package/package.json +94 -7
  147. package/dist/index.js +0 -0
@@ -0,0 +1,566 @@
1
+ import {
2
+ emitWhere,
3
+ selectedColumns,
4
+ rejectKeys,
5
+ projectExpr,
6
+ decodeRow,
7
+ indexes,
8
+ quote,
9
+ isRecord,
10
+ fail
11
+ } from "./f5thc1s0.js";
12
+ import {
13
+ isOperator,
14
+ operatorName,
15
+ operatorValue
16
+ } from "./cn0n68ft.js";
17
+ import {
18
+ OkmError2,
19
+ throwNamed2
20
+ } from "./ycwz42az.js";
21
+
22
+ // src/runtime/tx.ts
23
+ async function runWrite(pool, statements, options) {
24
+ if (statements.length === 0)
25
+ return [];
26
+ const first = statements[0];
27
+ if (statements.length === 1 && first !== undefined) {
28
+ return [await pool.execute(first.text, first.params, options)];
29
+ }
30
+ return pool.batch(statements, options);
31
+ }
32
+
33
+ // src/runtime/write.ts
34
+ var WRITE_PARAM_BUDGET = 2048;
35
+ var INSERT_OPTIONS = ["expect", "onConflict", "returning", "signal", "timeout"];
36
+ var FILTER_OPTIONS = ["expect", "returning", "signal", "timeout"];
37
+ async function executeWrite(host, op, table, input, options, mods) {
38
+ const planned = await planWrite(host.schema, op, table, input, options, mods);
39
+ if (planned.statements.length === 0)
40
+ return finish([], planned, table);
41
+ const results = await runWrite(host.pool, planned.statements, callOptions(options));
42
+ return finish(results, planned, table);
43
+ }
44
+ async function explainWrite(schema, op, table, input, options, mods) {
45
+ const planned = await planWrite(schema, op, table, input, options, mods);
46
+ return { statements: planned.statements };
47
+ }
48
+ async function planWrite(schema, op, tableName, input, options, mods) {
49
+ const table = indexes(schema).get(tableName);
50
+ if (table === undefined) {
51
+ fail("OKM1120", `Table ${tableName} is not in the schema.`);
52
+ }
53
+ const record = isRecord(options) ? options : {};
54
+ rejectKeys(record, op === "insert" ? INSERT_OPTIONS : FILTER_OPTIONS, op);
55
+ if (op === "insert")
56
+ return planInsert(table, input, record, mods);
57
+ if (op === "update")
58
+ return planUpdate(schema, table, input, record, mods);
59
+ return planDelete(schema, table, input, record, mods);
60
+ }
61
+ async function planInsert(table, input, options, mods) {
62
+ const many = Array.isArray(input);
63
+ const rows = (many ? input : [input]).map((row) => insertRow(table, row));
64
+ const columns = writtenColumns(table, rows);
65
+ const returning = selectedColumns(table, options.returning);
66
+ const outputs = outputsOf(returning);
67
+ const clause = returningClause(returning, undefined);
68
+ const expect = expectOf(options, mods);
69
+ const shape = many ? "rows" : "row";
70
+ if (columns.length === 0) {
71
+ const text = `insert into ${quote(table.model.sql)} default values${clause}`;
72
+ return {
73
+ statements: rows.map(() => ({ text })),
74
+ outputs,
75
+ shape,
76
+ expect,
77
+ keys: undefined,
78
+ keyFields: undefined
79
+ };
80
+ }
81
+ const conflictMod = options.onConflict === undefined || options.onConflict === "error" ? undefined : await import("./79ggp945.js");
82
+ const conflict = conflictMod?.readConflict(table, options.onConflict);
83
+ const chunks = chunkRows(rows.map((row) => cellsFor(table, columns, row)));
84
+ const statements = [];
85
+ const keys = [];
86
+ let offset = 0;
87
+ for (const chunk of chunks) {
88
+ const slice = rows.slice(offset, offset + chunk.length);
89
+ offset += chunk.length;
90
+ const built = insertHead(table, columns, chunk);
91
+ if (conflict === undefined || conflictMod === undefined) {
92
+ statements.push(withParams(`${built.text}${clause}`, built.params));
93
+ continue;
94
+ }
95
+ const keyRows = conflict.kind === "return" ? slice.map((row) => keyWire(conflict.columns, row)) : [];
96
+ for (const row of keyRows)
97
+ keys.push([...row]);
98
+ statements.push(conflictMod.finishInsert(built.text, clause, built.params ?? [], conflict, table, returning, keyRows));
99
+ }
100
+ return {
101
+ statements,
102
+ outputs,
103
+ shape,
104
+ expect,
105
+ keys: conflict?.kind === "return" ? keys : undefined,
106
+ keyFields: conflict?.kind === "return" ? conflict.columns.map((column) => column.field) : undefined
107
+ };
108
+ }
109
+ function planUpdate(schema, table, input, options, mods) {
110
+ const returning = returningOption(table, options.returning);
111
+ const outputs = outputsOf(returning);
112
+ const expect = expectOf(options, mods);
113
+ if (Array.isArray(input)) {
114
+ const rows = input.map((item) => updateItem(table, item));
115
+ return {
116
+ statements: updateList(schema, table, rows, returning),
117
+ outputs,
118
+ shape: returning === undefined ? "count" : "rows",
119
+ expect,
120
+ keys: undefined,
121
+ keyFields: undefined
122
+ };
123
+ }
124
+ if (!isRecord(input))
125
+ fail("OKM1121", "update expects { where, set } or a list of rows.");
126
+ const set = writeSet(table, input.set);
127
+ requireFilter(table, input.where, mods, "update");
128
+ if (Object.keys(set).length === 0)
129
+ fail("OKM1120", "update set is empty.");
130
+ const sql = new Sql;
131
+ sql.text("update ");
132
+ sql.text(quote(table.model.sql));
133
+ sql.text(" as t set ");
134
+ emitSet(sql, table, set, "t");
135
+ emitFilter(schema, table, input.where, sql, "t");
136
+ sql.text(returningClause(returning, "t"));
137
+ return {
138
+ statements: [sql.statement()],
139
+ outputs,
140
+ shape: returning === undefined ? "count" : "rows",
141
+ expect,
142
+ keys: undefined,
143
+ keyFields: undefined
144
+ };
145
+ }
146
+ function planDelete(schema, table, input, options, mods) {
147
+ if (!isRecord(input))
148
+ fail("OKM1121", "delete expects { where }.");
149
+ rejectKeys(input, ["where"], "delete");
150
+ requireFilter(table, input.where, mods, "delete");
151
+ const returning = returningOption(table, options.returning);
152
+ const sql = new Sql;
153
+ sql.text("delete from ");
154
+ sql.text(quote(table.model.sql));
155
+ sql.text(" as t");
156
+ emitFilter(schema, table, input.where, sql, "t");
157
+ sql.text(returningClause(returning, "t"));
158
+ return {
159
+ statements: [sql.statement()],
160
+ outputs: outputsOf(returning),
161
+ shape: returning === undefined ? "count" : "rows",
162
+ expect: expectOf(options, mods),
163
+ keys: undefined,
164
+ keyFields: undefined
165
+ };
166
+ }
167
+ function finish(results, planned, table) {
168
+ if (planned.shape === "count") {
169
+ let count = 0;
170
+ for (const result of results)
171
+ count += result.count;
172
+ checkExpect(count, planned.expect, table, "write");
173
+ return { count };
174
+ }
175
+ const decoded = [];
176
+ for (const result of results) {
177
+ for (const row of result.rows)
178
+ decoded.push(decodeRow(planned.outputs, row));
179
+ }
180
+ const rows = planned.keys === undefined || planned.keyFields === undefined ? decoded : orderByKeys(decoded, planned.keyFields, planned.keys);
181
+ checkExpect(rows.length, planned.expect, table, "insert");
182
+ if (planned.shape === "row")
183
+ return rows[0] ?? null;
184
+ return rows;
185
+ }
186
+ function orderByKeys(rows, fields, keys) {
187
+ const found = new Map;
188
+ for (const row of rows)
189
+ found.set(fields.map((field) => wireKey(row[field])).join("\x00"), row);
190
+ const ordered = [];
191
+ for (const key of keys) {
192
+ const row = found.get(key.map((value) => value ?? "").join("\x00"));
193
+ if (row !== undefined)
194
+ ordered.push(row);
195
+ }
196
+ return ordered;
197
+ }
198
+ function wireKey(value) {
199
+ if (typeof value === "string")
200
+ return value;
201
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
202
+ return String(value);
203
+ }
204
+ return "";
205
+ }
206
+ function insertHead(table, columns, rows) {
207
+ const params = [];
208
+ const lists = [];
209
+ for (const row of rows) {
210
+ const slots = [];
211
+ for (const cell of row) {
212
+ if (cell.kind === "default") {
213
+ slots.push("default");
214
+ continue;
215
+ }
216
+ params.push(cell.kind === "null" ? null : cell.wire);
217
+ slots.push(`$${String(params.length)}::${cell.dataType}`);
218
+ }
219
+ lists.push(`(${slots.join(", ")})`);
220
+ }
221
+ const names = columns.map((column) => quote(column.sql)).join(", ");
222
+ return {
223
+ text: `insert into ${quote(table.model.sql)} (${names}) values ${lists.join(", ")}`,
224
+ params
225
+ };
226
+ }
227
+ function updateList(schema, table, rows, returning) {
228
+ if (rows.length === 0)
229
+ return [];
230
+ const width = Math.max(1, Object.keys(rows[0]?.set ?? {}).length + 2);
231
+ const size = Math.max(1, Math.floor(WRITE_PARAM_BUDGET / (width * 2)));
232
+ const statements = [];
233
+ for (let index = 0;index < rows.length; index += size) {
234
+ statements.push(updateSlice(schema, table, rows.slice(index, index + size), returning));
235
+ }
236
+ return statements;
237
+ }
238
+ function updateSlice(schema, table, rows, returning) {
239
+ const fields = [];
240
+ const seen = new Set;
241
+ for (const row of rows) {
242
+ for (const key of Object.keys(row.set)) {
243
+ if (seen.has(key))
244
+ continue;
245
+ seen.add(key);
246
+ const column = table.columns.get(key);
247
+ if (column !== undefined)
248
+ fields.push(column);
249
+ }
250
+ }
251
+ if (fields.length === 0)
252
+ fail("OKM1120", "update set is empty.");
253
+ const sql = new Sql;
254
+ sql.text("update ");
255
+ sql.text(quote(table.model.sql));
256
+ sql.text(" as t set ");
257
+ for (let field = 0;field < fields.length; field += 1) {
258
+ const column = fields[field];
259
+ if (column === undefined)
260
+ continue;
261
+ if (field > 0)
262
+ sql.text(", ");
263
+ sql.text(quote(column.sql));
264
+ sql.text(" = case");
265
+ for (const row of rows) {
266
+ sql.text(" when ");
267
+ emitBare(schema, table, row.where, sql, "t");
268
+ sql.text(" then ");
269
+ const value = row.set[column.field];
270
+ if (value === undefined)
271
+ sql.text(`t.${quote(column.sql)}`);
272
+ else
273
+ emitValue(sql, column, value, "t");
274
+ }
275
+ sql.text(" else t.");
276
+ sql.text(quote(column.sql));
277
+ sql.text(" end");
278
+ }
279
+ sql.text(" where ");
280
+ for (let index = 0;index < rows.length; index += 1) {
281
+ const row = rows[index];
282
+ if (row === undefined)
283
+ continue;
284
+ if (index > 0)
285
+ sql.text(" or ");
286
+ sql.text("(");
287
+ emitBare(schema, table, row.where, sql, "t");
288
+ sql.text(")");
289
+ }
290
+ sql.text(returningClause(returning, "t"));
291
+ return sql.statement();
292
+ }
293
+ function emitSet(sql, table, set, alias) {
294
+ const keys = Object.keys(set);
295
+ for (let index = 0;index < keys.length; index += 1) {
296
+ const key = keys[index];
297
+ if (key === undefined)
298
+ continue;
299
+ const column = table.columns.get(key);
300
+ if (column === undefined)
301
+ continue;
302
+ if (index > 0)
303
+ sql.text(", ");
304
+ sql.text(quote(column.sql));
305
+ sql.text(" = ");
306
+ emitValue(sql, column, set[key], alias);
307
+ }
308
+ }
309
+ function emitValue(sql, column, value, alias) {
310
+ if (isOperator(value)) {
311
+ if (operatorName(value) !== "inc") {
312
+ fail("OKM1121", `Field ${column.field} received an operator. set accepts a value or inc.`);
313
+ }
314
+ const amount = operatorValue(value);
315
+ if (typeof amount === "object" && amount !== null) {
316
+ fail("OKM1121", `inc on ${column.field} needs a value.`);
317
+ }
318
+ sql.text(`${alias}.${quote(column.sql)} + `);
319
+ sql.param(column.encode(amount), column.dataType);
320
+ return;
321
+ }
322
+ if (value === null) {
323
+ sql.text(`null::${column.dataType}`);
324
+ return;
325
+ }
326
+ if (typeof value === "object") {
327
+ fail("OKM1121", `Field ${column.field} received an object. Pass a value or inc.`);
328
+ }
329
+ sql.param(column.encode(value), column.dataType);
330
+ }
331
+ function emitFilter(schema, table, where, sql, alias) {
332
+ emitWhere(schema, table, where, sql.sink(), alias, 0);
333
+ }
334
+ function emitBare(schema, table, where, sql, alias) {
335
+ let dropped = false;
336
+ const sink = {
337
+ text(value) {
338
+ if (!dropped) {
339
+ dropped = true;
340
+ if (value === " where " || value === " and ")
341
+ return;
342
+ }
343
+ sql.text(value);
344
+ },
345
+ param(encoded) {
346
+ sql.param(encoded, "");
347
+ },
348
+ mark() {}
349
+ };
350
+ emitWhere(schema, table, where, sink, alias, 0);
351
+ if (!dropped) {
352
+ fail("OKM1102", `update on ${table.model.name} needs a where for each row.`);
353
+ }
354
+ }
355
+
356
+ class Sql {
357
+ parts = [];
358
+ params = [];
359
+ text(value) {
360
+ this.parts.push(value);
361
+ }
362
+ param(wire, dataType) {
363
+ this.params.push(wire);
364
+ const slot = `$${String(this.params.length)}`;
365
+ this.parts.push(dataType.length === 0 ? slot : `${slot}::${dataType}`);
366
+ }
367
+ sink() {
368
+ return {
369
+ text: (value) => {
370
+ this.text(value);
371
+ },
372
+ param: (encoded) => {
373
+ this.param(encoded, "");
374
+ },
375
+ mark() {}
376
+ };
377
+ }
378
+ statement() {
379
+ return this.params.length === 0 ? { text: this.parts.join("") } : { text: this.parts.join(""), params: this.params };
380
+ }
381
+ }
382
+ function insertRow(table, value) {
383
+ if (!isRecord(value))
384
+ fail("OKM1121", "insert expects an object or a list of objects.");
385
+ const row = {};
386
+ for (const key of Object.keys(value)) {
387
+ const column = table.columns.get(key);
388
+ if (column === undefined)
389
+ continue;
390
+ if (!column.writable)
391
+ refuse(table.model.name, column);
392
+ if (value[key] !== undefined)
393
+ row[key] = value[key];
394
+ }
395
+ return row;
396
+ }
397
+ function cellsFor(table, columns, row) {
398
+ return columns.map((column) => {
399
+ if (!Object.hasOwn(row, column.field))
400
+ return { kind: "default" };
401
+ const value = row[column.field];
402
+ if (value === null)
403
+ return { kind: "null", dataType: column.dataType };
404
+ if (typeof value === "object") {
405
+ fail("OKM1121", `Field ${table.model.name}.${column.field} received an object.`);
406
+ }
407
+ return { kind: "value", wire: column.encode(value), dataType: column.dataType };
408
+ });
409
+ }
410
+ function writtenColumns(table, rows) {
411
+ const present = new Set;
412
+ for (const row of rows) {
413
+ for (const key of Object.keys(row))
414
+ present.add(key);
415
+ }
416
+ const columns = [];
417
+ for (const column of table.model.columns) {
418
+ if (column.writable && present.has(column.field))
419
+ columns.push(column);
420
+ }
421
+ return columns;
422
+ }
423
+ function writeSet(table, value) {
424
+ if (!isRecord(value))
425
+ fail("OKM1121", "set must be an object of fields.");
426
+ const set = {};
427
+ for (const key of Object.keys(value)) {
428
+ if (value[key] === undefined)
429
+ continue;
430
+ const column = table.columns.get(key);
431
+ if (column === undefined) {
432
+ throwNamed2("OKM1120", key, table.names, `Field ${key} is not on ${table.model.name}. Accepted names: ${table.names.join(", ")}.`);
433
+ }
434
+ if (!column.writable)
435
+ refuse(table.model.name, column);
436
+ set[key] = value[key];
437
+ }
438
+ return set;
439
+ }
440
+ function updateItem(table, value) {
441
+ if (!isRecord(value))
442
+ fail("OKM1121", "update expects { where, set } or a list of rows.");
443
+ const set = writeSet(table, value.set);
444
+ if (value.where !== undefined)
445
+ return { where: value.where, set };
446
+ if (value.id !== undefined)
447
+ return { where: { id: value.id }, set };
448
+ fail("OKM1102", `update on ${table.model.name} needs id or where for each row.`);
449
+ }
450
+ function requireFilter(table, where, mods, op) {
451
+ if (mods.all !== undefined) {
452
+ if (mods.all.trim().length === 0) {
453
+ fail("OKM1102", `${op} on ${table.model.name} needs a where. .all needs a reason.`);
454
+ }
455
+ return;
456
+ }
457
+ if (isOperator(where))
458
+ return;
459
+ if (isRecord(where) && Object.keys(where).length > 0)
460
+ return;
461
+ fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
462
+ }
463
+ function chunkRows(rows) {
464
+ const chunks = [];
465
+ let current = [];
466
+ let count = 0;
467
+ for (const row of rows) {
468
+ let cost = 0;
469
+ for (const cell of row)
470
+ if (cell.kind !== "default")
471
+ cost += 1;
472
+ if (current.length > 0 && count + cost > WRITE_PARAM_BUDGET) {
473
+ chunks.push(current);
474
+ current = [];
475
+ count = 0;
476
+ }
477
+ current.push(row);
478
+ count += cost;
479
+ }
480
+ if (current.length > 0)
481
+ chunks.push(current);
482
+ return chunks;
483
+ }
484
+ function withParams(text, params) {
485
+ if (params === undefined || params.length === 0)
486
+ return { text };
487
+ return { text, params };
488
+ }
489
+ function keyWire(columns, row) {
490
+ return columns.map((column) => {
491
+ const value = row[column.field];
492
+ if (value === undefined || value === null)
493
+ return null;
494
+ if (typeof value === "object")
495
+ return null;
496
+ return column.encode(value);
497
+ });
498
+ }
499
+ function returningOption(table, value) {
500
+ if (value === undefined)
501
+ return;
502
+ return selectedColumns(table, value);
503
+ }
504
+ function returningClause(columns, alias) {
505
+ if (columns === undefined || columns.length === 0)
506
+ return "";
507
+ const parts = columns.map((column) => {
508
+ const sql = alias === undefined ? quote(column.sql) : `${alias}.${quote(column.sql)}`;
509
+ return projectExpr(sql, column.dataType);
510
+ });
511
+ return ` returning ${parts.join(", ")}`;
512
+ }
513
+ function outputsOf(columns) {
514
+ const list = columns ?? [];
515
+ return {
516
+ fields: list.map((column, index) => ({
517
+ key: column.field,
518
+ at: index,
519
+ decode: column.decode
520
+ })),
521
+ includes: []
522
+ };
523
+ }
524
+ function expectOf(options, mods) {
525
+ const value = mods.expect ?? options.expect;
526
+ if (value === undefined)
527
+ return;
528
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
529
+ throw new OkmError2("invalid", "expect must be an integer from 0 up.", { kind: "invalid" });
530
+ }
531
+ return value;
532
+ }
533
+ function checkExpect(count, expected, table, op) {
534
+ if (expected === undefined || count === expected)
535
+ return;
536
+ throw new OkmError2("not_found", `${op} on ${table} changed ${String(count)} rows. expect was ${String(expected)}.`, {
537
+ kind: "not_found",
538
+ table,
539
+ fix: { summary: "Change the filter, or pass the count this write produced." }
540
+ });
541
+ }
542
+ function callOptions(options) {
543
+ if (!isRecord(options))
544
+ return;
545
+ const signal = options.signal;
546
+ const timeout = options.timeout;
547
+ const hasSignal = typeof signal === "object" && signal !== null && "aborted" in signal;
548
+ const hasTimeout = typeof timeout === "number";
549
+ if (!hasSignal && !hasTimeout)
550
+ return;
551
+ return {
552
+ ...hasSignal ? { signal } : {},
553
+ ...hasTimeout ? { timeout } : {}
554
+ };
555
+ }
556
+ function refuse(table, column) {
557
+ if (column.guarded) {
558
+ fail("OKM1190", `Field ${table}.${column.field} is guarded. Input cannot set it.`);
559
+ }
560
+ fail("OKM1120", `Field ${table}.${column.field} cannot be written.`);
561
+ }
562
+ export {
563
+ WRITE_PARAM_BUDGET,
564
+ executeWrite,
565
+ explainWrite
566
+ };
@@ -0,0 +1,16 @@
1
+ // src/dialects/pg/operators.ts
2
+ var RUNTIME = Symbol("okmodel.operator");
3
+ function isOperator(value) {
4
+ return typeof value === "object" && value !== null && RUNTIME in value;
5
+ }
6
+ function operatorName(value) {
7
+ return value[RUNTIME];
8
+ }
9
+ function operatorValue(value) {
10
+ return value.value;
11
+ }
12
+ function tag(name, value) {
13
+ return { [RUNTIME]: name, value };
14
+ }
15
+
16
+ export { isOperator, operatorName, operatorValue, tag };
@@ -0,0 +1,81 @@
1
+ import {
2
+ DriverError2,
3
+ outcomeUnknown2,
4
+ mapDriverError2
5
+ } from "./hd293j9g.js";
6
+ import {
7
+ isConnectionFailure
8
+ } from "./ngk8gj61.js";
9
+
10
+ // src/adapters/pg/batch.ts
11
+ var savepointIds = 0;
12
+ async function runAtomicBatch(session, statements, watch) {
13
+ if (session.inTransaction())
14
+ return savepoint(session, statements, watch);
15
+ return transaction(session, statements, watch);
16
+ }
17
+ async function transaction(session, statements, watch) {
18
+ try {
19
+ await control(session, "BEGIN", watch);
20
+ const results = await statementsOf(session, statements, watch);
21
+ try {
22
+ await control(session, "COMMIT", watch);
23
+ } catch (error) {
24
+ if (isConnectionFailure(error))
25
+ throw outcomeUnknown2(error);
26
+ throw stamp(error, null);
27
+ }
28
+ return results;
29
+ } catch (error) {
30
+ await rollback(session);
31
+ throw error;
32
+ }
33
+ }
34
+ async function savepoint(session, statements, watch) {
35
+ savepointIds += 1;
36
+ const name = `okm_b${String(savepointIds)}`;
37
+ try {
38
+ await control(session, `SAVEPOINT ${name}`, watch);
39
+ const results = await statementsOf(session, statements, watch);
40
+ await control(session, `RELEASE SAVEPOINT ${name}`, watch);
41
+ return results;
42
+ } catch (error) {
43
+ await rollback(session, `ROLLBACK TO SAVEPOINT ${name}`);
44
+ throw error;
45
+ }
46
+ }
47
+ function control(session, text, watch) {
48
+ return session.query(text, undefined, watch).then(() => {
49
+ return;
50
+ });
51
+ }
52
+ async function rollback(session, text = "ROLLBACK") {
53
+ try {
54
+ await session.query(text, undefined, undefined);
55
+ } catch {
56
+ session.abandon();
57
+ }
58
+ }
59
+ async function statementsOf(session, statements, watch) {
60
+ const results = Array.from({ length: statements.length });
61
+ for (let index = 0;index < statements.length; index += 1) {
62
+ const statement = statements[index];
63
+ if (statement === undefined)
64
+ continue;
65
+ try {
66
+ results[index] = await session.query(statement.text, statement.params, watch);
67
+ } catch (error) {
68
+ throw stamp(error, index);
69
+ }
70
+ }
71
+ return results;
72
+ }
73
+ function stamp(error, batchIndex) {
74
+ const mapped = mapDriverError2(error, batchIndex);
75
+ if (mapped instanceof DriverError2)
76
+ return mapped;
77
+ return error;
78
+ }
79
+ export {
80
+ runAtomicBatch
81
+ };