dblang/src/defaultHandler.ts

200 lines
7.2 KiB
TypeScript
Raw Normal View History

2023-01-24 20:34:03 +01:00
import { Attribute, DB, Table } from "./db"
2023-01-23 21:19:18 +01:00
import { Aggregation, Modifier } from "./dbStructure"
import { selectQuery } from "./query"
import { allModifierInput, primaryData, serializeReturn } from "./types"
export class Handler {
2023-01-24 20:34:03 +01:00
syncDB(db : DB){
}
querys = {
select: (handler:Handler,q: selectQuery): serializeReturn => {
2023-01-23 21:19:18 +01:00
let args: primaryData[] = [];
2023-01-24 20:34:03 +01:00
let w = joinArg(", ")(handler,q.attr);
2023-01-23 21:19:18 +01:00
args.push(...w[1]);
2023-01-24 20:34:03 +01:00
let sql = `select ${w[0]} from ${q.from == null ? 'DUAL' : q.from.serialize(handler)}`;
2023-01-23 21:19:18 +01:00
if (q.whereD) {
2023-01-24 20:34:03 +01:00
let whereS = q.whereD.serialize(handler);
2023-01-23 21:19:18 +01:00
args.push(...whereS[1]);
2023-01-23 22:10:33 +01:00
sql += " where " + whereS[0];
2023-01-23 21:19:18 +01:00
}
2023-01-23 22:10:33 +01:00
if (q.groupByD.length > 0) {
2023-01-24 20:34:03 +01:00
let groupByS = joinArg(",")(handler,q.groupByD);
2023-01-23 21:19:18 +01:00
args.push(...groupByS[1]);
2023-01-23 22:10:33 +01:00
sql += " group by " + groupByS[0];
2023-01-23 21:19:18 +01:00
if (q.havingD) {
2023-01-24 20:34:03 +01:00
let havingS = q.havingD.serialize(handler);
2023-01-23 21:19:18 +01:00
args.push(...havingS[1]);
2023-01-23 22:10:33 +01:00
sql += " having " + havingS[0];
2023-01-23 21:19:18 +01:00
}
}
2023-01-23 22:10:33 +01:00
if (q.limitD != null) {
sql += " limit ?";
args.push(q.limitD);
}
2023-01-23 21:19:18 +01:00
return [sql, args];
2023-01-24 20:34:03 +01:00
},
create:(handler:Handler,table: Table): serializeReturn=>{
let args:primaryData[] = [];
let sql = `create table if not exists ${table.toString(handler)}(
${Object.entries(table.dbLangTableAttributes).map(([_,a])=>{
let atype = a.serializeSettings(handler);
args.push(...(atype[1]));
return a.serialize(handler)+" "+atype[0];
}).join(",\n")}
)`;
return [sql,args];
}
}
builders = {
attributeSettings: (handler:Handler,a: Attribute): serializeReturn => {
let dtype = a.type.serialize(handler);
let sql = ""+dtype[0];
let args:primaryData[] = [...dtype[1]];
if (a.ops.autoIncrement) {
sql += " auto_increment";
}
if (a.ops.primaryKey) {
sql += " primary key";
}
if (a.ops.default != null) {
if (a.ops.autoIncrement || a.ops.primaryKey || a.ops.notNull)
throw new Error(`Can not set default when autoIncrement, primaryKey or notNull ist set on Attribute: ${a.toStringFunc(handler)}`);
sql += " default ?";
args.push(a.ops.default);
}
if (a.ops.unique != null) {
if (!a.ops.autoIncrement && !a.ops.primaryKey){
sql += " unique";
}
}
if (a.ops.notNull != null) {
if (!a.ops.autoIncrement && !a.ops.primaryKey && a.ops.default == null){
sql += " not null";
}
}
if (a.ops.foreginKey != null) {
sql += ` foreign key references (${a.ops.foreginKey.link.toStringFunc(handler)})`
}
return [sql, args];
},
escapeID: (key:string) :string =>{
if(!key || key === "" || key.includes('\u0000')) throw new Error("Can not escape empty key or with null unicode!");
if (key.match(/^`.+`$/g)) return key;
return `\`${key.replace(/`/g, '``')}\``;
2023-01-23 21:19:18 +01:00
}
}
2023-01-24 20:34:03 +01:00
aggregations = {
count: (handler:Handler,a: Attribute): serializeReturn => ["count(" + a.toString(handler) + ")", []],
sum: (handler:Handler,a: Attribute): serializeReturn => ["sum(" + a.toString(handler) + ")", []],
avg: (handler:Handler,a: Attribute): serializeReturn => ["avg(" + a.toString(handler) + ")", []],
min: (handler:Handler,a: Attribute): serializeReturn => ["min(" + a.toString(handler) + ")", []],
max: (handler:Handler,a: Attribute): serializeReturn => ["max(" + a.toString(handler) + ")", []],
2023-01-23 21:19:18 +01:00
}
2023-01-24 20:34:03 +01:00
modifiers = {
and: joinArg("and"),
or: joinArg("or"),
le: joinArg("<"),
leq: joinArg("<="),
eq: joinArg("="),
geq: joinArg(">="),
ge: joinArg(">"),
plus: joinArg("+"),
minus: joinArg("-"),
not: (handler:Handler,a: allModifierInput[]): serializeReturn => {
2023-01-23 21:19:18 +01:00
let e = a[0];
2023-01-24 20:34:03 +01:00
if (e instanceof Attribute) return ["not (" + e.toString(handler) + ")", []];
2023-01-23 21:19:18 +01:00
if (e instanceof Modifier || e instanceof selectQuery || e instanceof Aggregation) {
2023-01-24 20:34:03 +01:00
let [sqli, argsi] = e.serialize(handler);
2023-01-23 21:19:18 +01:00
return ["not (" + sqli + ")", argsi]
}
return ["not (?)", [e]];
}
}
2023-01-24 20:34:03 +01:00
datatypes = {
2023-01-24 10:40:16 +01:00
char: dataTypeSingleNum("char"),
varchar: dataTypeSingleNum("varchar"),
binary: dataTypeSingleNum("binary"),
varbinary: dataTypeSingleNum("varbinary"),
tinyblob: dataTypeNoArg("tinyblob"),
blob: dataTypeNoArg("blob"),
mediumblob: dataTypeNoArg("mediumblob"),
longblob: dataTypeNoArg("longblob"),
tinytext: dataTypeNoArg("tinytext"),
text: dataTypeNoArg("text"),
mediumtext: dataTypeNoArg("mediumtext"),
longtext: dataTypeNoArg("longtext"),
2023-01-24 20:34:03 +01:00
enum: (a: primaryData[]): serializeReturn => {
console.log(a);
return ["enum(" + a.map(() => "?").join(", ") + ")", a];
2023-01-24 10:40:16 +01:00
},
2023-01-24 20:34:03 +01:00
set: (a: primaryData[]): serializeReturn => {
return ["set(" + a.map(() => "?").join(", ") + ")", a];
2023-01-24 10:40:16 +01:00
},
bool: dataTypeNoArg("bool"),
bit: dataTypeNoArg("bit"),
tinyint: dataTypeNoArg("tinyint"),
smallint: dataTypeNoArg("smallint"),
mediumint: dataTypeNoArg("mediumint"),
int: dataTypeNoArg("int"),
bigint: dataTypeNoArg("bigint"),
float: dataTypeDblNum("float"),
double: dataTypeDblNum("double"),
decimal: dataTypeDblNum("decimal"),
2023-01-24 20:34:03 +01:00
date: dataTypeNoArg("data"),
datetime: dataTypeNoArg("datatime"),
2023-01-24 10:40:16 +01:00
timestamp: dataTypeNoArg("timestamp"),
time: dataTypeNoArg("time"),
year: dataTypeNoArg("year"),
}
2023-01-23 21:19:18 +01:00
};
2023-01-24 20:34:03 +01:00
function dataTypeNoArg(type: string) {
return (a: primaryData[]): serializeReturn => {
return [type, []];
2023-01-24 10:40:16 +01:00
}
}
2023-01-24 20:34:03 +01:00
function dataTypeSingleNum(type: string) {
return (a: primaryData[]): serializeReturn => {
return [type + "(?)", [a[0]]];
2023-01-24 10:40:16 +01:00
}
}
2023-01-24 20:34:03 +01:00
function dataTypeDblNum(type: string) {
return (a: primaryData[]): serializeReturn => {
return [type + "(?,?)", [a[0], a[1]]];
2023-01-24 10:40:16 +01:00
}
}
2023-01-24 20:34:03 +01:00
function joinArg(type: string) {
return (handler:Handler,a: (allModifierInput)[]): serializeReturn => {
2023-01-23 21:19:18 +01:00
let args: primaryData[] = [];
2023-01-23 22:10:33 +01:00
let sql = a.map(d => {
2023-01-24 20:34:03 +01:00
if (d instanceof Attribute) return d.toString(handler);
2023-01-23 21:19:18 +01:00
if (d instanceof Modifier || d instanceof selectQuery || d instanceof Aggregation) {
2023-01-24 20:34:03 +01:00
let [sqli, argsi] = d.serialize(handler);
2023-01-23 21:19:18 +01:00
args.push(...(argsi.flat(Infinity)));
2023-01-24 20:34:03 +01:00
return "(" + sqli + ")";
2023-01-23 21:19:18 +01:00
}
args.push(d);
return "?";
2023-01-23 22:10:33 +01:00
}).join(" " + type + " ");
2023-01-23 21:19:18 +01:00
return [sql, args]
}
}