UNPKG

@react-awesome-query-builder/sql

Version:
305 lines (304 loc) 11.8 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* eslint-disable @typescript-eslint/no-redundant-type-constituents, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */ import { SqlPrimitiveTypes } from "./conv"; export var processAst = function processAst(sqlAst, meta) { var _select$columns; if (sqlAst.type !== "select") { meta.errors.push("Expected SELECT, but got ".concat(sqlAst.type)); } var select = sqlAst; var pWhere = processLogic(select.where, meta); var selectExpr = ((_select$columns = select.columns) !== null && _select$columns !== void 0 ? _select$columns : []).find(function (c) { return c.type === "expr"; }); var pSelectExpr = processLogic(selectExpr === null || selectExpr === void 0 ? void 0 : selectExpr.expr, meta); var hasLogic = select.where || (selectExpr === null || selectExpr === void 0 ? void 0 : selectExpr.expr); if (!hasLogic) { meta.errors.push("No logic found in WHERE/SELECT"); } return { where: pWhere, select: pSelectExpr }; }; var processLogic = function processLogic(logic, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (!logic) { return undefined; } var ret; if (logic.type === "function") { ret = processFunc(logic, meta, not); } else if (logic.type === "binary_expr") { if (["AND", "OR"].includes(logic.operator)) { ret = processConj(logic, meta, not); } else { ret = processBinaryOp(logic, meta, not); } } else if (logic.type === "unary_expr") { if (logic.operator === "NOT") { var subFilter = logic.expr; ret = processLogic(subFilter, meta, !not); if (ret) { ret.parentheses = true; } } else { meta.errors.push("Unexpected unary operator ".concat(logic.operator)); } } else if (logic.type === "expr_list") { ret = processExprList(logic, meta, not); } else if (logic.type === "case") { ret = processCase(logic, meta, not); } else if (logic.type === "column_ref") { ret = processField(logic, meta, not); } else if (logic.type === "interval") { ret = processInterval(logic, meta, not); } else if (logic.value !== undefined) { ret = processValue(logic, meta, not); } else { // todo: aggr_func (like COUNT) meta.errors.push("Unexpected logic type ".concat(logic.type)); } return ret; }; var processConj = function processConj(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var parentheses = expr.parentheses; var conj = expr.operator; // flatize OR/AND var childrenChain = [processLogic(expr.left, meta), processLogic(expr.right, meta)].filter(function (c) { return !!c; }); var children = childrenChain.reduce(function (acc, child) { var _child$children; var canFlatize = (child === null || child === void 0 ? void 0 : child.conj) === conj && !child.parentheses && !child.not; var flat = canFlatize ? (_child$children = child.children) !== null && _child$children !== void 0 ? _child$children : [] : [child]; return [].concat(_toConsumableArray(acc), _toConsumableArray(flat)); }, []); return { parentheses: parentheses, not: not, conj: conj, children: children }; }; var processCase = function processCase(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var parentheses = expr.parentheses; var children = expr.args.map(function (arg) { if (!["when", "else"].includes(arg.type)) { meta.errors.push("Unexpected type ".concat(arg.type, " inside CASE")); } return { cond: arg.type === "when" ? processLogic(arg.cond, meta) : undefined, result: processLogic(arg.result, meta) }; }).filter(function (a) { return !!a; }); return { parentheses: parentheses, children: children, _type: "case", not: not }; }; var processBinaryOp = function processBinaryOp(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var parentheses = expr.parentheses; var operator = expr.operator; var children = [processLogic(expr.left, meta), processLogic(expr.right, meta)].filter(function (c) { return !!c; }); if (operator === "BETWEEN" || operator === "NOT BETWEEN") { var _children$1$children; // flatize BETWEEN children = [children[0]].concat(_toConsumableArray((_children$1$children = children[1].children) !== null && _children$1$children !== void 0 ? _children$1$children : [])).filter(function (c) { return !!c; }); } return { parentheses: parentheses, not: not, children: children, operator: operator }; }; var getExprValue = function getExprValue(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var value = expr.value; if (expr.type === "boolean" && not) { value = !value; } // todo: date literals? return value; }; var getExprStringValue = function getExprStringValue(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var v = getExprValue(expr, meta, not); return String(v); }; var processExprList = function processExprList(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var children = expr.value.map(function (ev) { return processLogic(ev, meta, false); }).filter(function (ev) { return !!ev; }); var valueTypes = children.map(function (ch) { return ch.valueType; }).filter(function (ev) { return !!ev; }); var uniqValueTypes = Array.from(new Set(valueTypes)); var oneValueType = valueTypes.length === children.length && uniqValueTypes.length === 1 ? uniqValueTypes[0] : undefined; var values; if (oneValueType && SqlPrimitiveTypes[oneValueType]) { // it's list of primitive values // eslint-disable-next-line @typescript-eslint/no-unsafe-return values = children.map(function (ch) { return ch.value; }); } return { children: children, not: not, _type: "expr_list", oneValueType: oneValueType, values: values }; }; var processInterval = function processInterval(expr, meta) { var _processValue; var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; return _objectSpread(_objectSpread({ _type: "interval" }, (_processValue = processValue(expr.expr, meta)) !== null && _processValue !== void 0 ? _processValue : {}), {}, { unit: expr.unit }); }; var processValue = function processValue(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var valueType = expr.type; var value = getExprValue(expr, meta, not); return { valueType: valueType, value: value }; }; var processField = function processField(expr, meta) { var _expr$table; var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (expr.type === "expr") { return undefined; } var parentheses = expr.parentheses; var field = typeof expr.column === "string" ? expr.column : getExprStringValue(expr.column.expr, meta, not); var table = (_expr$table = expr.table) !== null && _expr$table !== void 0 ? _expr$table : undefined; if (field === "") { // fix for empty string return { valueType: "single_quote_string", value: "" }; } else { return { parentheses: parentheses, field: field, table: table }; } }; var flatizeTernary = function flatizeTernary(children, meta) { var flat = []; function _processTernaryChildren(tern) { var _tern = _slicedToArray(tern, 3), cond = _tern[0], if_val = _tern[1], else_val = _tern[2]; if (if_val.func === "IF") { meta.errors.push("Unexpected IF inside IF"); } flat.push([cond, if_val]); if ((else_val === null || else_val === void 0 ? void 0 : else_val.func) === "IF") { _processTernaryChildren(else_val === null || else_val === void 0 ? void 0 : else_val.children); } else { flat.push([undefined, else_val]); } } _processTernaryChildren(children); return flat; }; var processFunc = function processFunc(expr, meta) { var not = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var nameType = expr.name.name[0].type; var firstName = expr.name.name[0].value; var getArgs = function getArgs(useNot) { if (expr.args) { if (expr.args.type === "expr_list") { return expr.args.value.map(function (arg) { return processLogic(arg, meta, useNot ? not : undefined); }).filter(function (a) { return !!a; }); } else { meta.errors.push("Unexpected args type for func (".concat(JSON.stringify(expr.name.name), "): ").concat(JSON.stringify(expr.args.type))); } } return []; }; var ret; if (nameType === "default" && firstName === "NOT") { var _expr$args; if (((_expr$args = expr.args) === null || _expr$args === void 0 ? void 0 : _expr$args.value.length) === 1) { var args = getArgs(false); ret = args[0]; // ret.parentheses = true; ret.not = !ret.not; if (not) { ret.not = !ret.not; } } else { var _expr$args2; meta.errors.push("Unexpected args for func NOT: ".concat(JSON.stringify((_expr$args2 = expr.args) === null || _expr$args2 === void 0 ? void 0 : _expr$args2.value))); } } else if (nameType === "default" && firstName === "IFNULL") { var _args = getArgs(true); // const defaultValue = args[1].value; ret = _args[0]; } else if (nameType === "default") { var flatizeArgs = firstName === "IF"; var _args2 = getArgs(false); ret = { func: firstName, children: _args2, not: not }; if (flatizeArgs) { ret.ternaryChildren = flatizeTernary(_args2, meta); } return ret; } else { meta.errors.push("Unexpected function name ".concat(JSON.stringify(expr.name.name))); } return ret; }; export var getLogicDescr = function getLogicDescr(logic) { if ((logic === null || logic === void 0 ? void 0 : logic._type) === "case") { // const cases = logic.children as {cond: OutLogic, result: OutLogic}[]; return "CASE"; } else if ((logic === null || logic === void 0 ? void 0 : logic._type) === "interval") { return "INTERVAL ".concat(JSON.stringify(logic.value), " ").concat(logic.unit); } else if (logic !== null && logic !== void 0 && logic.func) { return "".concat(logic.func, "()"); } else if (logic !== null && logic !== void 0 && logic.operator) { return "operator ".concat(logic.operator); } else if ((logic === null || logic === void 0 ? void 0 : logic._type) === "expr_list") { return JSON.stringify(logic.values); } return JSON.stringify(logic); };