Aliases #3

Merged
jusax23 merged 10 commits from dev into main 2023-02-18 15:47:44 +01:00
5 changed files with 92 additions and 34 deletions
Showing only changes of commit 039ae26773 - Show all commits

View file

@ -1,9 +1,51 @@
import { Attribute, Table } from "./db"
export class TableAlias extends Table{
import { Attribute, DB, Table } from "./db"
import { Handler } from "./defaultHandler";
export class AttributeAlias {
name: string;
nameO: string;
table: TableAlias;
attr: Attribute;
constructor(attr: Attribute, table: TableAlias) {
this.name = attr.name;
this.nameO = attr.nameO;
this.attr = attr;
this.table = table;
}
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 AttributeAlias extends Attribute{
export class TableAlias {
dbLangTableName: string;
dbLangTableAttributes: { [key: string]: AttributeAlias; } = {};
dbLangDatabaseInstance: DB;
dbLangTableInstance: Table;
[key: string]: AttributeAlias | any;
constructor(name: string, table: Table) {
this.dbLangTableName = name;
this.dbLangTableInstance = table;
this.dbLangDatabaseInstance = table.dbLangDatabaseInstance;
let keys = Object.keys(table.dbLangTableAttributes);
for (let i = 0; i < keys.length; i++) {
const a = table.dbLangTableAttributes[keys[i]];
let attrAlias = new AttributeAlias(a, this);
this[a.name] = attrAlias;
this[a.nameO] = attrAlias;
this.dbLangTableAttributes[a.name] = attrAlias;
}
}
serialize(handler: Handler) {
return this.toString(handler);
}
toString(handler: Handler = this.dbLangDatabaseInstance.getHandler()) {
return handler.builders.escapeID(this.dbLangTableName);
}
}

View file

@ -3,6 +3,7 @@ import { checkConstraint, Constraint, Datatype, foreignConstraint, uniqueConstra
import { Handler } from './defaultHandler';
import { Query } from './query';
import { attributeSettings, extendedAttributeSettings, onAction, dbType } from './types';
import { TableAlias } from "./alias"
//import { postgresHandler } from "./postgresHandler"
@ -16,7 +17,7 @@ export class DB {
constructor({ host, user, password, database, connectionLimit = 5, databaseType = dbType.mariadb }: { host: string, user: string, password: string, database: string, connectionLimit: number, databaseType: dbType }) {
this.type = databaseType;
if (databaseType == dbType.mariadb) {
this.mariaPool = mariadb.createPool({ host, user, password, database, connectionLimit, multipleStatements: true });
this.mariaPool = mariadb.createPool({ host, user, password, database, connectionLimit, multipleStatements: false });
this.handler = new Handler(this);
}
/*else if (databaseType == dbType.postgres) {
@ -28,7 +29,7 @@ export class DB {
this.name = database;
}
async query(query: Query) {
//console.log(query);
console.log(query);
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);
@ -64,11 +65,13 @@ export class DB {
export class Attribute {
name: string;
nameO: string;
table: Table;
ops: attributeSettings;
type: Datatype;
constructor(name: string, table: Table, type: Datatype, ops: attributeSettings) {
constructor(name: string, nameO: string, table: Table, type: Datatype, ops: attributeSettings) {
this.name = name.toLowerCase();
this.nameO = nameO;
this.type = type;
this.table = table;
this.ops = ops;
@ -133,9 +136,9 @@ export class Table {
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);
let attr = new Attribute(lowName, name, this, type, ops);
this.dbLangTableAttributes[lowName] = attr;
if (["serialize", "toString", "addAttribute", "dbLangTableName", "dbLangTableAttributes", "dbLangDatabaseInstance", "addConstraint", "addAttributes"].includes(lowName)) {
if (["serialize", "toString", "addAttribute", "dbLangTableName", "dbLangTableAttributes", "dbLangDatabaseInstance", "addConstraint", "addAttributes", "createAlias"].includes(lowName)) {
if (!noErrorOnNameConflict) throw new Error("You cannot name Attribute like Methode of this Table!");
} else {
this[lowName] = attr;
@ -152,6 +155,9 @@ export class Table {
c.check(this);
this.dbLangConstrains.push(c);
}
createAlias(name: string) {
return new TableAlias(name, this);
}
}
export * from './funcs';

View file

@ -1,3 +1,4 @@
import { AttributeAlias, TableAlias } from "./alias";
import { Attribute, DB, Table } from "./db"
import { Aggregation, checkConstraint, joinCross, Datatype, foreignConstraint, Modifier, joinNatural, onJoin, uniqueConstraint, usingJoin } from "./dbStructure"
import { insertQuery, Query, QueryBuilder, removeQuery, selectQuery, updateQuery } from "./query"
@ -5,13 +6,13 @@ import { allModifierInput, joinType, onAction, primaryData } from "./types"
export class Handler {
db: DB;
constructor(db: DB){
constructor(db: DB) {
this.db = db;
}
async syncDB(db: DB, handler: Handler, deleteInDB: boolean = false) {
//Constraint Data
let constraints = await db.query(handler.builders.query(handler.querys.listConstraints(handler, db)));
let key = await db.query(handler.builders.query(handler.querys.listConstraintDetails(handler, db)));
let key = [...await db.query(handler.builders.query(handler.querys.listConstraintDetails(handler, db)))];
//Table List
let allTables = (await db.query(handler.builders.query(handler.querys.listTables(handler, db)))).map((d: any) => d.TABLE_NAME ?? d.table_name);
@ -23,10 +24,10 @@ export class Handler {
const tableDataBuilder = new QueryBuilder();
tableDataBuilder.addCode("DESCRIBE ");
tableDataBuilder.addCode(table.serialize(handler));
tableData[table.dbLangTableName.toLowerCase()] =
tableData[table.dbLangTableName] =
Object.fromEntries((await db.query(handler.builders.query(tableDataBuilder))).map((d: any) => [d.Field.toLowerCase(), d]));
} catch (_) {
tableData[table.dbLangTableName.toLowerCase()] = null;
tableData[table.dbLangTableName] = null;
}
}
@ -126,12 +127,12 @@ export class Handler {
del.appendEnding(handler.querys.removeCheck(handler, (c.TABLE_NAME ?? c.table_name), (c.CONSTRAINT_NAME ?? c.constraint_name)));
} else if ((c.CONSTRAINT_TYPE ?? c.constraint_type) == "UNIQUE") {
if (
(typeof tableData[(c.TABLE_NAME ?? c.table_name).toLowerCase()] == "undefined" && deleteInDB)
(typeof tableData[c.TABLE_NAME ?? c.table_name] == "undefined" && deleteInDB)
|| !checkUniqueIsVaild((c.CONSTRAINT_NAME ?? c.constraint_name), (c.TABLE_NAME ?? c.table_name))
) del.appendEnding(handler.querys.removeUnique(handler, (c.TABLE_NAME ?? c.table_name), (c.CONSTRAINT_NAME ?? c.constraint_name)));
} else if ((c.CONSTRAINT_TYPE ?? c.constraint_type) == "FOREIGN KEY") {
if (
(typeof tableData[(c.TABLE_NAME ?? c.table_name).toLowerCase()] == "undefined" && deleteInDB)
(typeof tableData[c.TABLE_NAME ?? c.table_name] == "undefined" && deleteInDB)
|| !checkForeignIsVaild((c.CONSTRAINT_NAME ?? c.constraint_name), (c.TABLE_NAME ?? c.table_name))
) del.appendEnding(handler.querys.removeForeignKey(handler, (c.TABLE_NAME ?? c.table_name), (c.CONSTRAINT_NAME ?? c.constraint_name)));
}
@ -149,6 +150,7 @@ export class Handler {
&& (k.REFERENCED_COLUMN_NAME ?? k.referenced_column_name).toLowerCase() == attr.toLowerCase()
) {
del.appendEnding(handler.querys.removeForeignKey(handler, (k.TABLE_NAME ?? k.table_name), (k.CONSTRAINT_NAME ?? k.constraint_name)));
key.splice(i--, 1);
}
}
}
@ -156,7 +158,7 @@ export class Handler {
//create tables
for (let i = 0; i < db.tables.length; i++) {
const table = db.tables[i];
const tableD = tableData[table.dbLangTableName.toLowerCase()];
const tableD = tableData[table.dbLangTableName];
//delete unused Columns
if (deleteInDB && tableD != null) {
let keys = Object.keys(tableD);
@ -191,6 +193,7 @@ export class Handler {
(!!a.ops.notNull || !!a.ops.autoIncrement || !!a.ops.primaryKey), (attrData.Null == "NO"), "|",
(!!a.ops.autoIncrement), (attrData.Extra == "auto_increment"));*/
freeForUpdate(a.name, a.table.dbLangTableName);
if (a.ops.autoIncrement)
create.appendEnding(handler.querys.changeColumn(handler, a));
}
if (attrData == null) {
@ -207,6 +210,9 @@ export class Handler {
create.appendEnding(handler.querys.removePrimaryKey(handler, table.dbLangTableName));
create.appendEnding(handler.querys.addPrimaryKey(handler, table));
}
}
for (let i = 0; i < db.tables.length; i++) {
const table = db.tables[i];
for (let j = 0; j < table.dbLangConstrains.length; j++) {
const c = table.dbLangConstrains[j];
if (c instanceof checkConstraint) {
@ -235,7 +241,7 @@ export class Handler {
builder.addCode(` from `);
if (q.from == null) {
builder.addCode(" DUAL");
} else if (q.from instanceof Table) {
} else if (q.from instanceof Table || q.from instanceof TableAlias) {
builder.addCode(q.from.serialize(handler));
} else {
builder.append(q.from.serialize(handler));
@ -299,7 +305,7 @@ export class Handler {
const s = q.setD[i];
qb.addCode(s[0].serialize(handler));
qb.addCode(" = (");
if (s[1] instanceof Attribute) qb.addCode(s[1].serialize(handler));
if (s[1] instanceof Attribute || s[1] instanceof AttributeAlias) 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 {
@ -443,14 +449,15 @@ export class Handler {
return builder;
},
addPrimaryKey: (handler: Handler, table: Table) => {
let primaAttr = Object.entries(table.dbLangTableAttributes)
.filter(([n, attr]) => !!attr.ops.primaryKey);
const qb = new QueryBuilder();
if(primaAttr.length == 0) return qb;
qb.addCode("ALTER TABLE ");
qb.addCode(table.serialize(handler));
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))
primaAttr.map(([n, attr]) => handler.builders.escapeID(n))
);
qb.addCode(")");
return qb;
@ -550,7 +557,7 @@ export class Handler {
let sql = "";
for (let i = 0; i < qb.list.length; i++) {
const [inject, data] = qb.list[i];
if(inject)sql += handler.builders.escapeLiteral(data);
if (inject) sql += handler.builders.escapeLiteral(data);
else sql += data;
}
return curr.split(", ").join(",").startsWith(sql.split(", ").join(","));
@ -664,7 +671,7 @@ export class Handler {
divide: joinArg("-/"),
not: (handler: Handler, a: allModifierInput[]): QueryBuilder => {
let e = a[0];
if (e instanceof Attribute) return new QueryBuilder([{ data: "not (" + e.toString(handler) + ")" }])
if (e instanceof Attribute || e instanceof AttributeAlias) return new QueryBuilder([{ data: "not (" + e.toString(handler) + ")" }])
if (e instanceof Modifier || e instanceof selectQuery || e instanceof Aggregation) {
const builder = new QueryBuilder();
builder.addCode("not (");
@ -680,14 +687,14 @@ export class Handler {
},
like: (handler: Handler, a: allModifierInput[]): QueryBuilder => {
const builder = new QueryBuilder();
if (a[0] instanceof Attribute) builder.addCode(a[0].toString());
if (a[0] instanceof Attribute || a[0] instanceof AttributeAlias) builder.addCode(a[0].toString());
else if (a[0] instanceof Modifier || a[0] instanceof selectQuery || a[0] instanceof Aggregation) {
builder.append(a[0].serialize(handler));
} else {
builder.addInjection(a[0]);
}
builder.addCode(" LIKE ");
if (a[1] instanceof Attribute) builder.addCode(a[1].toString());
if (a[1] instanceof Attribute || a[1] instanceof AttributeAlias) builder.addCode(a[1].toString());
else if (a[1] instanceof Modifier || a[1] instanceof selectQuery || a[1] instanceof Aggregation) {
builder.append(a[1].serialize(handler));
} else {
@ -700,7 +707,7 @@ export class Handler {
builder.addCode("CONCAT(");
for (let i = 0; i < a.length; i++) {
const e = a[i];
if (e instanceof Attribute) builder.addCode(e.toString());
if (e instanceof Attribute || e instanceof AttributeAlias) builder.addCode(e.toString());
else if (e instanceof Modifier || e instanceof selectQuery || e instanceof Aggregation) {
builder.append(e.serialize(handler));
} else {
@ -798,7 +805,7 @@ function joinArg(type: string) {
const builder = new QueryBuilder();
for (let i = 0; i < a.length; i++) {
const d = a[i];
if (d instanceof Attribute) builder.addCode(d.toString(handler));
if (d instanceof Attribute || d instanceof AttributeAlias) builder.addCode(d.toString(handler));
else if (d instanceof Modifier || d instanceof selectQuery || d instanceof Aggregation) {
builder.addCode("(");
builder.append(d.serialize(handler));

View file

@ -1,3 +1,4 @@
import { AttributeAlias } from "./alias";
import { Attribute, DB, Table } from "./db";
import { BooleanModifier, Modifier } from "./dbStructure";
import { Handler } from "./defaultHandler";
@ -48,6 +49,7 @@ export class QueryBuilder {
this.list.push(...qb.list);
}
appendEnding(qb: QueryBuilder) {
if(qb.isEmpty()) return;
this.append(qb);
this.list.push([false, ";"]);
}
@ -72,8 +74,8 @@ export class selectQuery {
this.whereD = m;
return this;
}
groupByD: Attribute[] = [];
groupBy(a: Attribute[]) {
groupByD: (Attribute | AttributeAlias)[] = [];
groupBy(a: (Attribute | AttributeAlias)[]) {
this.groupByD = a;
return this;
}

View file

@ -1,12 +1,13 @@
import { AttributeAlias, TableAlias } from "./alias";
import { Attribute, Table } from "./db";
import { Aggregation, BooleanModifier, Datatype, Joins, Modifier } from "./dbStructure";
import { QueryBuilder, selectQuery } from "./query";
export type primaryData = string | number | boolean | null;
export type allModifierInput = primaryData | Modifier | selectQuery | Attribute | Aggregation;
export type allModifierInput = primaryData | Modifier | selectQuery | Attribute | AttributeAlias | Aggregation;
export type selectElements = primaryData | Attribute | Aggregation | selectQuery
export type selectFromElements = Table | Joins | null;
export type selectElements = primaryData | Attribute | AttributeAlias | Aggregation | selectQuery
export type selectFromElements = TableAlias | Table | Joins | null;
export type joinElements = Table | Joins;
export type serializeReturn = [string, primaryData[]];