|
| 1 | +import { ScriptContext } from "../module.gen.ts"; |
| 2 | +import { checkHypertable } from "../utils/hypertable_init.ts"; |
| 3 | +import { stringifyFilters } from "../utils/stringify_filters.ts"; |
| 4 | +import { AggregationMethod, Filter } from "../utils/types.ts"; |
| 5 | + |
| 6 | +export interface Request { |
| 7 | + event: string; |
| 8 | + aggregate: AggregationMethod; |
| 9 | + filters: Filter[] |
| 10 | + groupBy: string[]; |
| 11 | + startAt: number; |
| 12 | + stopAt: number; |
| 13 | +} |
| 14 | + |
| 15 | +export interface Response { |
| 16 | + results: { groups: Record<string, any>, count: number}[] |
| 17 | +} |
| 18 | + |
| 19 | +export async function run( |
| 20 | + ctx: ScriptContext, |
| 21 | + req: Request, |
| 22 | +): Promise<Response> { |
| 23 | + checkHypertable(ctx); |
| 24 | + |
| 25 | + const props = req.groupBy.map((col) => `metadata->>'${col}'`); |
| 26 | + |
| 27 | + // A query that counts the amount of events in the database, per name (should return an array of counts per name) |
| 28 | + // the name isn't an actual field but instead a value in the metadata field |
| 29 | + const result = await ctx.db.$queryRawUnsafe(` |
| 30 | + SELECT ${req.groupBy.map(col => `metadata->>'${col}' as _${col}`).join(', ')}, COUNT(*) as count |
| 31 | + FROM "${ctx.dbSchema}"."Event" |
| 32 | + WHERE name = '${req.event}' |
| 33 | + AND timestamp >= '${new Date(req.startAt).toISOString()}' |
| 34 | + AND timestamp <= '${new Date(req.stopAt).toISOString()}' |
| 35 | + ${req.filters.length ? " AND " + stringifyFilters(req.filters) : ""} |
| 36 | + GROUP BY ${props.join(', ')} |
| 37 | + ORDER BY ${props.join(', ')} |
| 38 | + `) as any; |
| 39 | + |
| 40 | + return { |
| 41 | + results: result.map((e: any) => ({ |
| 42 | + // TODO: optimize |
| 43 | + groups: props.reduce<Record<string, any>>((acc, k) => (acc[k] = e["_" + k], acc), {}), |
| 44 | + count: e.count |
| 45 | + })) |
| 46 | + } |
| 47 | +} |
| 48 | + |
0 commit comments