UNPKG

@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
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