import mariadb from 'mariadb'; import { checkConstraint, Constraint, Datatype, foreignConstraint, uniqueConstraint } from './dbStructure'; import { Handler } from './defaultHandler'; import { Query } from './query'; import { attributeSettings, extendedAttributeSettings, onAction } from './types'; export class DB { tables: Table[] = []; handler: Handler; name: string; pool: mariadb.Pool; 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.handler = new Handler(); this.name = database; } async query(query: Query) { //console.log(query); return await this.pool.query(query); } getHandler() { return this.handler; } async sync(force = false) { let handler = this.getHandler(); await handler.syncDB(this, handler, force); //this.tables.forEach(t=>{ // console.log(handler.builders.query(handler.querys.create(handler,t))); //}) } newTable(name: string) { let tabel = new Table(name, this); this.tables.push(tabel); return tabel; } getTable(name: string) { for (let i = 0; i < this.tables.length; i++) if (this.tables[i].dbLangTableName == name) return this.tables[i]; return null; } async close() { if (this.pool) await this.pool.end(); } } export class Attribute { name: string; table: Table; ops: attributeSettings; type: Datatype; constructor(name: string, table: Table, type: Datatype, ops: attributeSettings) { this.name = name.toLowerCase(); this.type = type; this.table = table; this.ops = ops; if (ops.check != null) { if (typeof ops.check == "function") ops.check = ops.check(this); table.addConstraint(new checkConstraint( table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_check_constraint", ops.check )) } if (ops.unique != null) { table.addConstraint(new uniqueConstraint( table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_unique_constraint", [this] )) } if (ops.foreginKey != null) { table.addConstraint(new foreignConstraint( table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_foreign_constraint_to_" + ops.foreginKey.link.name, [this], [ops.foreginKey.link], ops.foreginKey.onDelete, ops.foreginKey.onUpdate )); } } serializeDatatype(handler: Handler) { return this.type.serialize(handler); } serializeSettings(handler: Handler) { return handler.builders.attributeSettings(handler, this); } serialize(handler: Handler) { return handler.builders.escapeID(this.name); } toString(handler: Handler = this.table.dbLangDatabaseInstance.getHandler()) { return this.table.serialize(handler) + "." + this.serialize(handler); } toStringFunc(handler: Handler) { return this.table.serialize(handler) + "(" + this.serialize(handler) + ")"; } } export class Table { dbLangTableName: string; dbLangTableAttributes: { [key: string]: Attribute; } = {}; dbLangDatabaseInstance: DB; dbLangConstrains: Constraint[] = []; [key: string]: Attribute | any; constructor(name: string, db: DB) { this.dbLangTableName = name; this.dbLangDatabaseInstance = db; } serialize(handler: Handler) { return this.toString(handler); } toString(handler: Handler = this.dbLangDatabaseInstance.getHandler()) { return handler.builders.escapeID(this.dbLangTableName); } addAttribute(name: string, type: Datatype, ops: attributeSettings = {}, noErrorOnNameConflict = false) { let lowName = name.toLowerCase(); if (this.dbLangTableAttributes[lowName] != null) throw new Error("You are tring to create an Attribute twise!"); let attr = new Attribute(lowName, this, type, ops); this.dbLangTableAttributes[lowName] = attr; if (["serialize", "toString", "addAttribute", "dbLangTableName", "dbLangTableAttributes", "dbLangDatabaseInstance", "addConstraint", "addAttributes"].includes(lowName)) { if (!noErrorOnNameConflict) throw new Error("You cannot name Attribute like Methode of this Table!"); } else { this[lowName] = attr; this[name] = attr; } return attr; } addAttributes(list: { [key: string]: (extendedAttributeSettings) }): { [key: string]: Attribute } { return Object.fromEntries(Object.entries(list).map(([k, a]) => { return [k, this.addAttribute(k, a.type, a)]; })); } addConstraint(c: Constraint) { c.check(this); this.dbLangConstrains.push(c); } } export * from './funcs'; export { onAction };