2019-02-02 16:18:25 +08:00
|
|
|
|
// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
2018-12-14 18:35:51 +08:00
|
|
|
|
//
|
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
2019-02-02 16:18:25 +08:00
|
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2018-12-14 18:35:51 +08:00
|
|
|
|
|
|
|
|
|
package gdb
|
|
|
|
|
|
|
|
|
|
import (
|
2018-12-17 10:52:44 +08:00
|
|
|
|
"bytes"
|
2018-12-14 18:35:51 +08:00
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
2019-02-02 16:18:25 +08:00
|
|
|
|
"github.com/gogf/gf/g/os/glog"
|
|
|
|
|
"github.com/gogf/gf/g/os/gtime"
|
|
|
|
|
"github.com/gogf/gf/g/text/gregex"
|
2019-03-03 00:14:20 +08:00
|
|
|
|
"github.com/gogf/gf/g/util/gconv"
|
2019-02-02 16:18:25 +08:00
|
|
|
|
_ "github.com/gogf/gf/third/github.com/go-sql-driver/mysql"
|
2018-12-15 15:50:39 +08:00
|
|
|
|
"reflect"
|
2018-12-17 10:52:44 +08:00
|
|
|
|
"strings"
|
2018-12-14 18:35:51 +08:00
|
|
|
|
)
|
|
|
|
|
|
2018-12-15 15:50:39 +08:00
|
|
|
|
// 格式化SQL查询条件
|
2019-03-03 00:14:20 +08:00
|
|
|
|
func formatCondition(where interface{}, args []interface{}) (newWhere string, newArgs []interface{}) {
|
2018-12-17 10:52:44 +08:00
|
|
|
|
// 条件字符串处理
|
|
|
|
|
buffer := bytes.NewBuffer(nil)
|
2019-02-26 14:23:29 +08:00
|
|
|
|
// 使用反射进行类型判断
|
|
|
|
|
rv := reflect.ValueOf(where)
|
|
|
|
|
kind := rv.Kind()
|
|
|
|
|
if kind == reflect.Ptr {
|
|
|
|
|
rv = rv.Elem()
|
|
|
|
|
kind = rv.Kind()
|
|
|
|
|
}
|
|
|
|
|
switch kind {
|
2019-03-03 00:14:20 +08:00
|
|
|
|
// 注意当where为map/struct类型时,args参数必须为空。
|
2019-02-26 14:23:29 +08:00
|
|
|
|
case reflect.Map: fallthrough
|
|
|
|
|
case reflect.Struct:
|
|
|
|
|
for k, v := range gconv.Map(where) {
|
|
|
|
|
if buffer.Len() > 0 {
|
|
|
|
|
buffer.WriteString(" AND ")
|
|
|
|
|
}
|
2019-03-03 00:14:20 +08:00
|
|
|
|
buffer.WriteString(k + "=?")
|
|
|
|
|
newArgs = append(newArgs, v)
|
2018-12-15 15:50:39 +08:00
|
|
|
|
}
|
2019-03-03 00:14:20 +08:00
|
|
|
|
newWhere = buffer.String()
|
2019-02-26 14:23:29 +08:00
|
|
|
|
default:
|
|
|
|
|
buffer.WriteString(gconv.String(where))
|
2018-12-15 15:50:39 +08:00
|
|
|
|
}
|
2018-12-17 10:52:44 +08:00
|
|
|
|
if buffer.Len() == 0 {
|
2019-01-21 16:26:47 +08:00
|
|
|
|
buffer.WriteString("1=1")
|
2018-12-14 18:35:51 +08:00
|
|
|
|
}
|
2019-03-03 00:14:20 +08:00
|
|
|
|
// 查询条件参数处理,主要处理slice参数类型
|
|
|
|
|
newWhere = buffer.String()
|
2018-12-17 10:52:44 +08:00
|
|
|
|
if len(args) > 0 {
|
|
|
|
|
for index, arg := range args {
|
|
|
|
|
rv := reflect.ValueOf(arg)
|
|
|
|
|
kind := rv.Kind()
|
|
|
|
|
if kind == reflect.Ptr {
|
|
|
|
|
rv = rv.Elem()
|
|
|
|
|
kind = rv.Kind()
|
|
|
|
|
}
|
|
|
|
|
switch kind {
|
2019-03-03 00:14:20 +08:00
|
|
|
|
// '?'占位符支持slice类型,
|
|
|
|
|
// 这里会将slice参数拆散,并更新原有占位符'?'为多个'?',使用','符号连接。
|
2018-12-17 10:52:44 +08:00
|
|
|
|
case reflect.Slice: fallthrough
|
|
|
|
|
case reflect.Array:
|
|
|
|
|
for i := 0; i < rv.Len(); i++ {
|
|
|
|
|
newArgs = append(newArgs, rv.Index(i).Interface())
|
|
|
|
|
}
|
|
|
|
|
counter := 0
|
|
|
|
|
newWhere, _ = gregex.ReplaceStringFunc(`\?`, newWhere, func(s string) string {
|
|
|
|
|
counter++
|
|
|
|
|
if counter == index + 1 {
|
|
|
|
|
return "?" + strings.Repeat(",?", rv.Len() - 1)
|
|
|
|
|
}
|
|
|
|
|
return s
|
|
|
|
|
})
|
|
|
|
|
default:
|
|
|
|
|
newArgs = append(newArgs, arg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-03-03 00:14:20 +08:00
|
|
|
|
return
|
2018-12-14 18:35:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打印SQL对象(仅在debug=true时有效)
|
|
|
|
|
func printSql(v *Sql) {
|
|
|
|
|
s := fmt.Sprintf("%s, %v, %s, %s, %d ms, %s", v.Sql, v.Args,
|
|
|
|
|
gtime.NewFromTimeStamp(v.Start).Format("Y-m-d H:i:s.u"),
|
|
|
|
|
gtime.NewFromTimeStamp(v.End).Format("Y-m-d H:i:s.u"),
|
|
|
|
|
v.End - v.Start,
|
|
|
|
|
v.Func,
|
|
|
|
|
)
|
|
|
|
|
if v.Error != nil {
|
|
|
|
|
s += "\nError: " + v.Error.Error()
|
|
|
|
|
glog.Backtrace(true, 2).Error(s)
|
|
|
|
|
} else {
|
|
|
|
|
glog.Debug(s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 格式化错误信息
|
|
|
|
|
func formatError(err error, query string, args ...interface{}) error {
|
|
|
|
|
if err != nil {
|
|
|
|
|
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 err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据insert选项获得操作名称
|
2018-12-15 15:50:39 +08:00
|
|
|
|
func getInsertOperationByOption(option int) string {
|
2019-02-26 01:19:01 +08:00
|
|
|
|
operator := "INSERT"
|
2018-12-14 18:35:51 +08:00
|
|
|
|
switch option {
|
|
|
|
|
case OPTION_REPLACE:
|
2019-02-26 01:19:01 +08:00
|
|
|
|
operator = "REPLACE"
|
2018-12-14 18:35:51 +08:00
|
|
|
|
case OPTION_SAVE:
|
|
|
|
|
case OPTION_IGNORE:
|
2019-02-26 01:19:01 +08:00
|
|
|
|
operator = "INSERT IGNORE"
|
2018-12-14 18:35:51 +08:00
|
|
|
|
}
|
2019-02-26 01:19:01 +08:00
|
|
|
|
return operator
|
2018-12-14 18:35:51 +08:00
|
|
|
|
}
|