import { Attribute } from "./db" import { Aggregation, Modifier } from "./dbStructure" import { selectQuery } from "./query" import { allModifierInput, primaryData, serializeReturn } from "./types" export class Handler { static querys = { select: (q: selectQuery): serializeReturn => { let args: primaryData[] = []; let w = joinArg(", ", this)(q.attr); args.push(...w[1]); let sql = `select ${w[0]} from ${q.from == null ? 'DUAL' : q.from.serialize(this)}`; if (q.whereD) { let whereS = q.whereD.serialize(this); args.push(...whereS[1]); sql += " where "+whereS[0]; } if (q.groupByD.length>0) { let groupByS = joinArg(",", this)(q.groupByD); args.push(...groupByS[1]); sql += " group by "+groupByS[0]; if (q.havingD) { let havingS = q.havingD.serialize(this); args.push(...havingS[1]); sql += " having "+havingS[0]; } } return [sql, args]; } } static aggregations = { count: (a: Attribute): serializeReturn => ["count(" + a + ")", []], sum: (a: Attribute): serializeReturn => ["sum(" + a + ")", []], avg: (a: Attribute): serializeReturn => ["avg(" + a + ")", []], min: (a: Attribute): serializeReturn => ["min(" + a + ")", []], max: (a: Attribute): serializeReturn => ["max(" + a + ")", []], } static modifiers = { and: joinArg("and", this), or: joinArg("or", this), eq: joinArg("=", this), plus: joinArg("+", this), minus: joinArg("-", this), not: (a: allModifierInput[]):serializeReturn => { let e = a[0]; if (e instanceof Attribute) return ["not (" + e + ")", []]; if (e instanceof Modifier || e instanceof selectQuery || e instanceof Aggregation) { let [sqli, argsi] = e.serialize(this); return ["not (" + sqli + ")", argsi] } return ["not (?)", [e]]; } } }; function joinArg(type: string, s: any) { return (a: (allModifierInput)[]): serializeReturn => { let args: primaryData[] = []; let sql = "(" + a.map(d => { if (d instanceof Attribute) return d; if (d instanceof Modifier || d instanceof selectQuery || d instanceof Aggregation) { let [sqli, argsi] = d.serialize(s); args.push(...(argsi.flat(Infinity))); return sqli; } args.push(d); return "?"; }).join(" " + type + " ") + ")"; return [sql, args] } }