@sqb/builder
Version:
Extensible multi-dialect SQL query builder written with TypeScript
82 lines (81 loc) • 2.85 kB
JavaScript
import isPlainObject from 'putil-isplainobject';
import { SerializationType } from '../../enums.js';
import { printArray } from '../../helpers.js';
import { isCompOperator, isLogicalOperator, isNotOperator, isRawStatement, } from '../../typeguards.js';
import { Operator } from '../operator.js';
export const WrapOps = {};
// noinspection RegExpUnnecessaryNonCapturingGroup
const COMPARE_LEFT_PATTERN = /^([\w\\.$]+(?:\[])?) *(.*)$/;
export class LogicalOperator extends Operator {
constructor(...expressions) {
super();
this._items = [];
this.add(...expressions);
}
get _type() {
return SerializationType.LOGICAL_EXPRESSION;
}
/**
* Adds operator(s) to item list
*/
add(...expressions) {
for (const item of expressions) {
if (!item)
continue;
if (isLogicalOperator(item)) {
this._items.push(item);
}
else if (isRawStatement(item) ||
isCompOperator(item) ||
isNotOperator(item)) {
this._items.push(item);
}
else if (isPlainObject(item)) {
this.add(...this._wrapObject(item));
}
else
throw new TypeError('Operator or Raw type required');
}
return this;
}
_serialize(ctx) {
const arr = [];
for (const t of this._items) {
const s = ctx.anyToSQL(t);
/* istanbul ignore else */
if (s)
arr.push(s);
}
return ctx.serialize(SerializationType.LOGICAL_EXPRESSION, arr, () => {
const s = printArray(arr, ' ' + String(this._operatorType));
return s.indexOf('\n') > 0 ? s.replace('\n', '\n\t') + '\b' : s;
});
}
// noinspection JSMethodCanBeStatic
_wrapObject(obj) {
const result = [];
for (const n of Object.getOwnPropertyNames(obj)) {
let op;
const v = obj[n];
if (['and', 'or'].includes(n.toLowerCase())) {
op = WrapOps[n.toLowerCase()];
if (!op)
throw new Error(`Unknown operator "${n}"`);
result.push(Array.isArray(v) ? op(...v) : op(v));
continue;
}
if (['exists', '!exists'].includes(n))
result.push(WrapOps[n](obj[n]));
else {
const m = n.match(COMPARE_LEFT_PATTERN);
if (!m)
throw new TypeError(`"${n}" is not a valid expression definition`);
op = WrapOps[m[2] || 'eq'];
if (!op)
throw new Error(`Unknown operator "${m[2]}"`);
result.push(op(m[1], obj[n]));
}
}
return result;
}
}