Skip to content
This repository has been archived by the owner on Sep 15, 2023. It is now read-only.

Commit

Permalink
egorm support build query
Browse files Browse the repository at this point in the history
  • Loading branch information
askuy committed May 31, 2021
1 parent bbe3515 commit 0e4535b
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 10 deletions.
2 changes: 1 addition & 1 deletion egorm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

## 简介

[gorm](https://github.com/jinzhu/gorm) 进行了轻量封装,并提供了以下功能:
[gorm](https://github.com/go-gorm/gorm) 进行了轻量封装,并提供了以下功能:

- 规范了标准配置格式,提供了统一的 Load().Build() 方法。
- 支持自定义拦截器
Expand Down
135 changes: 135 additions & 0 deletions egorm/buildquery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package egorm

import (
"log"
"strings"
"time"

"github.com/spf13/cast"
"gorm.io/gorm"
)

type (
// Cond 为字段查询结构体
Cond struct {
// Op MySQL中查询条件,如like,=,in
Op string
// Val 查询条件对应的值
Val interface{}
}

// Conds 为Cond类型map,用于定义Where方法参数 map[field.name]interface{}
Conds map[string]interface{}

// Ups 为更新某一条记录时存放的变更数据集合 map[field.name]field.value
Ups = map[string]interface{}
)

// assertCond 断言cond基本类型并返回Cond
// 如果是基本类型,则Cond.Op为"="
// 如果是切片类型,则Cond.Op为"in"。NOTICE: 不支持自定义类型切片,比如 type IDs []int
func assertCond(cond interface{}) Cond {
// 先尝试断言为基本类型
switch v := cond.(type) {
case Cond:
return v
case string:
return Cond{"=", v}
case bool:
return Cond{"=", v}
case float64:
return Cond{"=", v}
case float32:
return Cond{"=", v}
case int:
return Cond{"=", v}
case int64:
return Cond{"=", v}
case int32:
return Cond{"=", v}
case int16:
return Cond{"=", v}
case int8:
return Cond{"=", v}
case uint:
return Cond{"=", v}
case uint64:
return Cond{"=", v}
case uint32:
return Cond{"=", v}
case uint16:
return Cond{"=", v}
case uint8:
return Cond{"=", v}
case time.Duration:
return Cond{"=", v}
}

// 再尝试断言为stringSlice类型
condValueStr, err := cast.ToStringSliceE(cond)
if err == nil {
return Cond{"in", condValueStr}
}

// 再尝试断言为intSlice类型
condValueInt, err := cast.ToIntSliceE(cond)
if err == nil {
return Cond{"in", condValueInt}
}

// 未识别的类型
log.Printf("[assertCond] unrecognized type fail,%+v\n", cond)
return Cond{}
}

// BuildQuery 根据conds构建sql和绑定的参数
func BuildQuery(conds Conds) (sql string, binds []interface{}) {
sql = "1=1"
binds = make([]interface{}, 0, len(conds))
for field, cond := range conds {
condVal := assertCond(cond)

// 说明有表的数据
if strings.Contains(field, ".") {
arr := strings.Split(field, ".")
if len(arr) != 2 {
return
}
field = "`" + arr[0] + "`.`" + arr[1] + "`"
} else {
field = "`" + field + "`"
}

switch strings.ToLower(condVal.Op) {
case "like":
if condVal.Val != "" {
sql += " AND " + field + " like ?"
condVal.Val = "%" + condVal.Val.(string) + "%"
}
case "%like":
if condVal.Val != "" {
sql += " AND " + field + " like ?"
condVal.Val = "%" + condVal.Val.(string)
}
case "like%":
if condVal.Val != "" {
sql += " AND " + field + " like ?"
condVal.Val = condVal.Val.(string) + "%"
}
case "in", "not in":
sql += " AND " + field + condVal.Op + " (?) "
case "between":
sql += " AND " + field + condVal.Op + " ? AND ?"
val := cast.ToStringSlice(condVal.Val)
binds = append(binds, val[0], val[1])
continue
case "exp":
sql += " AND " + field + " ? "
condVal.Val = gorm.Expr(condVal.Val.(string))
default:
sql += " AND " + field + condVal.Op + " ? "
}
binds = append(binds, condVal.Val)
}
return
}
1 change: 0 additions & 1 deletion egorm/dsn/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

func TestMysqlDSNParser_ParseDSN(t *testing.T) {
dsn := "user:password@tcp(localhost:9910)/dbname?charset=utf8&parseTime=True"

cfg, err := DefaultMysqlDSNParser.ParseDSN(dsn)
assert.NoError(t, err)
assert.Equal(t, "user", cfg.User)
Expand Down
3 changes: 2 additions & 1 deletion egorm/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ module github.com/gotomicro/ego-component/egorm
go 1.15

require (
github.com/gotomicro/ego v0.4.1
github.com/gotomicro/ego v0.5.6
github.com/json-iterator/go v1.1.10
github.com/opentracing/opentracing-go v1.1.0
github.com/spf13/cast v1.3.1
github.com/stretchr/testify v1.6.1
gorm.io/driver/mysql v1.0.5
gorm.io/driver/postgres v1.0.8
Expand Down
Loading

0 comments on commit 0e4535b

Please sign in to comment.