convert parse expression to Sequelize where condition
GitHubWuYi opened this issue · 2 comments
// parsing
import { parse } from "@rsql/parser";
const expression = parse("year>=2003");
// return
{
type: 'COMPARISON',
left: { type: 'SELECTOR', selector: 'year' },
operator: '>=',
right: { type: 'VALUE', value: '2003' }
}
how to convert the expression to Sequelize where condition ?
You will need a mapping function, similar to the emit
function from @rsql/emitter
. Instead of producing a string, you should produce a format supported by sequelize :) Here is a pseudo-code to show you direction:
import { Op } from "sequelize";
import {
EQ,
GT,
AND,
AND_VERBOSE,
OR,
OR_VERBOSE,
isLogicOperator,
ComparisonNode,
ExpressionNode,
isComparisonNode,
isLogicNode,
LogicNode,
SelectorNode,
ValueNode,
getSelector,
getValue
} from "@rsql/ast";
export function mapRsqlToSequelize(node: ExpressionNode): string {
if (isComparisonNode(node)) {
return { where: mapComparisionToSequelize(node) };
} else if (isLogicNode(node)) {
return { where: mapLogicToSequelize(node) };
}
throw new TypeError(`The "expression" has to be a valid "ExpressionNode", ${String(node)} passed.`);
}
function mapComparisonToSequelize(node: ComparisionNode) {
const selector = getSelector(node);
const value = getValue(node);
switch (node.operator) {
case EQ:
return { [selector]: value };
case GT:
return { [selector]: { [Op.gt]: value } };
// ...
}
}
function mapLogicToSequelize(node: LogicNode) {
const children = [mapRsqlToSequelize(node.left), mapRsqlToSequelize(node.right)];
switch (node.operator) {
case AND:
case AND_VERBORSE:
return { [Op.and]: children };
case OR:
case OR_VERBOSE:
return { [Op.or]: children };
}
}
Keep in mind that value is always a string
or string[]
- so you will probably need some schema metadata to cast it to a proper type (for example to number). I guess you can extract it from sequelize models :)
I'm closing it as there is no activity :)