add support for like statement in map key for Where function, improve error format for gdb

This commit is contained in:
John
2019-10-13 00:37:25 +08:00
parent 76a9f4ca14
commit 142484d89c
5 changed files with 25 additions and 14 deletions

View File

@ -687,12 +687,15 @@ func (bs *dbBase) formatWhere(where interface{}, args []interface{}) (newWhere s
if value == nil {
buffer.WriteString(key)
} else {
// 支持key带操作符号
// 支持key带操作符号注意like也算是操作符号
if gstr.Pos(key, "?") == -1 {
if gstr.Pos(key, "<") == -1 && gstr.Pos(key, ">") == -1 && gstr.Pos(key, "=") == -1 {
if gstr.Pos(key, "<") == -1 &&
gstr.Pos(key, ">") == -1 &&
gstr.Pos(key, "=") == -1 &&
gstr.PosI(key, " like") == -1 {
buffer.WriteString(key + "=?")
} else {
buffer.WriteString(key + "?")
buffer.WriteString(key + " ?")
}
} else {
buffer.WriteString(key)

View File

@ -146,12 +146,7 @@ func convertParam(value interface{}) interface{} {
// 格式化错误信息
func formatError(err error, query string, args ...interface{}) error {
if err != nil && err != sql.ErrNoRows {
errStr := fmt.Sprintf("DB ERROR: %s\n", err.Error())
errStr += fmt.Sprintf("DB QUERY: %s\n", query)
if len(args) > 0 {
errStr += fmt.Sprintf("DB PARAM: %v\n", args)
}
err = errors.New(errStr)
return errors.New(fmt.Sprintf("%s, %s\n", err.Error(), bindArgsToQuery(query, args)))
}
return err
}
@ -209,6 +204,9 @@ func bindArgsToQuery(query string, args []interface{}) string {
newQuery, _ := gregex.ReplaceStringFunc(`\?`, query, func(s string) string {
index++
if len(args) > index {
if args[index] == nil {
return "null"
}
rv := reflect.ValueOf(args[index])
kind := rv.Kind()
if kind == reflect.Ptr {
@ -217,7 +215,7 @@ func bindArgsToQuery(query string, args []interface{}) string {
}
switch kind {
case reflect.String, reflect.Map, reflect.Slice, reflect.Array:
return "'" + gstr.QuoteMeta(gconv.String(args[index]), "'") + "'"
return `'` + gstr.QuoteMeta(gconv.String(args[index]), `'`) + `'`
}
return gconv.String(args[index])
}

View File

@ -282,8 +282,8 @@ func (md *Model) Batch(batch int) *Model {
// 查询缓存/清除缓存操作,需要注意的是,事务查询不支持缓存。
// 当time < 0时表示清除缓存 time=0时表示不过期, time > 0时表示过期时间time过期时间单位
// name表示自定义的缓存名称便于业务层精准定位缓存项(如果业务层需要手动清理时,必须指定缓存名称)
// 例如:查询缓存时设置名称,清理缓存时可以给定清理的缓存名称进行精准清理。
// name表示自定义的缓存名称(注意不要出现重复),便于业务层精准定位缓存项(如果业务层需要手动清理时,必须指定缓存名称)
// 例如:查询缓存时设置名称,在特定的业务逻辑中清理缓存时可以给定缓存名称进行精准清理。
func (md *Model) Cache(time int, name ...string) *Model {
model := md.getModel()
model.cacheTime = time

View File

@ -25,7 +25,7 @@ func (r Record) Xml(rootTag ...string) string {
return string(content)
}
// 将Record转换为Map其中最主要的区别是里面的键值被强制转换为string类型方便json处理
// 将Record转换为Map类型
func (r Record) Map() Map {
m := make(map[string]interface{})
for k, v := range r {
@ -34,7 +34,7 @@ func (r Record) Map() Map {
return m
}
// 将Record转换为gmap.StrAnyMap类型
// 将Record转换为常用的gmap.StrAnyMap类型
func (r Record) GMap() *gmap.StrAnyMap {
return gmap.NewStrAnyMapFrom(r.Map())
}

View File

@ -656,6 +656,16 @@ func Test_Model_Where(t *testing.T) {
gtest.AssertGT(len(result), 0)
gtest.Assert(result["id"].Int(), 3)
})
// map like
gtest.Case(t, func() {
result, err := db.Table(table).Where(g.Map{
"passport like": "user_1%",
}).OrderBy("id asc").All()
gtest.Assert(err, nil)
gtest.Assert(len(result), 2)
gtest.Assert(result[0].GMap().Get("id"), 1)
gtest.Assert(result[1].GMap().Get("id"), 10)
})
// map + slice parameter
gtest.Case(t, func() {
result, err := db.Table(table).Where(g.Map{