2023-01-23 21:19:18 +01:00
|
|
|
import mariadb from 'mariadb';
|
2023-02-14 17:37:01 +01:00
|
|
|
import { checkConstraint, Constraint, Datatype, foreignConstraint, uniqueConstraint } from './dbStructure';
|
2023-01-23 21:19:18 +01:00
|
|
|
import { Handler } from './defaultHandler';
|
2023-02-13 23:44:08 +01:00
|
|
|
import { Query } from './query';
|
2023-02-17 22:04:24 +01:00
|
|
|
import { attributeSettings, extendedAttributeSettings, onAction, dbType } from './types';
|
2023-02-18 14:47:44 +01:00
|
|
|
import { TableAlias } from "./alias"
|
2023-02-17 22:04:24 +01:00
|
|
|
//import { postgresHandler } from "./postgresHandler"
|
2023-01-23 21:19:18 +01:00
|
|
|
|
|
|
|
|
|
|
|
export class DB {
|
2023-02-13 23:44:08 +01:00
|
|
|
tables: Table[] = [];
|
2023-01-24 20:34:03 +01:00
|
|
|
handler: Handler;
|
2023-01-29 22:11:24 +01:00
|
|
|
name: string;
|
2023-02-17 22:04:24 +01:00
|
|
|
type: dbType;
|
|
|
|
mariaPool!: mariadb.Pool;
|
|
|
|
//pgPool!: pg.Pool;
|
2023-02-19 13:43:19 +01:00
|
|
|
constructor({ host, user, password, database, connectionLimit = 5, databaseType = dbType.mariadb }: { host: string, user: string, password: string, database: string, connectionLimit?: number, databaseType?: dbType }) {
|
2023-02-17 22:04:24 +01:00
|
|
|
this.type = databaseType;
|
|
|
|
if (databaseType == dbType.mariadb) {
|
2023-02-18 14:53:07 +01:00
|
|
|
this.mariaPool = mariadb.createPool({ host, user, password, database, connectionLimit, multipleStatements: true });
|
2023-02-18 11:45:23 +01:00
|
|
|
this.handler = new Handler(this);
|
2023-02-17 22:04:24 +01:00
|
|
|
}
|
|
|
|
/*else if (databaseType == dbType.postgres) {
|
|
|
|
this.pgPool = new pg.Pool({ host, user, password, max: connectionLimit, database, idleTimeoutMillis: 30000, connectionTimeoutMillis: 2000 });
|
2023-02-18 11:45:23 +01:00
|
|
|
this.handler = new postgresHandler(this);
|
2023-02-17 22:04:24 +01:00
|
|
|
}*/
|
|
|
|
else throw new Error("Unsuported Database type!");
|
|
|
|
|
2023-02-13 23:44:08 +01:00
|
|
|
this.name = database;
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
|
|
|
async query(query: Query) {
|
2023-02-18 14:47:44 +01:00
|
|
|
console.log(query);
|
2023-02-17 22:04:24 +01:00
|
|
|
if (this.type == dbType.mariadb) return await this.mariaPool.query(query);
|
|
|
|
/*else if (this.type == dbType.postgres) {
|
|
|
|
let res = await this.pgPool.query(query.sql, query.values);
|
|
|
|
console.log([...res.rows]);
|
|
|
|
return res.rows;
|
|
|
|
}*/
|
|
|
|
else throw new Error("Invalid Database Type!");
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
|
|
|
getHandler() {
|
2023-01-24 20:34:03 +01:00
|
|
|
return this.handler;
|
|
|
|
}
|
|
|
|
|
2023-02-14 16:45:21 +01:00
|
|
|
async sync(force = false) {
|
2023-01-24 20:34:03 +01:00
|
|
|
let handler = this.getHandler();
|
2023-02-14 16:45:21 +01:00
|
|
|
await handler.syncDB(this, handler, force);
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
|
|
|
|
2023-01-23 22:10:33 +01:00
|
|
|
newTable(name: string) {
|
2023-02-13 23:44:08 +01:00
|
|
|
let tabel = new Table(name, this);
|
2023-01-24 20:34:03 +01:00
|
|
|
this.tables.push(tabel);
|
|
|
|
return tabel;
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
2023-02-14 16:45:21 +01:00
|
|
|
|
2023-02-14 17:37:01 +01:00
|
|
|
getTable(name: string) {
|
|
|
|
for (let i = 0; i < this.tables.length; i++) if (this.tables[i].dbLangTableName == name) return this.tables[i];
|
2023-02-14 16:45:21 +01:00
|
|
|
return null;
|
|
|
|
}
|
2023-02-14 20:40:25 +01:00
|
|
|
async close() {
|
2023-02-17 22:04:24 +01:00
|
|
|
if (this.type == dbType.mariadb && this.mariaPool) await this.mariaPool.end();
|
|
|
|
//if (this.type == dbType.postgres && this.pgPool) await this.pgPool.end();
|
2023-02-14 20:40:25 +01:00
|
|
|
}
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Attribute {
|
2023-01-23 22:10:33 +01:00
|
|
|
name: string;
|
2023-02-18 14:47:44 +01:00
|
|
|
nameO: string;
|
2023-01-24 20:34:03 +01:00
|
|
|
table: Table;
|
2023-01-24 10:40:16 +01:00
|
|
|
ops: attributeSettings;
|
|
|
|
type: Datatype;
|
2023-02-18 14:47:44 +01:00
|
|
|
constructor(name: string, nameO: string, table: Table, type: Datatype, ops: attributeSettings) {
|
2023-02-14 16:45:21 +01:00
|
|
|
this.name = name.toLowerCase();
|
2023-02-18 14:47:44 +01:00
|
|
|
this.nameO = nameO;
|
2023-01-24 10:40:16 +01:00
|
|
|
this.type = type;
|
2023-01-24 20:34:03 +01:00
|
|
|
this.table = table;
|
2023-02-13 23:44:08 +01:00
|
|
|
this.ops = ops;
|
|
|
|
|
|
|
|
if (ops.check != null) {
|
2023-02-14 17:37:01 +01:00
|
|
|
if (typeof ops.check == "function") ops.check = ops.check(this);
|
2023-01-29 22:11:24 +01:00
|
|
|
table.addConstraint(new checkConstraint(
|
2023-02-13 23:44:08 +01:00
|
|
|
table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_check_constraint",
|
2023-01-29 22:11:24 +01:00
|
|
|
ops.check
|
|
|
|
))
|
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
if (ops.unique != null) {
|
2023-01-29 22:11:24 +01:00
|
|
|
table.addConstraint(new uniqueConstraint(
|
2023-02-14 16:45:21 +01:00
|
|
|
table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_unique_constraint",
|
2023-01-29 22:11:24 +01:00
|
|
|
[this]
|
|
|
|
))
|
|
|
|
}
|
2023-02-14 17:37:01 +01:00
|
|
|
if (ops.foreginKey != null) {
|
|
|
|
table.addConstraint(new foreignConstraint(
|
2023-02-14 20:40:25 +01:00
|
|
|
table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_foreign_constraint_to_" + ops.foreginKey.link.name,
|
2023-02-14 17:37:01 +01:00
|
|
|
[this],
|
|
|
|
[ops.foreginKey.link],
|
|
|
|
ops.foreginKey.onDelete,
|
|
|
|
ops.foreginKey.onUpdate
|
|
|
|
));
|
|
|
|
}
|
2023-01-24 20:34:03 +01:00
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
serializeDatatype(handler: Handler) {
|
2023-01-24 20:34:03 +01:00
|
|
|
return this.type.serialize(handler);
|
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
serializeSettings(handler: Handler) {
|
|
|
|
return handler.builders.attributeSettings(handler, this);
|
2023-01-24 10:40:16 +01:00
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
serialize(handler: Handler) {
|
2023-01-24 20:34:03 +01:00
|
|
|
return handler.builders.escapeID(this.name);
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
toString(handler: Handler = this.table.dbLangDatabaseInstance.getHandler()) {
|
|
|
|
return this.table.serialize(handler) + "." + this.serialize(handler);
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
toStringFunc(handler: Handler) {
|
|
|
|
return this.table.serialize(handler) + "(" + this.serialize(handler) + ")";
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-23 22:10:33 +01:00
|
|
|
export class Table {
|
|
|
|
dbLangTableName: string;
|
|
|
|
dbLangTableAttributes: { [key: string]: Attribute; } = {};
|
2023-01-24 20:34:03 +01:00
|
|
|
dbLangDatabaseInstance: DB;
|
2023-01-29 22:11:24 +01:00
|
|
|
dbLangConstrains: Constraint[] = [];
|
2023-02-13 23:44:08 +01:00
|
|
|
[key: string]: Attribute | any;
|
|
|
|
constructor(name: string, db: DB) {
|
2023-01-23 21:19:18 +01:00
|
|
|
this.dbLangTableName = name;
|
2023-01-29 22:11:24 +01:00
|
|
|
this.dbLangDatabaseInstance = db;
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
serialize(handler: Handler) {
|
2023-01-24 20:34:03 +01:00
|
|
|
return this.toString(handler);
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
toString(handler: Handler = this.dbLangDatabaseInstance.getHandler()) {
|
2023-01-24 20:34:03 +01:00
|
|
|
return handler.builders.escapeID(this.dbLangTableName);
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
2023-01-24 20:34:03 +01:00
|
|
|
addAttribute(name: string, type: Datatype, ops: attributeSettings = {}, noErrorOnNameConflict = false) {
|
2023-02-14 18:13:06 +01:00
|
|
|
let lowName = name.toLowerCase();
|
|
|
|
if (this.dbLangTableAttributes[lowName] != null) throw new Error("You are tring to create an Attribute twise!");
|
2023-02-18 14:47:44 +01:00
|
|
|
let attr = new Attribute(lowName, name, this, type, ops);
|
2023-02-14 18:13:06 +01:00
|
|
|
this.dbLangTableAttributes[lowName] = attr;
|
2023-02-18 14:47:44 +01:00
|
|
|
if (["serialize", "toString", "addAttribute", "dbLangTableName", "dbLangTableAttributes", "dbLangDatabaseInstance", "addConstraint", "addAttributes", "createAlias"].includes(lowName)) {
|
2023-01-23 22:10:33 +01:00
|
|
|
if (!noErrorOnNameConflict) throw new Error("You cannot name Attribute like Methode of this Table!");
|
|
|
|
} else {
|
2023-02-14 18:13:06 +01:00
|
|
|
this[lowName] = attr;
|
2023-01-23 21:19:18 +01:00
|
|
|
this[name] = attr;
|
|
|
|
}
|
|
|
|
return attr;
|
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
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)];
|
2023-01-29 22:11:24 +01:00
|
|
|
}));
|
|
|
|
}
|
2023-02-13 23:44:08 +01:00
|
|
|
addConstraint(c: Constraint) {
|
2023-01-29 22:11:24 +01:00
|
|
|
c.check(this);
|
|
|
|
this.dbLangConstrains.push(c);
|
|
|
|
}
|
2023-02-18 14:47:44 +01:00
|
|
|
createAlias(name: string) {
|
|
|
|
return new TableAlias(name, this);
|
|
|
|
}
|
2023-01-23 21:19:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export * from './funcs';
|
2023-02-17 22:04:24 +01:00
|
|
|
export { onAction };
|
|
|
|
export { dbType as databaseType }
|