重构: Condition/Engine 迁移到 db-v2 的表达式树,替换掉旧的 db.Raw 拼字符串

ToSql 之前是手工拼接 SQL 字符串(string 类型的 conditions、手动加括号、
手动拼 AND/OR),改成用 exp.NewExpressionList 构造表达式树,跟 db-v2
其余部分统一走"先建表达式树、由方言渲染成 SQL"这条路,不再自己维护一份
字符串拼接逻辑。ConditionType/ConditionOperator 相应改成 exp.ExpressionListType/
exp.BooleanOperation 的类型别名。

TokenValue 从 condition_expr.go 里独立成 token_value.go,从
GetParam(k string) req.GlobalParams 改成 GetParam(k string) valuex.Accessor
(配合 reflux/valuex),跟其它 "-v2" 项目的属性访问方式统一。engine 包
配合适配(sqlite3 用 db/engine 的新连接管理,SelectDataset 替代
db.Connection),删掉了不再需要的 EngineParam(老 GlobalParams 包装,
新 TokenValue 已经不需要这层)。

已知问题:engine.go 在没有外部传入 GlobalParams 时用 nil user 构造兜底
值,跟 NewTokenValue 现在强制要求非 nil user 冲突,TestEngine 会 panic
——这个先不修,等后面调整 Engine.Execute 让调用方能传 user 时一起解决。
This commit is contained in:
2026-08-21 08:55:21 +08:00
parent 50e1b3630e
commit 5b39565a36
9 changed files with 313 additions and 232 deletions
+35 -20
View File
@@ -4,6 +4,7 @@ import (
"testing"
"git.fsdpf.net/go/condition"
"git.fsdpf.net/go/reflux"
"git.fsdpf.net/go/req"
)
@@ -18,26 +19,40 @@ type TestTable struct {
}
func TestEngine(t *testing.T) {
engine := Engine[any]{
engine := Engine{
code: "TestTable",
g: req.NewGlobalParam(`{"age": 30}`, nil),
g: req.NewGlobalParams(`{"age": 30}`, nil),
}
cond1 := condition.New(condition.Describe("条件1"))
cond1.SetExpr(condition.NewExpr("TestTable", "age", condition.Token("age", condition.PARAM)))
engine.Case(cond1, func(data any, g req.GlobalParams) error {
t.Log("cond1", data)
engine.Case(cond1, func(data reflux.R, g req.UserAccessor) error {
t.Log("cond1", data.Any())
return nil
})
engine.Default(func(data any, g req.GlobalParams) error {
t.Log("default", data)
engine.Default(func(data reflux.R, g req.UserAccessor) error {
t.Log("default", data.Any())
return nil
})
engine.Execute(map[string]any{
testData := map[string]any{
"null": nil,
"age": 30,
"name": "张三",
"map": map[string]any{
"field": 1,
},
"bool": false,
"struct": struct{ Name string }{"李四"},
"struct-ptr": &struct{ Name string }{"张三"},
"array": []any{1, "a", false},
}
engine.Execute(testData)
testData2 := map[string]any{
"null": nil,
"age": 30,
"name": "张三",
@@ -47,15 +62,14 @@ func TestEngine(t *testing.T) {
"bool": false,
"struct": &struct{ Name string }{"李四"},
"array": []any{1, "a", false},
})
t.Log("execute error", engine.Execute(TestTable{nil, 30, "张三", map[string]any{"field": 1}, false, &struct{ Name string }{"李四"}, []any{1, "a", false}}))
}
t.Log("execute error", engine.Execute(testData2))
}
func TestRelationEngine(t *testing.T) {
engine := Engine[any]{
engine := Engine{
code: "TestTable",
g: req.NewGlobalParam(`{"age": 30}`, nil),
g: req.NewGlobalParams(`{"age": 30}`, nil),
opts: engineOptions{
debug: false,
relations: []string{"TestTableA"},
@@ -65,8 +79,8 @@ func TestRelationEngine(t *testing.T) {
cond1 := condition.New(condition.Describe("条件1")).
SetExpr(condition.NewExpr("TestTable", "age", condition.Token("age", condition.PARAM)))
engine.Case(cond1, func(data any, g req.GlobalParams) error {
t.Log("cond1", data)
engine.Case(cond1, func(data reflux.R, g req.UserAccessor) error {
t.Log("cond1", data.Any())
return nil
})
@@ -74,17 +88,17 @@ func TestRelationEngine(t *testing.T) {
SetExpr(condition.NewExpr("TestTableA", "age", condition.Token("age", condition.PARAM))).
SetExpr(condition.NewExpr("TestTable", "age", condition.Token("age", condition.PARAM)))
engine.Case(cond2, func(data any, g req.GlobalParams) error {
t.Log("cond2", data)
engine.Case(cond2, func(data reflux.R, g req.UserAccessor) error {
t.Log("cond2", data.Any())
return nil
})
engine.Default(func(data any, g req.GlobalParams) error {
t.Log("default", data)
engine.Default(func(data reflux.R, g req.UserAccessor) error {
t.Log("default", data.Any())
return nil
})
engine.Execute(map[string]any{
testData := map[string]any{
"null": nil,
"age": 31,
"name": "张三",
@@ -100,7 +114,8 @@ func TestRelationEngine(t *testing.T) {
"age": 22,
},
},
})
}
engine.Execute(testData)
// t.Log("execute error", engine.Execute(TestTable{nil, 30, "张三", map[string]any{"field": 1}, false, &struct{ Name string }{"李四"}, []any{1, "a", false}}))
}