okmodel 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +727 -37
- package/dist/adapters/capabilities.d.ts +34 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +17 -0
- package/dist/adapters/pg/bunsql.d.ts +60 -0
- package/dist/adapters/pg/call.d.ts +2 -12
- package/dist/adapters/pg/nodepostgres-extra.d.ts +18 -0
- package/dist/adapters/pg/nodepostgres.d.ts +57 -0
- package/dist/adapters/pg/postgres-extra.d.ts +50 -1
- package/dist/adapters/pg/postgresjs.d.ts +0 -4
- package/dist/adapters/pg/session.d.ts +94 -0
- package/dist/adapters/pg/watch.d.ts +18 -0
- package/dist/contracts/catalog/enum.d.ts +31 -4
- package/dist/contracts/catalog/extension.d.ts +61 -0
- package/dist/contracts/catalog/object.d.ts +1 -0
- package/dist/contracts/catalog/privilege.d.ts +64 -0
- package/dist/contracts/catalog/routine.d.ts +56 -0
- package/dist/contracts/catalog/types.d.ts +179 -18
- package/dist/contracts/catalog/view.d.ts +73 -0
- package/dist/contracts/connection.d.ts +13 -0
- package/dist/contracts/driver.d.ts +18 -5
- package/dist/contracts/error.d.ts +17 -1
- package/dist/contracts/generator.d.ts +63 -0
- package/dist/contracts/index.d.ts +2 -2
- package/dist/contracts/index.js +1 -1
- package/dist/contracts/internal.js +11 -9
- package/dist/contracts/location.d.ts +24 -0
- package/dist/contracts/rows.d.ts +15 -0
- package/dist/dialects/pg/archive-bind.d.ts +22 -0
- package/dist/dialects/pg/column.d.ts +129 -10
- package/dist/dialects/pg/compile.d.ts +1 -0
- package/dist/dialects/pg/custom.d.ts +6 -0
- package/dist/dialects/pg/ddl.d.ts +65 -1
- package/dist/dialects/pg/enum.d.ts +10 -8
- package/dist/dialects/pg/ext/citext.d.ts +14 -0
- package/dist/dialects/pg/ext/citext.js +11 -0
- package/dist/dialects/pg/ext/index.d.ts +52 -0
- package/dist/dialects/pg/ext/index.js +6 -0
- package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
- package/dist/dialects/pg/ext/pg-trgm.js +42 -0
- package/dist/dialects/pg/filter-parse.d.ts +19 -0
- package/dist/dialects/pg/filters.d.ts +19 -0
- package/dist/dialects/pg/fn/index.d.ts +107 -0
- package/dist/dialects/pg/fn/index.js +175 -0
- package/dist/dialects/pg/fn/touch.d.ts +14 -0
- package/dist/dialects/pg/index.d.ts +11 -2
- package/dist/dialects/pg/index.js +243 -1062
- package/dist/dialects/pg/introspect.d.ts +10 -1
- package/dist/dialects/pg/keys.d.ts +19 -3
- package/dist/dialects/pg/model.d.ts +223 -2
- package/dist/dialects/pg/operator-fit.d.ts +86 -0
- package/dist/dialects/pg/operators.d.ts +46 -1
- package/dist/dialects/pg/ops/arr-append.d.ts +9 -0
- package/dist/dialects/pg/ops/arr-ns.d.ts +7 -0
- package/dist/dialects/pg/ops/arr-remove.d.ts +9 -0
- package/dist/dialects/pg/ops/containedBy.d.ts +9 -0
- package/dist/dialects/pg/ops/contains.d.ts +8 -4
- package/dist/dialects/pg/ops/hasAnyKey.d.ts +8 -0
- package/dist/dialects/pg/ops/hasKey.d.ts +8 -0
- package/dist/dialects/pg/ops/json-ns.d.ts +6 -0
- package/dist/dialects/pg/ops/json-set.d.ts +12 -0
- package/dist/dialects/pg/ops/matches.d.ts +16 -0
- package/dist/dialects/pg/ops/overlaps.d.ts +9 -0
- package/dist/dialects/pg/ops/path.d.ts +13 -0
- package/dist/dialects/pg/preset.d.ts +76 -0
- package/dist/dialects/pg/relations.d.ts +59 -2
- package/dist/dialects/pg/role/check.d.ts +45 -0
- package/dist/dialects/pg/role/index.d.ts +50 -0
- package/dist/dialects/pg/role/sql.d.ts +44 -0
- package/dist/dialects/pg/schema.d.ts +109 -5
- package/dist/dialects/pg/table.d.ts +137 -11
- package/dist/dialects/pg/temporal.d.ts +9 -7
- package/dist/dialects/pg/tenancy.d.ts +103 -0
- package/dist/dialects/pg/through.d.ts +21 -0
- package/dist/dialects/pg/trait.d.ts +141 -0
- package/dist/dialects/pg/view/client.d.ts +30 -0
- package/dist/dialects/pg/view/depend.d.ts +35 -0
- package/dist/dialects/pg/view/index.d.ts +114 -0
- package/dist/dialects/pg/view/index.js +289 -0
- package/dist/dialects/pg/view/scratch.d.ts +21 -0
- package/dist/dialects/pg/where.d.ts +37 -0
- package/dist/runtime/aggregate.d.ts +25 -0
- package/dist/runtime/archive-handle.d.ts +18 -0
- package/dist/runtime/archive-rules.d.ts +12 -0
- package/dist/runtime/archive.d.ts +73 -0
- package/dist/runtime/batch.d.ts +20 -0
- package/dist/runtime/client.d.ts +114 -5
- package/dist/runtime/conflict.d.ts +2 -1
- package/dist/runtime/exposure.d.ts +27 -0
- package/dist/runtime/hookm.d.ts +39 -0
- package/dist/runtime/ids/index.d.ts +11 -0
- package/dist/runtime/ids/index.js +193 -0
- package/dist/runtime/ids/okid-extended.d.ts +19 -0
- package/dist/runtime/ids/okid-generator.d.ts +21 -0
- package/dist/runtime/ids/okid-shared.d.ts +89 -0
- package/dist/runtime/ids/okid.d.ts +24 -0
- package/dist/runtime/ids/uuid.d.ts +21 -0
- package/dist/runtime/lock.d.ts +22 -0
- package/dist/runtime/operator-sql.d.ts +8 -0
- package/dist/runtime/page.d.ts +25 -0
- package/dist/runtime/pg/bun.d.ts +30 -0
- package/dist/runtime/pg/bun.js +52 -0
- package/dist/runtime/pg/pg.d.ts +29 -0
- package/dist/runtime/pg/pg.js +52 -0
- package/dist/runtime/pg/pglite.js +16 -17
- package/dist/runtime/pg/postgresjs.js +14 -24
- package/dist/runtime/plan.d.ts +146 -7
- package/dist/runtime/preset-stack.d.ts +17 -0
- package/dist/runtime/presets.d.ts +48 -0
- package/dist/runtime/read-stream.d.ts +26 -0
- package/dist/runtime/safety/index.d.ts +159 -0
- package/dist/runtime/safety/index.js +294 -0
- package/dist/runtime/safety-hook.d.ts +42 -0
- package/dist/runtime/server-check.d.ts +34 -0
- package/dist/runtime/tenancy/index.d.ts +37 -0
- package/dist/runtime/tenancy/index.js +368 -0
- package/dist/runtime/trait-read.d.ts +30 -0
- package/dist/runtime/traits/index.d.ts +133 -0
- package/dist/runtime/traits/index.js +646 -0
- package/dist/runtime/transaction.d.ts +19 -0
- package/dist/runtime/tx.d.ts +22 -7
- package/dist/runtime/types.d.ts +376 -27
- package/dist/runtime/validate/bind.d.ts +11 -0
- package/dist/runtime/validate/closed.d.ts +16 -0
- package/dist/runtime/validate/engine.d.ts +41 -0
- package/dist/runtime/validate/hook.d.ts +17 -0
- package/dist/runtime/validate/index.d.ts +21 -0
- package/dist/runtime/validate/index.js +175 -0
- package/dist/runtime/validate/load.d.ts +13 -0
- package/dist/runtime/validate/places.d.ts +41 -0
- package/dist/runtime/validate/rules.d.ts +108 -0
- package/dist/runtime/validate/surface.d.ts +102 -0
- package/dist/runtime/write.d.ts +30 -5
- package/dist/shared/01yr20s5.js +149 -0
- package/dist/shared/0jc3ffzf.js +154 -0
- package/dist/shared/0v1g424p.js +26 -0
- package/dist/shared/1g0drakv.js +225 -0
- package/dist/shared/{kprcwaha.js → 1tfdfvhh.js} +5 -3
- package/dist/shared/{05w44d8g.js → 2ssqrv66.js} +767 -715
- package/dist/shared/3ekj9x92.js +210 -0
- package/dist/shared/49ypnfwt.js +1122 -0
- package/dist/shared/4e4c6vq2.js +62 -0
- package/dist/shared/4m9fn52z.js +70 -0
- package/dist/shared/{ycwz42az.js → 52szzakm.js} +6 -26
- package/dist/shared/5nmdenb6.js +1229 -0
- package/dist/shared/672t5vym.js +12 -0
- package/dist/shared/6bazvqwm.js +86 -0
- package/dist/shared/6w5j844a.js +201 -0
- package/dist/shared/{fgqgsb5z.js → 75xkjv0t.js} +2 -2
- package/dist/shared/7fvtrkwr.js +84 -0
- package/dist/shared/7m88x3e9.js +45 -0
- package/dist/shared/{mtkwv8wx.js → 7p2wbz7f.js} +1 -1
- package/dist/shared/83eaefwr.js +10 -0
- package/dist/shared/94ez8kzh.js +19 -0
- package/dist/shared/96ps4g1z.js +32 -0
- package/dist/shared/{xqbhg6cn.js → 999ade2q.js} +95 -10
- package/dist/shared/9m80mkac.js +158 -0
- package/dist/shared/9x25fxhc.js +150 -0
- package/dist/shared/a5sxz52y.js +13 -0
- package/dist/shared/axhk06q1.js +156 -0
- package/dist/shared/{dynq16vb.js → b066g80h.js} +8 -6
- package/dist/shared/bqha5cg6.js +229 -0
- package/dist/shared/bryqk9k9.js +31 -0
- package/dist/shared/c8aghh05.js +442 -0
- package/dist/shared/c9z5g0fm.js +309 -0
- package/dist/shared/{m3ypagh5.js → dbjej1tw.js} +124 -15
- package/dist/shared/dyj86cmj.js +69 -0
- package/dist/shared/e6wg00wd.js +164 -0
- package/dist/shared/{hadrfb9h.js → edwqqryd.js} +17 -14
- package/dist/shared/{qk3hxfja.js → fptpmvxp.js} +5 -5
- package/dist/shared/fs0ex00p.js +76 -0
- package/dist/shared/{jjb7yht9.js → g4f5kcx9.js} +3 -3
- package/dist/shared/gjthds9j.js +48 -0
- package/dist/shared/hcmdtwgh.js +102 -0
- package/dist/shared/{g5fhqmwe.js → jkc6ws1p.js} +6 -56
- package/dist/shared/{yd1kzwn2.js → jns2wx4t.js} +55 -12
- package/dist/shared/k34e0xf2.js +450 -0
- package/dist/shared/k3ted12y.js +33 -0
- package/dist/shared/k7dwkhvq.js +31 -0
- package/dist/shared/{8b04d28c.js → kgnc8grt.js} +2 -2
- package/dist/shared/{hd293j9g.js → kyxb62mc.js} +14 -2
- package/dist/shared/m78s7898.js +376 -0
- package/dist/shared/m9tv7xn7.js +404 -0
- package/dist/shared/meck53jv.js +99 -0
- package/dist/shared/mt5wswjz.js +90 -0
- package/dist/shared/n0dgs0pb.js +75 -0
- package/dist/shared/n442h54c.js +14 -0
- package/dist/shared/n4jqhpqz.js +27 -0
- package/dist/shared/n7mcc1gk.js +132 -0
- package/dist/shared/ne02ng5c.js +68 -0
- package/dist/shared/{mkjmqjv4.js → nfzc5z0w.js} +2 -104
- package/dist/shared/nsva2a6b.js +42 -0
- package/dist/shared/p24x2334.js +195 -0
- package/dist/shared/qbxzvwwc.js +88 -0
- package/dist/shared/{w8samvk1.js → qybh48nd.js} +1 -1
- package/dist/shared/r6nwkxnt.js +86 -0
- package/dist/shared/{xy79j5hq.js → rrstp3kb.js} +25 -36
- package/dist/shared/rwmrejjz.js +26 -0
- package/dist/shared/{zhc5vmgf.js → s6gqfn5j.js} +2 -2
- package/dist/shared/{523ft3e8.js → scwxrpx2.js} +7 -5
- package/dist/shared/{j5cn2963.js → t4tbsy9h.js} +13 -64
- package/dist/shared/{y9m15dfv.js → t616ynfn.js} +544 -32
- package/dist/shared/{ngk8gj61.js → tbszx8mz.js} +15 -1
- package/dist/shared/th14ygv2.js +69 -0
- package/dist/shared/tmbdywx0.js +178 -0
- package/dist/shared/ty3v3hfk.js +64 -0
- package/dist/shared/wekze34d.js +246 -0
- package/dist/shared/x6wysh83.js +1132 -0
- package/dist/shared/{rgs0st28.js → xrfnq5k8.js} +237 -434
- package/dist/shared/{x5x59srr.js → xva8v7qk.js} +416 -83
- package/dist/shared/{dkn3y60a.js → xw1d69vd.js} +76 -112
- package/dist/shared/y005b761.js +112 -0
- package/dist/shared/ydaz1sv3.js +55 -0
- package/dist/shared/{p0cbr3g2.js → zwmqxb0g.js} +1 -1
- package/dist/tooling/cli.js +40 -12
- package/dist/tooling/migrate/apply.d.ts +16 -0
- package/dist/tooling/migrate/commands.d.ts +12 -1
- package/dist/tooling/migrate/config.d.ts +8 -0
- package/dist/tooling/migrate/doctor.d.ts +25 -0
- package/dist/tooling/migrate/drift.d.ts +19 -0
- package/dist/tooling/migrate/engine.d.ts +36 -0
- package/dist/tooling/migrate/ext.d.ts +17 -0
- package/dist/tooling/migrate/extensions.d.ts +51 -0
- package/dist/tooling/migrate/managed.d.ts +17 -0
- package/dist/tooling/migrate/plan.d.ts +14 -1
- package/dist/tooling/migrate/project.d.ts +25 -1
- package/dist/tooling/migrate/type-name.d.ts +19 -0
- package/package.json +61 -4
- package/dist/shared/gk7cs7sp.js +0 -566
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readHandle,
|
|
3
|
+
readCall,
|
|
4
|
+
attachHttp
|
|
5
|
+
} from "./k34e0xf2.js";
|
|
6
|
+
import {
|
|
7
|
+
emitWhere,
|
|
8
|
+
emitOrder,
|
|
9
|
+
rejectKeys,
|
|
10
|
+
readLimit,
|
|
11
|
+
projectExpr,
|
|
12
|
+
cell,
|
|
13
|
+
indexes,
|
|
14
|
+
quote,
|
|
15
|
+
list,
|
|
16
|
+
isRecord,
|
|
17
|
+
fail
|
|
18
|
+
} from "./xrfnq5k8.js";
|
|
19
|
+
import {
|
|
20
|
+
OkmError2,
|
|
21
|
+
throwNamed2
|
|
22
|
+
} from "./52szzakm.js";
|
|
23
|
+
|
|
24
|
+
// src/runtime/aggregate.ts
|
|
25
|
+
var OPTIONS = [
|
|
26
|
+
"where",
|
|
27
|
+
"groupBy",
|
|
28
|
+
"count",
|
|
29
|
+
"sum",
|
|
30
|
+
"avg",
|
|
31
|
+
"min",
|
|
32
|
+
"max",
|
|
33
|
+
"orderBy",
|
|
34
|
+
"limit",
|
|
35
|
+
"signal",
|
|
36
|
+
"timeout"
|
|
37
|
+
];
|
|
38
|
+
var NUMERIC = /^(smallint|integer|bigint|real|double precision|numeric|decimal)\b/;
|
|
39
|
+
var AS_NUMBER = (wire) => Number(wire);
|
|
40
|
+
var AS_TEXT = (wire) => wire;
|
|
41
|
+
var UNORDERED = /^(json|jsonb|bytea|point|line|tsvector)\b|\[\]$/;
|
|
42
|
+
var FUNCTIONS = [
|
|
43
|
+
{ option: "sum", tag: "s", numeric: true },
|
|
44
|
+
{ option: "avg", tag: "a", numeric: true },
|
|
45
|
+
{ option: "min", tag: "n", numeric: false },
|
|
46
|
+
{ option: "max", tag: "x", numeric: false }
|
|
47
|
+
];
|
|
48
|
+
function build(session, table, options, mods, view) {
|
|
49
|
+
try {
|
|
50
|
+
return plan(session, table, options, mods, view);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
throw error instanceof OkmError2 ? attachHttp(session.http, error) : error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function plan(session, table, options, mods, view) {
|
|
56
|
+
const record = isRecord(options) ? options : {};
|
|
57
|
+
rejectKeys(record, OPTIONS, "aggregate");
|
|
58
|
+
const indexed = indexes(session.schema).get(table);
|
|
59
|
+
if (indexed === undefined)
|
|
60
|
+
fail("OKM1120", `Table ${table} is not in the schema.`);
|
|
61
|
+
const spec = parse(indexed, record);
|
|
62
|
+
if (spec.groups.length > 0 && record.limit === undefined && mods.all === undefined) {
|
|
63
|
+
fail("OKM1101", "aggregate() with groupBy needs a limit, or .all(reason) for every group.");
|
|
64
|
+
}
|
|
65
|
+
const orderBy = record.orderBy;
|
|
66
|
+
if (orderBy !== undefined) {
|
|
67
|
+
if (!isRecord(orderBy))
|
|
68
|
+
fail("OKM1120", "orderBy must be an object of fields.");
|
|
69
|
+
for (const field of Object.keys(orderBy)) {
|
|
70
|
+
if (!spec.groups.some((column) => column.field === field)) {
|
|
71
|
+
throwNamed2("OKM1120", field, spec.groups.map((column) => column.field), `aggregate() orders by a groupBy field. Accepted names: ${list(spec.groups.map((column) => column.field))}.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (record.limit !== undefined)
|
|
76
|
+
readLimit(record.limit);
|
|
77
|
+
const base = readCall("find", table, {
|
|
78
|
+
where: record.where,
|
|
79
|
+
orderBy,
|
|
80
|
+
limit: record.limit,
|
|
81
|
+
signal: record.signal,
|
|
82
|
+
timeout: record.timeout
|
|
83
|
+
}, mods.all, session.scope, session.schema.model[table], session.schema, view);
|
|
84
|
+
const call = { ...base, op: "aggregate", build: statement(spec) };
|
|
85
|
+
return readHandle(session, table, call, mods, (compiled, rows) => decode(compiled, rows));
|
|
86
|
+
}
|
|
87
|
+
function parse(table, record) {
|
|
88
|
+
const groups = columns(table, record.groupBy, "groupBy");
|
|
89
|
+
const count = record.count === true;
|
|
90
|
+
if (record.count !== undefined && typeof record.count !== "boolean") {
|
|
91
|
+
fail("OKM1120", "count is true when you want a row count.");
|
|
92
|
+
}
|
|
93
|
+
const calls = [];
|
|
94
|
+
for (const { option, tag, numeric } of FUNCTIONS) {
|
|
95
|
+
for (const column of columns(table, record[option], option)) {
|
|
96
|
+
const fits = numeric ? NUMERIC.test(column.dataType) : !UNORDERED.test(column.dataType);
|
|
97
|
+
if (!fits) {
|
|
98
|
+
fail("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."}`);
|
|
99
|
+
}
|
|
100
|
+
calls.push({ option, tag, column, decode: numeric ? sumDecode(column) : column.decode });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!count && calls.length === 0 && groups.length === 0) {
|
|
104
|
+
fail("OKM1120", "aggregate() needs count, sum, avg, min, max, or groupBy.");
|
|
105
|
+
}
|
|
106
|
+
return { groups, count, calls };
|
|
107
|
+
}
|
|
108
|
+
function sumDecode(column) {
|
|
109
|
+
const kind = typeof (column.decode?.("0") ?? "");
|
|
110
|
+
if (kind === "string")
|
|
111
|
+
return AS_TEXT;
|
|
112
|
+
if (kind === "number")
|
|
113
|
+
return AS_NUMBER;
|
|
114
|
+
return fail("OKM1124", `sum and avg need a column whose value is a number or a string. ${column.field} reads as ${kind}.`);
|
|
115
|
+
}
|
|
116
|
+
function columns(table, value, option) {
|
|
117
|
+
if (value === undefined)
|
|
118
|
+
return [];
|
|
119
|
+
if (!Array.isArray(value))
|
|
120
|
+
fail("OKM1120", `${option} must be a list of field names.`);
|
|
121
|
+
const out = [];
|
|
122
|
+
for (const name of value) {
|
|
123
|
+
const column = typeof name === "string" ? table.columns.get(name) : undefined;
|
|
124
|
+
if (typeof name !== "string" || column === undefined) {
|
|
125
|
+
throwNamed2("OKM1120", String(name), table.names, `Field ${String(name)} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
|
|
126
|
+
}
|
|
127
|
+
if (column.hidden) {
|
|
128
|
+
fail("OKM1120", `Field ${column.field} is hidden, so ${option} cannot read it.`);
|
|
129
|
+
}
|
|
130
|
+
out.push(column);
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
function statement(spec) {
|
|
135
|
+
return (schema, table, sink, outputs, call) => {
|
|
136
|
+
sink.mark(`aggregate|${table.model.name}|g:${spec.groups.map((column) => column.field).join(",")}|c:${String(spec.count)}|${spec.calls.map((item) => `${item.tag}:${item.column.field}`).join(",")}|`);
|
|
137
|
+
sink.text("select ");
|
|
138
|
+
const wrote = { at: 0 };
|
|
139
|
+
for (const column of spec.groups) {
|
|
140
|
+
put(sink, outputs, wrote, projectExpr(`t.${quote(column.sql)}`, column.dataType), {
|
|
141
|
+
key: `g:${column.field}`,
|
|
142
|
+
decode: column.decode
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (spec.count)
|
|
146
|
+
put(sink, outputs, wrote, "count(*)::text", { key: "c:", decode: undefined });
|
|
147
|
+
for (const item of spec.calls) {
|
|
148
|
+
const ref = `t.${quote(item.column.sql)}`;
|
|
149
|
+
const expr = item.option === "sum" || item.option === "avg" ? `${item.option}(${ref})::text` : projectExpr(`${item.option}(${ref})`, item.column.dataType);
|
|
150
|
+
put(sink, outputs, wrote, expr, {
|
|
151
|
+
key: `${item.tag}:${item.column.field}`,
|
|
152
|
+
decode: item.decode
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
sink.text(" from ");
|
|
156
|
+
sink.text(quote(table.model.sql));
|
|
157
|
+
sink.text(" t");
|
|
158
|
+
emitWhere(schema, table, call.where, sink, "t", 0);
|
|
159
|
+
if (spec.groups.length > 0) {
|
|
160
|
+
sink.text(" group by ");
|
|
161
|
+
sink.text(spec.groups.map((column) => `t.${quote(column.sql)}`).join(", "));
|
|
162
|
+
if (isRecord(call.orderBy) && Object.keys(call.orderBy).length > 0) {
|
|
163
|
+
emitOrder(table, call.orderBy, sink, "t");
|
|
164
|
+
} else {
|
|
165
|
+
sink.text(" order by ");
|
|
166
|
+
sink.text(spec.groups.map((column) => `t.${quote(column.sql)} asc nulls last`).join(", "));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (call.limit !== undefined) {
|
|
170
|
+
const limit = String(call.limit);
|
|
171
|
+
sink.text(" limit ");
|
|
172
|
+
sink.param(limit);
|
|
173
|
+
sink.mark(`l:${limit}`);
|
|
174
|
+
}
|
|
175
|
+
if (typeof call.all === "string")
|
|
176
|
+
sink.mark(`all:${call.all}`);
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function put(sink, outputs, wrote, expr, out) {
|
|
180
|
+
if (wrote.at > 0)
|
|
181
|
+
sink.text(", ");
|
|
182
|
+
sink.text(expr);
|
|
183
|
+
outputs?.fields.push({ key: out.key, at: wrote.at, decode: out.decode });
|
|
184
|
+
wrote.at += 1;
|
|
185
|
+
}
|
|
186
|
+
function decode(compiled, rows) {
|
|
187
|
+
const items = [];
|
|
188
|
+
for (const row of rows) {
|
|
189
|
+
const item = {};
|
|
190
|
+
for (const field of compiled.outputs.fields) {
|
|
191
|
+
const value = row[field.at];
|
|
192
|
+
const tag = field.key.slice(0, 2);
|
|
193
|
+
const name = field.key.slice(2);
|
|
194
|
+
if (tag === "g:") {
|
|
195
|
+
item[name] = cell(value, field.decode);
|
|
196
|
+
} else if (tag === "c:") {
|
|
197
|
+
item.count = Number(value ?? 0);
|
|
198
|
+
} else {
|
|
199
|
+
const group = tag === "s:" ? "sum" : tag === "a:" ? "avg" : tag === "n:" ? "min" : "max";
|
|
200
|
+
const into = item[group] ??= {};
|
|
201
|
+
into[name] = cell(value, field.decode);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
items.push(item);
|
|
205
|
+
}
|
|
206
|
+
return items;
|
|
207
|
+
}
|
|
208
|
+
export {
|
|
209
|
+
build
|
|
210
|
+
};
|