1 回答
TA贡献1830条经验 获得超9个赞
我会使用不同的结构,因为:
没有必要区分
operator和join。groupsrules应该是同一个概念。当它应该有嵌套规则时,只需使用嵌套rules属性。当您使用类型
inorbetween时,该value属性实际上应该是一个数组。解析器应该注入逗号和其他 SQL 语法。不要将逗号放在单个字符串中(尽管您没有这样的示例)避免解析
not_between和not_is_null分开;between它们与and是一样的is_null,但NOT应用了 a 。这可以更动态地完成。
这是您的示例的建议结构:
{
"type": "AND",
"rules": [{
"id": 100,
"column": "dd_Tttp",
"type": "equal",
"value": true
}, {
"type": "AND",
"rules": [{
"id": 200,
"column": "dd_tering",
"type": "equal",
"value": true
}, {
"id": 201,
"column": "dd_Size",
"type": "in",
"value": ["Standard"] // You should use arrays for type="in"
}, {
"id": 202,
"column": "dd_Lotpth",
"type": "equal",
"value": "12"
}, {
"type": "AND",
"rules": [{
"id": 300,
"column": "dd_cat",
"type": "equal",
"value": "34"
}, {
"id": 301,
"column": "dd_Cot",
"type": "in",
"value": ["Coftlassic"] // You should use arrays for type="in"
}, {
"id": 302,
"column": "dd_dse",
"type": "equal",
"value": "2020-01-01"
}, {
"id": 303,
"column": "dd_turflaid",
"type": "equal",
"value": true
}]
}]
}, {
"type": "AND",
"rules": [{
"id": 100,
"column": "dd_get",
"type": "equal",
"value": true
}, {
"id": 101,
"column": "dd_ccc",
"type": "in",
"value": ["Standard"] // // You should use arrays for type="in"
}]
}]
};
这是一个从中生成 SQL 的片段:
const op = { equal: " = ", not_equal: " <> ", less: " < ", less_or_equal: " <= ",
greater: " > ", greater_or_equal: " >= " };
function toSql(rule) {
// recursive case:
if (rule.rules) return "(" + rule.rules.map(toSql).join("\n" + rule.type + " ") + ")";
// Base case (it is an atomic rule):
if (op[rule.type]) return rule.column + op[rule.type] + JSON.stringify(rule.value);
// Deal with "not": that is just a negation of the opposite
let type = rule.type.replace(/^not_/, "");
let sql = rule.column + (
type === "in" ? " IN (" + JSON.stringify(rule.value).slice(1,-1) + ")"
: type === "between" ? " BETWEEN " + rule.value.map(item => JSON.stringify(item)).join(" AND ")
: type === "is_null" ? " IS NULL"
: "<UNKNOWN TYPE:" + type + ">"
);
return type === rule.type ? sql : "NOT (" + sql + ")";
}
let rule = {"type": "AND","rules": [{"id": 100,"column": "dd_Tttp","type": "equal","value": true}, {"type": "AND","rules": [{"id": 200,"column": "dd_tering","type": "equal","value": true}, {"id": 201,"column": "dd_Size","type": "in","value": ["Standard"]}, {"id": 202,"column": "dd_Lotpth","type": "equal","value": "12"}, {"type": "AND","rules": [{"id": 300,"column": "dd_cat","type": "equal","value": "34"}, {"id": 301,"column": "dd_Cot","type": "in","value": ["Coftlassic"]}, {"id": 302,"column": "dd_dse","type": "equal","value": "2020-01-01"}, {"id": 303,"column": "dd_turflaid","type": "equal","value": true}]}]}, {"type": "AND","rules": [{"id": 100,"column": "dd_get","type": "equal","value": true}, {"id": 101,"column": "dd_ccc","type": "in","value": ["Standard"]}]}]};
console.log(toSql(rule));
禁用规则
在评论中,您添加了一个您希望禁用某些规则的要求。在这种情况下,首先按新属性过滤规则disabled。
这是与该更改相同的代码段,其中最后两个(嵌套)规则被禁用:
const op = { equal: " = ", not_equal: " <> ", less: " < ", less_or_equal: " <= ",
greater: " > ", greater_or_equal: " >= " };
function toSql(rule) {
// recursive case:
if (rule.rules) {
// Filter out recursive return values that are empty (using Boolean):
let sql = rule.rules.map(toSql).filter(Boolean).join("\n" + rule.type + " ");
// return that SQL in parentheses, except when it is empty
return sql ? "(" + sql + ")" : "";
}
// Base case (it is an atomic rule):
if (rule.disabled) return ""; // Return empty string when disabled
if (op[rule.type]) return rule.column + op[rule.type] + JSON.stringify(rule.value);
// Deal with "not": that is just a negation of the opposite
let type = rule.type.replace(/^not_/, "");
let sql = rule.column + (
type === "in" ? " IN (" + JSON.stringify(rule.value).slice(1,-1) + ")"
: type === "between" ? " BETWEEN " + rule.value.map(item => JSON.stringify(item)).join(" AND ")
: type === "is_null" ? " IS NULL"
: "<UNKNOWN TYPE:" + type + ">"
);
return type === rule.type ? sql : "NOT (" + sql + ")";
}
let rule = {"type": "AND","rules": [{"id": 100,"column": "dd_Tttp","type": "equal","value": true}, {"type": "AND","rules": [{"id": 200,"column": "dd_tering","type": "equal","value": true}, {"id": 201,"column": "dd_Size","type": "in","value": ["Standard"]}, {"id": 202,"column": "dd_Lotpth","type": "equal","value": "12"}, {"type": "AND","rules": [{"id": 300,"column": "dd_cat","type": "equal","value": "34"}, {"id": 301,"column": "dd_Cot","type": "in","value": ["Coftlassic"]}, {"id": 302,"column": "dd_dse","type": "equal","value": "2020-01-01"}, {"id": 303,"column": "dd_turflaid","type": "equal","value": true}]}]}, {"type": "AND","rules": [{"id": 100,disabled:true,"column": "dd_get","type": "equal","value": true}, {"id": 101,disabled:true,"column": "dd_ccc","type": "in","value": ["Standard"]}]}]};
console.log(toSql(rule));
- 1 回答
- 0 关注
- 133 浏览
添加回答
举报
