diff --git a/src/defaultHandler.ts b/src/defaultHandler.ts index 450babb..3765dfb 100644 --- a/src/defaultHandler.ts +++ b/src/defaultHandler.ts @@ -1,6 +1,6 @@ import { Attribute, DB, Table } from "./db" import { Aggregation, checkConstraint, Constraint, Datatype, foreignConstraint, Modifier, uniqueConstraint } from "./dbStructure" -import { Query, QueryBuilder, selectQuery } from "./query" +import { insertQuery, Query, QueryBuilder, removeQuery, selectQuery, updateQuery } from "./query" import { allModifierInput, onAction, primaryData, serializeReturn } from "./types" export class Handler { @@ -261,6 +261,60 @@ export class Handler { return builder; }, + insert: (hander: Handler, q: insertQuery): QueryBuilder => { + const qb = new QueryBuilder(); + qb.addCode("INSERT INTO "); + qb.addCode(q.attrs[0].table.serialize(hander)); + qb.addCode("("); + qb.addCodeCommaSeperated(q.attrs.map(a => a.serialize(hander))); + qb.addCode(") "); + if (q.select == null) { + qb.addCode("VALUES "); + for (let i = 0; i < q.values.length; i++) { + qb.addCode("("); + qb.addInjectionCommaSeperated(q.values[i]); + qb.addCode(")"); + if (i + 1 < q.values.length) qb.addCode(","); + } + } else { + qb.append(q.select.serialize(hander)); + } + return qb; + }, + update: (handler: Handler, q: updateQuery): QueryBuilder => { + const qb = new QueryBuilder(); + qb.addCode("UPDATE "); + qb.addCode(q.table.serialize(handler)); + qb.addCode(" SET "); + for (let i = 0; i < q.setD.length; i++) { + const s = q.setD[i]; + qb.addCode(s[0].serialize(handler)); + qb.addCode(" = ("); + if (s[1] instanceof Attribute) qb.addCode(s[1].serialize(handler)); + else if (s[1] instanceof Modifier || s[1] instanceof selectQuery || s[1] instanceof Aggregation) { + qb.append(s[1].serialize(handler)); + } else { + qb.addInjection(s[1]); + } + qb.addCode(")"); + if (i + 1 < q.setD.length) qb.addCode(", "); + } + if (q.whereD) { + qb.addCode(" where "); + qb.append(q.whereD.serialize(handler)); + } + return qb; + }, + remove: (handler: Handler, q: removeQuery): QueryBuilder =>{ + const qb = new QueryBuilder(); + qb.addCode("DELETE FROM "); + qb.addCode(q.table.serialize(handler)); + if (q.whereD) { + qb.addCode(" where "); + qb.append(q.whereD.serialize(handler)); + } + return qb; + }, listTables: (handler: Handler, db: DB) => { const qb = new QueryBuilder(); qb.addCode(`SELECT * FROM information_schema.tables where TABLE_SCHEMA = `); @@ -505,25 +559,37 @@ export class Handler { const builder = new QueryBuilder(); if (a[0] instanceof Attribute) builder.addCode(a[0].toString()); else if (a[0] instanceof Modifier || a[0] instanceof selectQuery || a[0] instanceof Aggregation) { - const builder = new QueryBuilder(); builder.append(a[0].serialize(handler)); - return builder; - }else{ + } else { builder.addInjection(a[0]); } builder.addCode(" LIKE "); if (a[1] instanceof Attribute) builder.addCode(a[1].toString()); else if (a[1] instanceof Modifier || a[1] instanceof selectQuery || a[1] instanceof Aggregation) { - const builder = new QueryBuilder(); builder.append(a[1].serialize(handler)); - return builder; - }else{ + } else { builder.addInjection(a[1]); } return builder; + }, + concat: (handler: Handler, a: allModifierInput[]): QueryBuilder => { + const builder = new QueryBuilder(); + builder.addCode("CONCAT("); + for (let i = 0; i < a.length; i++) { + const e = a[i]; + if (e instanceof Attribute) builder.addCode(e.toString()); + else if (e instanceof Modifier || e instanceof selectQuery || e instanceof Aggregation) { + builder.append(e.serialize(handler)); + } else { + builder.addInjection(e); + } + if (i < a.length - 1) builder.addCode(", "); + } + builder.addCode(")"); + return builder; } } - + datatypes = { char: dataTypeSingleNum("char"), varchar: dataTypeSingleNum("varchar"), diff --git a/src/funcs.ts b/src/funcs.ts index 870d2d0..9c9aebe 100644 --- a/src/funcs.ts +++ b/src/funcs.ts @@ -1,26 +1,27 @@ -import { Attribute } from "./db"; -import { Aggregation, BooleanModifier, checkConstraint, Datatype, foreignConstraint, NumberModifier, uniqueConstraint } from "./dbStructure"; -import { selectQuery } from "./query"; -import { allModifierInput, primaryData, selectElements, selectFromElements } from "./types"; +import { Attribute, Table } from "./db"; +import { Aggregation, BooleanModifier, checkConstraint, Datatype, foreignConstraint, NumberModifier, StringModifier, uniqueConstraint } from "./dbStructure"; +import { insertQuery, removeQuery, selectQuery, updateQuery } from "./query"; +import { allModifierInput, selectElements, selectFromElements } from "./types"; //modifiers -export const and = (...args: (BooleanModifier)[]) => new BooleanModifier("and", args); -export const or = (...args: (BooleanModifier)[]) => new BooleanModifier("or", args); -export const ge = (...args: (allModifierInput)[]) => new BooleanModifier("ge", args); -export const geq = (...args: (allModifierInput)[]) => new BooleanModifier("geq", args); -export const eq = (...args: (allModifierInput)[]) => new BooleanModifier("eq", args); -export const leq = (...args: (allModifierInput)[]) => new BooleanModifier("leq", args); -export const le = (...args: (allModifierInput)[]) => new BooleanModifier("le", args); -export const plus = (...args: (allModifierInput)[]) => new NumberModifier("plus", args); -export const minus = (...args: (allModifierInput)[]) => new NumberModifier("minus", args); -export const mult = (...args: (allModifierInput)[]) => new NumberModifier("mult", args); -export const divide = (...args: (allModifierInput)[]) => new NumberModifier("divide", args); +export const and = (...args: BooleanModifier[]) => new BooleanModifier("and", args); +export const or = (...args: BooleanModifier[]) => new BooleanModifier("or", args); +export const ge = (...args: allModifierInput[]) => new BooleanModifier("ge", args); +export const geq = (...args: allModifierInput[]) => new BooleanModifier("geq", args); +export const eq = (...args: allModifierInput[]) => new BooleanModifier("eq", args); +export const leq = (...args: allModifierInput[]) => new BooleanModifier("leq", args); +export const le = (...args: allModifierInput[]) => new BooleanModifier("le", args); +export const plus = (...args: allModifierInput[]) => new NumberModifier("plus", args); +export const minus = (...args: allModifierInput[]) => new NumberModifier("minus", args); +export const mult = (...args: allModifierInput[]) => new NumberModifier("mult", args); +export const divide = (...args: allModifierInput[]) => new NumberModifier("divide", args); -export const not = (...args: (allModifierInput)[]) => new BooleanModifier("not", args); +export const not = (...args: allModifierInput[]) => new BooleanModifier("not", args); export const like = (a: allModifierInput, b: allModifierInput) => new BooleanModifier("like", [a, b]); -//aggregations +export const concat = (...args: allModifierInput[]) => new StringModifier("concat", args); +//aggregations export const count = (a: Attribute) => new Aggregation("count", a); export const sum = (a: Attribute) => new Aggregation("sum", a); export const avg = (a: Attribute) => new Aggregation("avg", a); @@ -29,6 +30,9 @@ export const max = (a: Attribute) => new Aggregation("max", a); //query export const select = (args: selectElements[], from: selectFromElements) => new selectQuery(args, from); +export const insert = (...attrs: Attribute[]) => new insertQuery(attrs); +export const update = (table: Table) => new updateQuery(table); +export const remove = (table: Table) => new removeQuery(table); //datatypes @@ -75,7 +79,7 @@ export const foreignKey = (attrs: Attribute[], target: Attribute[]) => new forei "foreign_constraint_" + attrs.map(a => a.name + "_" + a.table.dbLangTableName).join("_") + "_to_" - + target.map(a => a.name + "_" + a.table.dbLangTableName).join("_"), + + target.map(a => a.name + "_" + a.table.dbLangTableName).join("_"), attrs, target); export const uniqueKey = (attrs: Attribute[]) => new uniqueConstraint("unique_constraint_" + attrs.map(a => a.name + "_" + a.table.dbLangTableName).join("_"), attrs); export const check = (name: string, mod: BooleanModifier) => new checkConstraint(name, mod); diff --git a/src/query.ts b/src/query.ts index c6e04d1..597ffb2 100644 --- a/src/query.ts +++ b/src/query.ts @@ -1,7 +1,7 @@ -import { Attribute, DB } from "./db"; +import { Attribute, DB, Table } from "./db"; import { BooleanModifier, Modifier } from "./dbStructure"; import { Handler } from "./defaultHandler"; -import { primaryData, selectElements, selectFromElements, serializeReturn } from "./types"; +import { allModifierInput, primaryData, selectElements, selectFromElements, serializeReturn } from "./types"; export class Query { @@ -92,6 +92,92 @@ export class selectQuery { return handler.querys.select(handler, this); } + async query(db: DB) { + const handler = db.getHandler(); + const builder = this.serialize(handler); + const s = handler.builders.query(builder); + return await db.query(s); + } +} + +export class insertQuery { + attrs: Attribute[]; + values: primaryData[][] = []; + select: selectQuery | null = null; + constructor(attrs: Attribute[]) { + if (attrs.length == 0) throw new Error("Insertion must be done in at least one Column."); + for (let i = 0; i < attrs.length; i++) { + if (attrs[i].table != attrs[0].table) throw new Error("Insertion Columns must be in one Table."); + } + this.attrs = attrs; + } + add(...data: primaryData[]) { + if (this.select != null) throw new Error("Can not add Values when using select!"); + this.values.push(data); + return this; + } + addValues(...data: primaryData[][]) { + if (this.select != null) throw new Error("Can not add Values when using select!"); + this.values.push(...data); + return this; + } + setSelect(state: selectQuery) { + if (this.values.length != 0) throw new Error("Can not add select when using values!"); + this.select = state; + return this; + } + serialize(handler: Handler): QueryBuilder { + return handler.querys.insert(handler, this); + } + async query(db: DB) { + const handler = db.getHandler(); + const builder = this.serialize(handler); + const s = handler.builders.query(builder); + return await db.query(s); + } +} + +export class updateQuery { + table: Table; + setD: ([Attribute, allModifierInput])[] = []; + whereD: BooleanModifier | null = null; + + constructor(table: Table) { + this.table = table; + } + set(attr: Attribute, value: allModifierInput) { + if (this.table != attr.table) throw new Error("Can only edit columns of the updated table!"); + this.setD.push([attr, value]); + return this; + } + where(w: BooleanModifier) { + this.whereD = w; + return this; + } + serialize(handler: Handler): QueryBuilder { + return handler.querys.update(handler, this); + } + async query(db: DB) { + const handler = db.getHandler(); + const builder = this.serialize(handler); + const s = handler.builders.query(builder); + return await db.query(s); + } +} + +export class removeQuery { + table: Table; + whereD: BooleanModifier | null = null; + constructor(table: Table) { + this.table = table; + } + where(w: BooleanModifier) { + this.whereD = w; + return this; + } + serialize(handler: Handler): QueryBuilder { + return handler.querys.remove(handler, this); + } async query(db: DB) { const handler = db.getHandler(); const builder = this.serialize(handler);