我正在处理QueryBuilder JavaScript库(https://github.com/mistic100/jQuery-QueryBuilder/issues/59)的问题。
目标是从SQL语句填充构建器。为此,我使用https://github.com/forward/sql-parser将WHERE子句转换为AST。
现在我的问题是我需要将这个AST(这是一种二叉树)转换为QueryBuilder的内部格式(我不知道技术名称)。但我很蠢,我找不到一个有效的算法。
所以我在这里找到一个擅长这个的人!我只需要主算法来转换数据结构,转换值和运算符格式不会有问题。
注意:
输入SQL是(测试用例):
name LIKE "Mistic%"
AND price BETWEEN 100 AND 200
AND (
category IN(1,2)
OR parent <= 0
)
AND id is not null
这是SQL Parser的输出:
{
left: {
left: {
left: {
left: {
value: 'name'
},
operation: 'LIKE',
right: {
value: 'Mistic%'
},
},
operation: 'AND',
right: {
left: {
value: 'price'
},
operation: 'BETWEEN',
right: {
value: [
{
value: 100
},
{
value: 200
}
]
}
}
},
operation: 'AND',
right: {
left: {
left: {
value: 'category'
},
operation: 'IN',
right: {
value: [
{
value: 1
},
{
value: 2
}
]
}
},
operation: 'OR',
right: {
left: {
value: 'parent'
},
operation: '<=',
right: {
value: 0
}
}
}
},
operation: 'AND',
right: {
left: {
value: 'id'
},
operation: 'is not',
right: {
value: null
}
}
}
这是我需要的数据结构:
{
condition: 'AND',
rules: [
{
id: 'name',
operator: 'like',
value: 'Mistic%'
},
{
id: 'price',
operator: 'between',
value: [100, 200]
},
{
condition: 'OR',
rules: [
{
id: 'category',
operator: 'in',
value: [1, 2]
},
{
id: 'parent',
operator: 'less_or_equal',
value: 0
}
]
},
{
id: 'id',
operator: 'not_null',
value: null
}
]
}
答案 0 :(得分:1)
我想我得到了它,这是伪代码:
var out = {
condition: null
rules: []
}
var curr = out
function flatten(node, level)
if node.operation = 'AND' or node.operation = 'OR' then
if level > 0 and curr.condition != node.operation then
curr.rules.push({
condition: null
rules: []
})
curr = curr.rules.end()
end if
curr.condition = node.operation
level++;
var next = curr
flatten(node.right, level)
curr = next
flatten(node.left, level)
else
curr.rules.push({
id: node.left.value
operator: node.operation
value: node.right.value
})
end if
end function
flatten(parsed, 0)
当操作符在AND和OR之间切换时,它是一个自调用递归函数创建子组,而在展平左侧和右侧部分时,在右子组中使用一点点技巧。