Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

有 _or 前缀的即认为是 or 语句,这样可以支持多个 or 条件 #130

Merged
merged 3 commits into from
Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,28 @@ result, err = AggregateQuery(ctx, db, "tableName", where, AggregateAvg("score"))
averageScore := result.Float64()
```

multi `or` condition can use multi `_or` prefix string mark
``` go
where := map[string]interface{}{
// location
"_or_location": []map[string]interface{}{{
"subway": "beijing_15",
}, {
"district": "Chaoyang",
}},
// functions
"_or_functions": []map[string]interface{}{{
"has_gas": true,
}, {
"has_lift": true,
}}}

// query = (((subway=?) OR (district=?)) AND ((has_gas=?) OR (has_lift=?)))
// args = ["beijing_15", "Chaoyang", true, true]
```

If you want to clear the value '0' in the where map, you can use builder.OmitEmpty

``` go
where := map[string]interface{}{
"score": 0,
Expand Down
2 changes: 1 addition & 1 deletion builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func getWhereConditions(where map[string]interface{}, ignoreKeys map[string]stru
if _, ok := ignoreKeys[key]; ok {
continue
}
if key == "_or" {
if strings.HasPrefix(key, "_or") {
var (
orWheres []map[string]interface{}
orWhereComparable []Comparable
Expand Down
59 changes: 59 additions & 0 deletions builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,65 @@ func Test_BuildSelect(t *testing.T) {
}
}

func Test_BuildSelectMutliOr(t *testing.T) {
type inStruct struct {
table string
where map[string]interface{}
fields []string
}
type outStruct struct {
cond string
vals []interface{}
err error
}
var data = []struct {
in inStruct
out outStruct
}{
{
in: inStruct{
table: "tb",
where: map[string]interface{}{
"a": 1,
"_or": []map[string]interface{}{
{
"b": 2,
"c": 3,
},
{
"d": 4,
"e": 5,
},
},
"_or2": []map[string]interface{}{
{
"b2": 22,
"c2": 33,
},
{
"d2": 44,
"e2": 55,
},
},
},
fields: []string{"id", "name", "age"},
},
out: outStruct{
cond: "SELECT id,name,age FROM tb WHERE (((b=? AND c=?) OR (d=? AND e=?)) AND ((b2=? AND c2=?) OR (d2=? AND e2=?)) AND a=?)",
vals: []interface{}{2, 3, 4, 5, 22, 33, 44, 55, 1},
err: nil,
},
},
}
ass := assert.New(t)
for _, tc := range data {
cond, vals, err := BuildSelect(tc.in.table, tc.in.where, tc.in.fields)
ass.Equal(tc.out.err, err)
ass.Equal(tc.out.cond, cond)
ass.Equal(tc.out.vals, vals)
}
}

func BenchmarkBuildSelect_Sequelization(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, err := BuildSelect("tb", map[string]interface{}{
Expand Down
21 changes: 21 additions & 0 deletions translation/zhcn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,27 @@ where := map[string]interface{}{
}
```

如果你有多个 `or` 条件可以是用 `_or` 前缀开头的字符串来标识 `or` 语句
``` go
where := map[string]interface{}{
// 位置条件(15号线或朝阳区)
"_or_location": []map[string]interface{}{{
"subway": "beijing_15",
}, {
"district": "Chaoyang",
}},
// 类型(有煤气或有电梯)
"_or_functions": []map[string]interface{}{{
"has_gas": true,
}, {
"has_lift": true,
}},
}

// query = (((subway=?) OR (district=?)) AND ((has_gas=?) OR (has_lift=?)))
// args = ["beijing_15", "Chaoyang", true, true]
```

如果你想清除where map中的零值可以使用 builder.OmitEmpty
``` go
where := map[string]interface{}{
Expand Down