@lordfokas/magic-orm
Version:
A class-based ORM in TypeScript. Unorthodox and extremely opinionated, made to fit my specific use cases.
104 lines • 3.27 kB
JavaScript
export class QueryBuilder {
#conds = [];
#parms = [];
#fields = [];
#entity;
constructor(entity, fields) {
this.#entity = entity;
this.#fields.push(...fields);
}
where(cond) {
this.#conds.push(cond);
return this;
}
param(...params) {
this.#parms.push(...params);
return this;
}
filter(filters, entity) {
filters.map(f => {
if (Array.isArray(f.in)) {
this.where(entity.COL(f.col) + ' IN ( ' + f.in.map(_ => '?').join(', ') + ' )');
this.param(...f.in);
}
else {
this.where(entity.COL(f.col) + ' ' + (f.op || '=') + ' ' + (f.val || '?'));
if (f.var !== undefined)
this.param(f.var);
}
});
return this;
}
injectConditions(sql) {
if (this.#conds.length > 0)
sql.push('WHERE ' + this.#conds.join('\n AND '));
}
fields() { return this.#fields; }
params() { return this.#parms; }
conds() { return this.#conds; }
table() { return this.#entity.TABLE(); }
entity() { return this.#entity; }
}
export class SelectBuilder extends QueryBuilder {
#chains = [];
#joins = [];
#order = [];
constructor(entity, fields) {
super(entity, [fields]);
}
order(order) {
this.#order.push(order);
return this;
}
join(master, reverse = false) {
this.fields().push(...master.fields());
const self = this.entity();
const other = master.entity();
const slavefield = (reverse ? self : other).$config.linkname;
const masterlink = (reverse ? other : self).COL(`uuid_${slavefield}`);
const masteruuid = (reverse ? self : other).COL('uuid');
this.#joins.push(`JOIN ${master.table()} ON ${masterlink} = ${masteruuid}`);
this.#joins.push(...master.#joins);
this.conds().push(...master.conds());
this.params().push(...master.params());
this.#order.push(...master.#order);
this.#chains.push({
parent: this.entity(),
child: master.entity()
}, ...master.#chains);
return this;
}
count() {
const f = this.fields();
f.length = 0;
f.push('COUNT(*)');
return this;
}
chains() {
return this.#chains;
}
async execute(db) {
const sql = [];
sql.push('SELECT ' + this.fields().join(',\n '));
sql.push('FROM ' + this.table());
sql.push(...this.#joins);
this.injectConditions(sql);
if (this.#order.length > 0)
sql.push('ORDER BY ' + this.#order.join(', '));
return await db.execute(sql, this.params());
}
}
export class UpdateBuilder extends QueryBuilder {
constructor(entity, fields) {
super(entity.constructor, fields);
this.param(...fields.map(f => entity[f]));
}
async execute(db) {
const sql = [];
sql.push('UPDATE ' + this.table());
sql.push('SET ' + this.fields().map(f => f + ' = ?').join(', '));
this.injectConditions(sql);
return await db.execute(sql, this.params());
}
}
//# sourceMappingURL=QueryBuilder.js.map