Go语言 动态条件生成器

ocebsuys  于 2022-12-16  发布在  Go
关注(0)|答案(2)|浏览(127)

我的问题很简单,我想动态地创建过滤器来在我的查询输入中使用它,我必须精确地保证tf变量不能改变。
所以我是这么做的:

totalFilter := expression.ConditionBuilder{}
filter := expression.Name("status").Equal(expression.Value("0"))
filter2 := expression.Name("foo").Equal(expression.Value("bar"))
filter3 := expression.Name("yes").Equal(expression.Value("no"))
tf := []expression.ConditionBuilder{filter, filter2, filter3}
for _, v := range tf {
    totalFilter = totalFilter.And(v)
}
expr := expression.NewBuilder().WithFilter(totalFilter)
builder, err := expr.Build()
if err != nil {
    log.Println(err)
    return err
}

但问题是,totalFilter是一个空结构体,因此它的模式变量等于0,然后它会发出警报,因为模式0是unsetCond。
我找到的唯一解决方法是这样做:

for i, v := range tf {
    if i == 0 {
        totalFilter = v
    } else {
        totalFilter.And(v)
    }
}

但我想知道是否有别的解决办法。

s8vozzvw

s8vozzvw1#

你可以在一个自定义可变变量函数中抽象出第一个expression.ConditionBuilder的处理,这个函数至少有一个expression.ConditionBuilder参数:

func And(first expression.ConditionBuilder, rest ...expression.ConditionBuilder) expression.ConditionBuilder {
    result := first
    for _, cb := range rest {
        result = result.And(cb)
    }
    return result
}

然后,在main中:

filter := expression.Name("status").Equal(expression.Value("0"))
filter2 := expression.Name("foo").Equal(expression.Value("bar"))
filter3 := expression.Name("yes").Equal(expression.Value("no"))
totalFilter := And(filter, filter2, filter3)
expr := expression.NewBuilder().WithFilter(totalFilter)
builder, err := expr.Build()
// etc.

请注意,expression包导出了一个类似的函数,也叫And,但它至少需要两个(不仅仅是一个)expression.ConditionBuilder参数。

4ioopgfo

4ioopgfo2#

我的方法是创建一个总是返回true的“伪”条件,很像动态SQL语句中常见的WHERE 1=1 [AND ...]条件。
示例代码将变为:

// dummy condition (1=1) to initialize the filter
totalFilter := expression.Equal(expression.Value(1), expression.Value(1))

filter := expression.Name("status").Equal(expression.Value("0"))
filter2 := expression.Name("foo").Equal(expression.Value("bar"))
filter3 := expression.Name("yes").Equal(expression.Value("no"))
tf := []expression.ConditionBuilder{filter, filter2, filter3}
for _, v := range tf {
    totalFilter = totalFilter.And(v)
}
expr := expression.NewBuilder().WithFilter(totalFilter)
builder, err := expr.Build()
if err != nil {
    log.Println(err)
    return err
}

字符串

请注意,如果您的其他条件由OR运算连接,则需要反转伪条件,以便它始终返回false。

相关问题