1 回答

TA貢獻1830條經驗 獲得超9個贊
我會使用不同的結構,因為:
沒有必要區分
operator
和join
。groups
rules
應該是同一個概念。當它應該有嵌套規則時,只需使用嵌套rules
屬性。當您使用類型
in
orbetween
時,該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 關注
- 102 瀏覽
添加回答
舉報