@opra/sqb
Version:
Opra SQB adapter package
105 lines (104 loc) • 3.62 kB
JavaScript
import '@opra/core';
import { OpraFilter } from '@opra/common';
import * as sqb from '@sqb/builder';
import { vg } from 'valgen';
/**
* Prepare the SQB filter based on the provided filters and options.
*
* @param {SQBAdapter.FilterInput|SQBAdapter.FilterInput[]} filters - The filter(s) to be applied.
*
* @returns {Expression} - The prepared SQB Expression.
*/
export default function prepareFilter(filters) {
const filtersArray = Array.isArray(filters) ? filters : [filters];
if (!filtersArray.length)
return undefined;
const arr = [];
for (const filter of filtersArray) {
if (!filter)
continue;
let ast;
if (typeof filter === 'string')
ast = prepareFilterAst(OpraFilter.parse(filter));
else if (filter instanceof OpraFilter.Expression)
ast = prepareFilterAst(filter);
else
ast = filter;
if (ast)
arr.push(ast);
}
return arr.length > 1 ? sqb.And(...arr) : arr[0];
}
const _isDate = vg.isDate({ trim: 'day' });
const _isDateTime = vg.isDate();
function prepareFilterAst(ast) {
if (!ast)
return;
if (ast instanceof OpraFilter.DateLiteral) {
return _isDate(ast.value, { coerce: true });
}
if (ast instanceof OpraFilter.DateTimeLiteral) {
return _isDateTime(ast.value, { coerce: true });
}
if (ast instanceof OpraFilter.ArrayExpression) {
return ast.items.map(prepareFilterAst);
}
if (ast instanceof OpraFilter.NegativeExpression) {
return sqb.Not(prepareFilterAst(ast.expression));
}
if (ast instanceof OpraFilter.LogicalExpression) {
if (ast.op === 'or')
return sqb.Or(...ast.items.map(prepareFilterAst));
return sqb.And(...ast.items.map(prepareFilterAst));
}
if (ast instanceof OpraFilter.ParenthesizedExpression) {
return prepareFilterAst(ast.expression);
}
if (ast instanceof OpraFilter.ComparisonExpression) {
const left = String(ast.left);
const right = prepareFilterAst(ast.right);
if (ast.prepare) {
const x = ast.prepare({
left,
right,
op: ast.op,
adapter: 'sqb',
});
if (x)
return x;
}
switch (ast.op) {
case '=':
return sqb.Eq(left, right);
case '!=':
return sqb.Ne(left, right);
case '>':
return sqb.Gt(left, right);
case '>=':
return sqb.Gte(left, right);
case '<':
return sqb.Lt(left, right);
case '<=':
return sqb.Lte(left, right);
case 'in':
return sqb.In(left, right);
case '!in':
return sqb.Nin(left, right);
case 'like':
return sqb.Like(left, String(right).replace(/\*/g, '%'));
case 'ilike':
return sqb.Ilike(left, String(right).replace(/\*/g, '%'));
case '!like':
return sqb.NotLike(left, String(right).replace(/\*/g, '%'));
case '!ilike':
return sqb.NotILike(left, String(right).replace(/\*/g, '%'));
default:
throw new Error(`ComparisonExpression operator (${ast.op}) not implemented yet`);
}
}
if (ast instanceof OpraFilter.QualifiedIdentifier ||
ast instanceof OpraFilter.Literal) {
return ast.value;
}
throw new Error(`${ast.kind} is not implemented yet`);
}