Skip to content

Commit

Permalink
有 _or 前缀的即认为是 or 语句,这样可以支持多个 or 条件 (#130)
Browse files Browse the repository at this point in the history
* 有 _or 前缀的即认为是 or 语句,这样可以支持多个 or 条件

* 补充单元测试 Test_BuildSelectMutliOr

* 补充文档:多个 or 语句如何使用

Co-authored-by: 张弘年 <[email protected]>
  • Loading branch information
zhanghongnian and 张弘年 authored Jul 22, 2022
1 parent bf9e04a commit becd38a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 1 deletion.
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

3 comments on commit becd38a

@vv5d
Copy link

@vv5d vv5d commented on becd38a Aug 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: release a new tag?..... @zhanghongnian

@caibirdme
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vv5d the new release will come this friday

@dongzeXD
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hero!

Please sign in to comment.