mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
add support for like statement in map key for Where function, improve error format for gdb
This commit is contained in:
@ -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)
|
||||
|
||||
@ -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])
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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())
|
||||
}
|
||||
|
||||
@ -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{
|
||||
|
||||
Reference in New Issue
Block a user