UNPKG

@opra/sqb

Version:

Opra SQB adapter package

105 lines (104 loc) 3.62 kB
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`); }