step in evolution
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
jusax23 2023-02-13 23:44:08 +01:00
parent 37385589d6
commit 78d894c415
6 changed files with 304 additions and 86 deletions

View file

@ -1,4 +1,4 @@
# DBlang # DBlang
sql Querys with js ot ts Syntax. sql Querys with js or ts Syntax.
[![status-badge](https://ci.jusax.de/api/badges/jusax23/dblang/status.svg)](https://ci.jusax.de/jusax23/dblang) [![status-badge](https://ci.jusax.de/api/badges/jusax23/dblang/status.svg)](https://ci.jusax.de/jusax23/dblang)

View file

@ -1,37 +1,38 @@
import mariadb from 'mariadb'; import mariadb from 'mariadb';
import { checkConstraint, Constraint, Datatype, uniqueConstraint } from './dbStructure'; import { checkConstraint, Constraint, Datatype, uniqueConstraint } from './dbStructure';
import { Handler } from './defaultHandler'; import { Handler } from './defaultHandler';
import { Query, selectQuery } from './query'; import { Query } from './query';
import { attributeSettings, extendedAttributeSettings, onAction, primaryData, serializeReturn } from './types'; import { attributeSettings, extendedAttributeSettings, onAction } from './types';
export class DB { export class DB {
tables:Table[] = []; tables: Table[] = [];
handler: Handler; handler: Handler;
name: string; name: string;
//pool:mariadb.Pool; pool: mariadb.Pool;
constructor(/*{ host, user, password, database, connectionLimit = 5 }*/) { constructor({ host, user, password, database, connectionLimit = 5 }: { host: string, user: string, password: string, database: string, connectionLimit: number }) {
//this.pool = mariadb.createPool({ host, user, password, database, connectionLimit, multipleStatements: true }); this.pool = mariadb.createPool({ host, user, password, database, connectionLimit, multipleStatements: true });
this.handler = new Handler(); this.handler = new Handler();
this.name = "notimplemented" this.name = database;
} }
async query(query: Query) { async query(query: Query) {
console.log(query); console.log(query);
//return this.pool.query(query); return await this.pool.query(query);
} }
getHandler() { getHandler() {
return this.handler; return this.handler;
} }
sync(){ async sync() {
let handler = this.getHandler(); let handler = this.getHandler();
this.tables.forEach(t=>{ await handler.syncDB(this, handler);
console.log(new Query(handler.builders.query(handler.querys.create(handler,t)))); //this.tables.forEach(t=>{
}) // console.log(handler.builders.query(handler.querys.create(handler,t)));
//})
} }
newTable(name: string) { newTable(name: string) {
let tabel = new Table(name,this); let tabel = new Table(name, this);
this.tables.push(tabel); this.tables.push(tabel);
return tabel; return tabel;
} }
@ -42,39 +43,40 @@ export class Attribute {
table: Table; table: Table;
ops: attributeSettings; ops: attributeSettings;
type: Datatype; type: Datatype;
constructor(name: string, table:Table, type: Datatype, ops: attributeSettings) { constructor(name: string, table: Table, type: Datatype, ops: attributeSettings) {
this.name = name; this.name = name;
this.ops = ops;
this.type = type; this.type = type;
this.table = table; this.table = table;
this.ops = ops;
if(ops.check != null){ if (ops.check != null) {
if(typeof ops.check == "function")ops.check = ops.check(this);
table.addConstraint(new checkConstraint( table.addConstraint(new checkConstraint(
table.dbLangDatabaseInstance.name+"_"+table.dbLangTableName+"_"+name+"_check_constraint", table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_check_constraint",
ops.check ops.check
)) ))
} }
if(ops.unique != null){ if (ops.unique != null) {
table.addConstraint(new uniqueConstraint( table.addConstraint(new uniqueConstraint(
table.dbLangDatabaseInstance.name+"_"+table.dbLangTableName+" "+name+"_unique_constraint", table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + " " + name + "_unique_constraint",
[this] [this]
)) ))
} }
} }
serializeDatatype(handler : Handler){ serializeDatatype(handler: Handler) {
return this.type.serialize(handler); return this.type.serialize(handler);
} }
serializeSettings(handler : Handler){ serializeSettings(handler: Handler) {
return handler.builders.attributeSettings(handler,this); return handler.builders.attributeSettings(handler, this);
} }
serialize(handler : Handler) { serialize(handler: Handler) {
return handler.builders.escapeID(this.name); return handler.builders.escapeID(this.name);
} }
toString(handler : Handler = this.table.dbLangDatabaseInstance.getHandler()) { toString(handler: Handler = this.table.dbLangDatabaseInstance.getHandler()) {
return this.table.serialize(handler)+"."+this.serialize(handler); return this.table.serialize(handler) + "." + this.serialize(handler);
} }
toStringFunc(handler : Handler){ toStringFunc(handler: Handler) {
return this.table.serialize(handler)+"("+this.serialize(handler)+")"; return this.table.serialize(handler) + "(" + this.serialize(handler) + ")";
} }
} }
@ -84,34 +86,34 @@ export class Table {
dbLangTableAttributes: { [key: string]: Attribute; } = {}; dbLangTableAttributes: { [key: string]: Attribute; } = {};
dbLangDatabaseInstance: DB; dbLangDatabaseInstance: DB;
dbLangConstrains: Constraint[] = []; dbLangConstrains: Constraint[] = [];
[key: string]: Attribute | any [key: string]: Attribute | any;
constructor(name: string, db:DB) { constructor(name: string, db: DB) {
this.dbLangTableName = name; this.dbLangTableName = name;
this.dbLangDatabaseInstance = db; this.dbLangDatabaseInstance = db;
} }
serialize(handler : Handler) { serialize(handler: Handler) {
return this.toString(handler); return this.toString(handler);
} }
toString(handler : Handler = this.dbLangDatabaseInstance.getHandler()) { toString(handler: Handler = this.dbLangDatabaseInstance.getHandler()) {
return handler.builders.escapeID(this.dbLangTableName); return handler.builders.escapeID(this.dbLangTableName);
} }
addAttribute(name: string, type: Datatype, ops: attributeSettings = {}, noErrorOnNameConflict = false) { addAttribute(name: string, type: Datatype, ops: attributeSettings = {}, noErrorOnNameConflict = false) {
if(this.dbLangTableAttributes[name] != null) throw new Error("You are tring to create an Attribute twise!"); if (this.dbLangTableAttributes[name] != null) throw new Error("You are tring to create an Attribute twise!");
let attr = new Attribute(name,this,type,ops); let attr = new Attribute(name, this, type, ops);
this.dbLangTableAttributes[name] = attr; this.dbLangTableAttributes[name] = attr;
if (["serialize", "toString", "addAttribute", "dbLangTableName", "dbLangTableAttributes", "dbLangDatabaseInstance","addConstraint","addAttributes"].includes(name)) { if (["serialize", "toString", "addAttribute", "dbLangTableName", "dbLangTableAttributes", "dbLangDatabaseInstance", "addConstraint", "addAttributes"].includes(name)) {
if (!noErrorOnNameConflict) throw new Error("You cannot name Attribute like Methode of this Table!"); if (!noErrorOnNameConflict) throw new Error("You cannot name Attribute like Methode of this Table!");
} else { } else {
this[name] = attr; this[name] = attr;
} }
return attr; return attr;
} }
addAttributes(list:{[key: string]:extendedAttributeSettings}):{[key: string]:Attribute} { addAttributes(list: { [key: string]: (extendedAttributeSettings) }): { [key: string]: Attribute } {
return Object.fromEntries(Object.entries(list).map(([k,a])=>{ return Object.fromEntries(Object.entries(list).map(([k, a]) => {
return [k,this.addAttribute(k,a.type,a)]; return [k, this.addAttribute(k, a.type, a)];
})); }));
} }
addConstraint(c:Constraint){ addConstraint(c: Constraint) {
c.check(this); c.check(this);
this.dbLangConstrains.push(c); this.dbLangConstrains.push(c);
} }

View file

@ -64,7 +64,7 @@ export class checkConstraint implements Constraint{
this.checkQuery = check; this.checkQuery = check;
} }
check(attr: Table): boolean { check(attr: Table): boolean {
throw new Error("Method not implemented."); return true;
} }
uses(attr: Attribute): boolean { uses(attr: Attribute): boolean {
throw new Error("Method not implemented."); throw new Error("Method not implemented.");
@ -76,19 +76,19 @@ export class checkConstraint implements Constraint{
export class uniqueConstraint implements Constraint{ export class uniqueConstraint implements Constraint{
name: string; name: string;
attr: Attribute[]; attrs: Attribute[];
constructor(name:string, attr:Attribute[]){ constructor(name:string, attrs:Attribute[]){
this.name = name; this.name = name;
this.attr = attr; this.attrs = attrs;
} }
check(table: Table): boolean|string { check(table: Table): boolean|string {
for(let i = 0; i < this.attr.length; i++){ for(let i = 0; i < this.attrs.length; i++){
if(this.attr[i].ops.primaryKey) return "Can not combine unique Constraint and primary key"; if(this.attrs[i].ops.primaryKey) return "Can not combine unique Constraint and primary key";
} }
return false; return false;
} }
uses(attr: Attribute): boolean { uses(attr: Attribute): boolean {
throw new Error("Method not implemented."); return this.attrs.includes(attr);
} }
serialize(handler: Handler): QueryBuilder { serialize(handler: Handler): QueryBuilder {
throw new Error("Method not implemented."); throw new Error("Method not implemented.");

View file

@ -1,12 +1,115 @@
import { Attribute, DB, Table } from "./db" import { Attribute, DB, Table } from "./db"
import { Aggregation, Modifier } from "./dbStructure" import { Aggregation, checkConstraint, Constraint, Datatype, Modifier, uniqueConstraint } from "./dbStructure"
import { QueryBuilder, selectQuery } from "./query" import { Query, QueryBuilder, selectQuery } from "./query"
import { allModifierInput, primaryData, serializeReturn } from "./types" import { allModifierInput, primaryData, serializeReturn } from "./types"
export class Handler { export class Handler {
/*syncDB(db : DB){ async syncDB(db: DB, handler: Handler, deleteInDB: boolean = false) {
console.log("start sync");
}*/ let gd = new QueryBuilder();
gd.addCode(`SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA = `);
gd.addInjection(db.name);
gd.addCode(` or TABLE_SCHEMA = `);
gd.addInjection(db.name);
gd.addCode(`;select * from information_schema.table_constraints where CONSTRAINT_SCHEMA = `);
gd.addInjection(db.name)
gd.addCode(` or TABLE_SCHEMA = `);
gd.addInjection(db.name);
let [key, constraints] = await db.query(handler.builders.query(gd));
let tableData = [];
for (let i = 0; i < db.tables.length; i++) {
const table = db.tables[i];
try {
const tableDataBuilder = new QueryBuilder();
tableDataBuilder.addCode("DESCRIBE ");
tableDataBuilder.addCode(table.serialize(handler));
tableData[i] = Object.fromEntries((await db.query(handler.builders.query(tableDataBuilder))).map((d: any) => [d.Field, d]));
} catch (_) {
tableData[i] = null;
}
}
const del = new QueryBuilder();
const create = new QueryBuilder();
for (let i = 0; i < constraints.length; i++) {
const c = constraints[i];
if (c.CONSTRAINT_TYPE == "CHECK") {
del.appendEnding(handler.querys.removeCheck(handler, c.TABLE_NAME, c.CONSTRAINT_NAME));
}
}
// TODO: delete old constraints/tables
function freeForUpdate(a: Attribute) {
for (let i = 0; i < key.length; i++) {
const k = key[i];
if (
k.REFERENCED_TABLE_NAME == a.table.dbLangTableName
&& k.REFERENCED_TABLE_NAME == a.name
) {
del.appendEnding(handler.querys.removeForeignKey(handler, k.TABLE_NAME, k.CONSTRAINT_NAME));
}
}
}
//create tables
for (let i = 0; i < db.tables.length; i++) {
const table = db.tables[i];
const tableD = tableData[i];
let changePrimary = false;
if (tableD == null) {
create.appendEnding(handler.querys.create(handler, table));
changePrimary = true;
} else {
let keys = Object.keys(table.dbLangTableAttributes);
for (let j = 0; j < keys.length; j++) {
const a = table.dbLangTableAttributes[keys[j]];
const attrData = tableD[keys[j]];
if (attrData == null) {
create.appendEnding(handler.querys.addColumn(handler, a));
changePrimary = true;
} else if (
!handler.builders.compareDatatypes(handler, a.type, attrData.Type) ||
a.ops.default != attrData.Default ||
(!!a.ops.notNull || !!a.ops.autoIncrement || !!a.ops.primaryKey) != (attrData.Null == "NO") ||
(!!a.ops.autoIncrement) != (attrData.Extra == "auto_increment")
) {
console.log(!handler.builders.compareDatatypes(handler, a.type, attrData.Type), "|",
a.ops.default, attrData.Default, "|",
(!!a.ops.notNull || !!a.ops.autoIncrement || !!a.ops.primaryKey), (attrData.Null == "NO"), "|",
(!!a.ops.autoIncrement), (attrData.Extra == "auto_increment"));
freeForUpdate(a);
create.appendEnding(handler.querys.changeColumn(handler, a));
}
if (attrData == null) {
changePrimary = true;
} else {
if ((attrData.Key == "PRI") != (!!a.ops.primaryKey)) {
freeForUpdate(a);
changePrimary = true;
}
}
}
}
if (changePrimary) {
create.appendEnding(handler.querys.removePrimaryKey(handler, table));
create.appendEnding(handler.querys.addPrimaryKey(handler, table));
}
for (let j = 0; j < table.dbLangConstrains.length; j++) {
const c = table.dbLangConstrains[j];
if (c instanceof checkConstraint) {
create.appendEnding(handler.querys.addCheck(handler, table, c));
}
}
// TODO: unique
}
if (!create.isEmpty()) del.append(create);
if (!del.isEmpty()) await db.query(handler.builders.query(del));
}
querys = { querys = {
select: (handler: Handler, q: selectQuery): QueryBuilder => { select: (handler: Handler, q: selectQuery): QueryBuilder => {
@ -26,11 +129,15 @@ export class Handler {
builder.append(q.havingD.serialize(handler)); builder.append(q.havingD.serialize(handler));
} }
} }
if (q.havingD) { if (q.havingD) {
builder.addCode(" limit "); builder.addCode(" limit ");
builder.addInjection(q.limitD); builder.addInjection(q.limitD);
} }
/*builder.setHandler((json)=>{
return json;
});*/
return builder; return builder;
}, },
create: (handler: Handler, table: Table): QueryBuilder => { create: (handler: Handler, table: Table): QueryBuilder => {
@ -46,16 +153,102 @@ export class Handler {
builder.addCode(")"); builder.addCode(")");
return builder; return builder;
}, },
addColumn: (handler: Handler, attr: Attribute): QueryBuilder => {
const builder = new QueryBuilder();
builder.addCode(`alter table `);
builder.addCode(attr.table.toString(handler));
builder.addCode(` add if not exists `);
builder.addCode(attr.serialize(handler) + " ");
builder.append(attr.serializeSettings(handler));
return builder;
},
changeColumn: (handler: Handler, attr: Attribute): QueryBuilder => {
const builder = new QueryBuilder();
builder.addCode(`alter table `);
builder.addCode(attr.table.toString(handler));
builder.addCode(` change `);
builder.addCode(attr.serialize(handler) + " ");
builder.addCode(attr.serialize(handler) + " ");
builder.append(attr.serializeSettings(handler));
return builder;
},
addForeignKey: (handler: Handler, table: Table) => {
const builder = new QueryBuilder();
} return builder;
},
removeForeignKey: (handler: Handler, tablenName: string, name: string) => {
const builder = new QueryBuilder();
builder.addCode("ALTER TABLE ");
builder.addCode(handler.builders.escapeID(tablenName));
builder.addCode(" DROP FOREIGN KEY IF EXISTS ");
builder.addCode(handler.builders.escapeID(name));
builder.addCode(";ALTER TABLE ");
builder.addCode(handler.builders.escapeID(tablenName));
builder.addCode(" DROP INDEX IF EXISTS ");
builder.addCode(handler.builders.escapeID(name));
constraints = { return builder;
// check constraints },
listPrimaryKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), addPrimaryKey: (handler: Handler, table: Table) => {
listForeignKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), const qb = new QueryBuilder();
listUniqueKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), qb.addCode("ALTER TABLE ");
listChecks: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), qb.addCode(table.serialize(handler));
// add constraints qb.addCode(" add PRIMARY KEY if not exists (");
qb.addCodeCommaSeperated(
Object.entries(table.dbLangTableAttributes)
.filter(([n, attr]) => !!attr.ops.primaryKey)
.map(([n, attr]) => handler.builders.escapeID(n))
);
qb.addCode(")");
return qb;
},
removePrimaryKey: (handler: Handler, table: Table) => {
const qb = new QueryBuilder();
qb.addCode("ALTER TABLE ");
qb.addCode(table.serialize(handler));
qb.addCode(" DROP INDEX IF EXISTS `PRIMARY`");
return qb;
},
removeCheck: (handler: Handler, table: string, name: string) => {
const qb = new QueryBuilder();
qb.addCode("ALTER TABLE ");
qb.addCode(handler.builders.escapeID(table));
qb.addCode(" DROP CONSTRAINT IF EXISTS ");
qb.addCode(handler.builders.escapeID(name));
return qb;
},
addCheck: (handler: Handler, table: Table, c: checkConstraint) => {
const qb = new QueryBuilder();
qb.addCode(`ALTER TABLE `);
qb.addCode(table.serialize(handler));
qb.addCode(` ADD CONSTRAINT `);
qb.addCode(handler.builders.escapeID(c.name));
qb.addCode(` CHECK (`);
qb.append(c.checkQuery.serialize(handler));
qb.addCode(")");
return qb;
},
removeUnique: (handler: Handler, table: string, name: string) => {
const qb = new QueryBuilder();
qb.addCode("ALTER TABLE ");
qb.addCode(handler.builders.escapeID(table));
qb.addCode(" DROP INDEX IF EXISTS ");
qb.addCode(handler.builders.escapeID(name));
return qb;
},
addUnique: (handler: Handler, table: Table, u: uniqueConstraint) => {
const qb = new QueryBuilder();
qb.addCode("ALTER TABLE ");
qb.addCode(table.serialize(handler));
qb.addCode(" ADD CONSTRAINT ");
qb.addCode(handler.builders.escapeID(u.name));
qb.addCode(" UNIQUE (");
qb.addCodeCommaSeperated(u.attrs.map(a => a.serialize(handler)));
qb.addCode(")");
return qb;
},
/*// add constraints
appPrimaryKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), appPrimaryKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
appForeignKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), appForeignKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
addUniqueKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), addUniqueKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
@ -65,10 +258,15 @@ export class Handler {
dropForeignKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), dropForeignKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
dropUniqueKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), dropUniqueKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
dropChecks: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(), dropChecks: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
// check constraints
listPrimaryKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
listForeignKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
listUniqueKeys: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),
listChecks: (handler: Handler, table: Table): QueryBuilder => new QueryBuilder(),*/
} }
builders = { builders = {
query: (qb: QueryBuilder): serializeReturn => { query: (qb: QueryBuilder): Query => {
let args: primaryData[] = []; let args: primaryData[] = [];
let sql = ""; let sql = "";
for (let i = 0; i < qb.list.length; i++) { for (let i = 0; i < qb.list.length; i++) {
@ -80,7 +278,7 @@ export class Handler {
sql += data; sql += data;
} }
} }
return [sql, args]; return new Query([sql, args]);
}, },
attributeSettings: (handler: Handler, a: Attribute): QueryBuilder => { attributeSettings: (handler: Handler, a: Attribute): QueryBuilder => {
@ -89,38 +287,34 @@ export class Handler {
if (a.ops.autoIncrement) { if (a.ops.autoIncrement) {
builder.addCode(" auto_increment"); builder.addCode(" auto_increment");
} }
/*if (a.ops.primaryKey) {
sql += " primary key";
}*/
if (a.ops.default != null) { if (a.ops.default != null) {
if (a.ops.autoIncrement || a.ops.primaryKey || a.ops.notNull) 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)}`); throw new Error(`Can not set default when autoIncrement, primaryKey or notNull ist set on Attribute: ${a.toStringFunc(handler)}`);
builder.addCode(" default "); builder.addCode(" default ");
builder.addInjection(a.ops.default); builder.addInjection(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.notNull != null) {
if (!a.ops.autoIncrement && !a.ops.primaryKey && a.ops.default == null) { if (!a.ops.autoIncrement && !a.ops.primaryKey && a.ops.default == null) {
builder.addCode(" not null"); builder.addCode(" not null");
} } else builder.addCode(" null");
} } else builder.addCode(" null");
/*if (a.ops.foreginKey != null) {
sql += ` foreign key references (${a.ops.foreginKey.link.toStringFunc(handler)})`
}*/
return builder; return builder;
}, },
escapeID: (key: string): string => { escapeID: (key: string): string => {
if (!key || key === "" || key.includes('\u0000')) throw new Error("Can not escape empty key or with null unicode!"); if (!key || key === "" || key.includes('\u0000')) throw new Error("Can not escape empty key or with null unicode!");
if (key.match(/^`.+`$/g)) return key; if (key.match(/^`.+`$/g)) return key;
return `\`${key.replace(/`/g, '``')}\``; return `\`${key.replace(/`/g, '``')}\``;
},
compareDatatypes: (handler: Handler, attr: Datatype, curr: String) => {
let qb = attr.serialize(handler);
let sql = "";
for (let i = 0; i < qb.list.length; i++) {
const [inject, data] = qb.list[i];
sql += data;
} }
return curr.split(" ").join("").startsWith(sql.split(" ").join(""));
},
} }
@ -200,7 +394,7 @@ export class Handler {
double: dataTypeDblNum("double"), double: dataTypeDblNum("double"),
decimal: dataTypeDblNum("decimal"), decimal: dataTypeDblNum("decimal"),
date: dataTypeNoArg("data"), date: dataTypeNoArg("date"),
datetime: dataTypeNoArg("datatime"), datetime: dataTypeNoArg("datatime"),
timestamp: dataTypeNoArg("timestamp"), timestamp: dataTypeNoArg("timestamp"),
time: dataTypeNoArg("time"), time: dataTypeNoArg("time"),

View file

@ -16,6 +16,7 @@ export class Query {
export class QueryBuilder { export class QueryBuilder {
//injekt and data //injekt and data
list: ([boolean, primaryData])[] = []; list: ([boolean, primaryData])[] = [];
constructor(l?: ({ inject?: boolean, data: primaryData })[]) { constructor(l?: ({ inject?: boolean, data: primaryData })[]) {
if (Array.isArray(l)) if (Array.isArray(l))
for (let i = 0; i < l.length; i++) { for (let i = 0; i < l.length; i++) {
@ -26,6 +27,13 @@ export class QueryBuilder {
addCode(text: string) { addCode(text: string) {
this.list.push([false, text]); this.list.push([false, text]);
} }
addCodeCommaSeperated(data: string[], comma = ", ") {
for (let i = 0; i < data.length; i++) {
const e = data[i];
this.list.push([false, e]);
if(i+1<data.length)this.list.push([false, comma]);
}
}
addInjection(data: primaryData) { addInjection(data: primaryData) {
this.list.push([true, data]); this.list.push([true, data]);
} }
@ -39,6 +47,16 @@ export class QueryBuilder {
append(qb: QueryBuilder) { append(qb: QueryBuilder) {
this.list.push(...qb.list); this.list.push(...qb.list);
} }
appendEnding(qb: QueryBuilder){
this.append(qb);
this.list.push([false,";"]);
}
isEmpty(){
return this.list.length == 0;
}
/*setHandler(fun:(d:any)=>any){
}*/
} }
@ -74,9 +92,10 @@ export class selectQuery {
return handler.querys.select(handler, this); return handler.querys.select(handler, this);
} }
query(db: DB) { async query(db: DB) {
const handler = db.getHandler(); const handler = db.getHandler();
const s = handler.builders.query(this.serialize(handler)); const builder = this.serialize(handler);
return db.query(new Query(s)); const s = handler.builders.query(builder);
return await db.query(s);
} }
} }

View file

@ -1,6 +1,6 @@
import { Attribute, Table } from "./db"; import { Attribute, Table } from "./db";
import { Aggregation, BooleanModifier, Datatype, Joins, Modifier } from "./dbStructure"; import { Aggregation, BooleanModifier, Datatype, Joins, Modifier } from "./dbStructure";
import { selectQuery } from "./query"; import { QueryBuilder, selectQuery } from "./query";
export type primaryData = string | number | boolean | null; export type primaryData = string | number | boolean | null;
export type allModifierInput = primaryData | Modifier | selectQuery | Attribute | Aggregation; export type allModifierInput = primaryData | Modifier | selectQuery | Attribute | Aggregation;
@ -10,6 +10,8 @@ export type selectFromElements = Table | Joins | null;
export type serializeReturn = [string, primaryData[]]; export type serializeReturn = [string, primaryData[]];
export type DatatypeBuild = [QueryBuilder, number];
export type attributeSettings = { export type attributeSettings = {
unique?: boolean, unique?: boolean,
autoIncrement?: boolean, autoIncrement?: boolean,
@ -21,8 +23,9 @@ export type attributeSettings = {
onDelete?: onAction, onDelete?: onAction,
onUpdate?: onAction onUpdate?: onAction
}, },
check?:BooleanModifier check?: BooleanModifier | ((a: Attribute) => BooleanModifier)
}; };
export type extendedAttributeSettings = { export type extendedAttributeSettings = {
type: Datatype, type: Datatype,
unique?: boolean, unique?: boolean,
@ -35,7 +38,7 @@ export type extendedAttributeSettings = {
onDelete?: onAction, onDelete?: onAction,
onUpdate?: onAction onUpdate?: onAction
}, },
check?:BooleanModifier check?: BooleanModifier | ((a: Attribute) => BooleanModifier)
} }
export enum onAction { export enum onAction {