代码拉取完成,页面将自动刷新
package coreModel
import (
"fmt"
"reflect"
"regexp"
"strings"
"gorm.io/gorm"
)
type NullType byte
const (
_ NullType = iota
// IsNull the same as `is null`
IsNull
// IsNotNull the same as `is not null`
IsNotNull
)
func IsExpString(s string) bool {
// 匹配 "exp" 或 "exp" + 正整数
pattern := `^exp(\d+)?$`
re, err := regexp.Compile(pattern)
if err != nil {
return false
}
return re.MatchString(s)
}
// WhereBuild sql build where
func WhereBuild(ado *gorm.DB, where map[string]any) (whereSQL string, vals []any, err error) {
for k, v := range where {
ks := strings.Split(k, " ")
if len(ks) > 2 {
return "", nil, fmt.Errorf("Error in query condition: %s. ", k)
}
if whereSQL != "" {
whereSQL += " AND "
}
//strings.Join(ks, ",")
switch len(ks) {
case 1:
if IsExpString(k) { // 匹配 `"exp" 或 "exp" + 正整数` 直接拼接sql
whereSQL += v.(string)
} else {
switch v := v.(type) {
case NullType:
if v == IsNotNull {
whereSQL += fmt.Sprint(k, " IS NOT NULL")
} else {
whereSQL += fmt.Sprint(k, " IS NULL")
}
default:
whereSQL += fmt.Sprint(k, "=?")
vals = append(vals, v)
}
}
case 2:
k = ks[0]
switch strings.ToLower(ks[1]) {
case "=":
whereSQL += fmt.Sprint(k, "=?")
vals = append(vals, v)
case ">":
whereSQL += fmt.Sprint(k, ">?")
vals = append(vals, v)
case ">=":
whereSQL += fmt.Sprint(k, ">=?")
vals = append(vals, v)
case "<":
whereSQL += fmt.Sprint(k, "<?")
vals = append(vals, v)
case "<=":
whereSQL += fmt.Sprint(k, "<=?")
vals = append(vals, v)
case "!=":
whereSQL += fmt.Sprint(k, "!=?")
vals = append(vals, v)
case "<>":
whereSQL += fmt.Sprint(k, "!=?")
vals = append(vals, v)
case "between":
switch rv := reflect.ValueOf(v); rv.Kind() {
case reflect.Slice, reflect.Array:
if rv.Len() == 2 {
whereSQL += fmt.Sprint(k, " between ? AND ?")
for i := 0; i < rv.Len(); i++ {
vals = append(vals, rv.Index(i).Interface())
}
} else {
return "", nil, fmt.Errorf("between vals error: %s. ", v)
}
default:
return "", nil, fmt.Errorf("between vals error: %s. ", v)
}
case "in":
switch rv := reflect.ValueOf(v); rv.Kind() {
case reflect.Slice, reflect.Array:
if rv.Len() == 0 {
whereSQL += fmt.Sprint(k, " in (NULL)")
} else {
replaceVar := strings.Repeat("?,", rv.Len())
replaceVar = strings.Trim(replaceVar, ",")
inSql := fmt.Sprint(k, " in ("+replaceVar+")")
var inVals []any
for i := 0; i < rv.Len(); i++ {
inVals = append(inVals, rv.Index(i).Interface())
}
whereSQL += ado.Dialector.Explain(inSql, inVals...)
}
default:
whereSQL += fmt.Sprint(k, " in ?")
vals = append(vals, v)
}
case "notin":
switch rv := reflect.ValueOf(v); rv.Kind() {
case reflect.Slice, reflect.Array:
if rv.Len() == 0 {
whereSQL = strings.Trim(whereSQL, " AND ")
} else {
replaceVar := strings.Repeat("?,", rv.Len())
replaceVar = strings.Trim(replaceVar, ",")
inSql := fmt.Sprint(k, " not in ("+replaceVar+")")
var inVals []any
for i := 0; i < rv.Len(); i++ {
inVals = append(inVals, rv.Index(i).Interface())
}
whereSQL += ado.Dialector.Explain(inSql, inVals...)
}
default:
whereSQL += fmt.Sprint(k, " not in ?")
vals = append(vals, v)
}
case "like":
whereSQL += fmt.Sprint(k, " like ?")
vals = append(vals, v)
case "notlike":
whereSQL += fmt.Sprint(k, " not like ?")
vals = append(vals, v)
case "regexp":
whereSQL += fmt.Sprint(k, " regexp ?")
vals = append(vals, v)
case "notregexp":
whereSQL += fmt.Sprint(k, " not regexp ?")
vals = append(vals, v)
}
}
}
return
}
// joinString 将 string 切片转换为逗号分隔的字符串
func joinString(val []string, sep string) string {
strValList := make([]string, len(val))
for i, v := range val {
strValList[i] = fmt.Sprintf("%s", escapeString(v))
}
return strings.Join(strValList, sep)
}
// escapeString 对字符串进行转义,替换特殊字符为转义后的形式
func escapeString(s string) string {
// 替换单引号为两个单引号
s = strings.ReplaceAll(s, "'", "''")
// 替换双引号为两个双引号
s = strings.ReplaceAll(s, `"`, `""`)
// 替换反斜杠为两个反斜杠
s = strings.ReplaceAll(s, `\`, `\\`)
// 替换百分号为转义后的百分号
s = strings.ReplaceAll(s, `%`, `\%`)
// 替换下划线为转义后的下划线
s = strings.ReplaceAll(s, `_`, `\_`)
return s
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。