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 }