数据库操作
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

130 lines
3.2 KiB

package dbquery
import (
"fmt"
"git.tetele.net/tgo/helper"
"log"
"reflect"
"regexp"
"strconv"
"strings"
"time"
)
// ===================达梦兼容===============
// 非关键字可以不添加标识符,关键字须添加
// 日期函数的使用TO_CHAR(TO_DATE('1970-01-01','yyyy-mm-dd') + (createtime / 86400), 'yyyy-mm-dd')
// group_concat替换成LISTAGG
// ========================================
// 关键字替换-支持达梦和高斯
func ReplaeByOtherSql(sql, sql_type, action string) string {
sql_type_arr := []string{"DmSql", "PgsqlDb"}
if !helper.IsInStringArray(sql_type_arr, sql_type) {
log.Println("sql_type error", sql_type)
return ""
}
// PgsqlDb用
if action == "add" {
sql = helper.StringJoin(sql, " RETURNING id")
}
// 定义需要处理的关键字列表
keywords := []string{"user", "order", "group", "table", "view", "admin", "new"}
if sql_type == "PgsqlDb" {
keywords = []string{"user", "order", "group"}
}
// 移除所有反引号
sql = strings.ReplaceAll(sql, "`", "")
// 使用单词边界 \b 确保只匹配完整单词
pattern := `\b(` + strings.Join(keywords, "|") + `)\b`
re := regexp.MustCompile(pattern)
//设置保护词组
excludePhrases := []string{
"order by", "group by",
}
//保护排除短语
phraseMap := make(map[string]string)
for i, phrase := range excludePhrases {
placeholder := fmt.Sprintf("__EXCLUDE_%d__", i)
phraseMap[placeholder] = phrase
sql = strings.Replace(sql, phrase, placeholder, -1)
}
// 执行替换
sql = re.ReplaceAllStringFunc(sql, func(match string) string {
// 检查匹配是否在字符串常量中
if isInStringLiteral(sql, match) {
return match
}
if sql_type == "DmSql" {
return "`" + match + "`"
} else {
return `"` + match + `"`
}
})
// 恢复排除短语
for placeholder, phrase := range phraseMap {
sql = strings.Replace(sql, placeholder, phrase, -1)
}
return sql
}
// 检查匹配是否在字符串常量中
func isInStringLiteral(sql, match string) bool {
index := strings.Index(sql, match)
if index == -1 {
return false
}
// 检查匹配前的单引号数量
prefix := sql[:index]
singleQuotes := strings.Count(prefix, "'") - strings.Count(prefix, "\\'")
// 奇数表示在字符串常量中
return singleQuotes%2 != 0
}
// 字段值类型转换--针对达梦用
func ToString(value interface{}) string {
switch v := value.(type) {
case string:
return v
case []byte:
return string(v)
case int, int8, int16, int32, int64:
return strconv.FormatInt(reflect.ValueOf(value).Int(), 10)
case uint, uint8, uint16, uint32, uint64:
return strconv.FormatUint(reflect.ValueOf(value).Uint(), 10)
case float32, float64:
return strconv.FormatFloat(reflect.ValueOf(value).Float(), 'f', -1, 64)
case bool:
return strconv.FormatBool(v)
case time.Time:
return v.Format("2006-01-02 15:04:05")
default:
return fmt.Sprintf("%v", v)
}
}
// 字符串切片元素追加前缀
func addPrefixInField(slice []string, prefix string) []string {
new_slice := make([]string, len(slice))
for i, v := range slice {
new_slice[i] = prefix + v
}
return new_slice
}
func DmFieldDeal(fields string) string {
//移除所有反引号
title := strings.Replace(fields, "`", "", -1)
return title
}