feat(db): 添加对达梦数据库的支持
- 在应用程序中新增对达梦数据库(DM)的配置和连接支持 - 实现 SetDmDB 函数以配置达梦数据库连接 - 更新数据库操作逻辑,支持达梦特有的 SQL 语法和功能 - 在相关文件中添加达梦数据库的处理逻辑,包括表创建、数据插入和查询 - 更新 go.mod 和 go.sum 文件以引入达梦数据库驱动 - 增强文档,详细说明达梦数据库的配置和使用方法
This commit is contained in:
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2018, 达梦数据库有限公司.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
func Split(s string, sep string) []string {
|
||||
var foot = make([]int, len(s)) // 足够的元素个数
|
||||
var count, sLen, sepLen = 0, len(s), len(sep)
|
||||
for i := 0; i < sLen; i++ {
|
||||
// 处理 s == “-9999-1" && seperators == "-"情况
|
||||
if i == 0 && sLen >= sepLen {
|
||||
if s[0:sepLen] == sep {
|
||||
i += sepLen - 1
|
||||
continue
|
||||
}
|
||||
}
|
||||
for j := 0; j < sepLen; j++ {
|
||||
if s[i] == sep[j] {
|
||||
foot[count] = i
|
||||
count++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
var ret = make([]string, count+1)
|
||||
if count == 0 {
|
||||
ret[0] = s
|
||||
return ret
|
||||
}
|
||||
ret[0] = s[0:foot[0]]
|
||||
for i := 1; i < count; i++ {
|
||||
ret[i] = s[foot[i-1]+1 : foot[i]]
|
||||
}
|
||||
ret[count] = s[foot[count-1]+1:]
|
||||
return ret
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2018, 达梦数据库有限公司.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"go/build"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
PathSeparator = string(os.PathSeparator)
|
||||
PathListSeparator = string(os.PathListSeparator)
|
||||
)
|
||||
|
||||
var (
|
||||
goRoot = build.Default.GOROOT
|
||||
goPath = build.Default.GOPATH //获取实际编译时的GOPATH值
|
||||
)
|
||||
|
||||
type fileUtil struct {
|
||||
}
|
||||
|
||||
var FileUtil = &fileUtil{}
|
||||
|
||||
func (fileUtil *fileUtil) Exists(path string) bool {
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (fileUtil *fileUtil) Search(relativePath string) (path string) {
|
||||
if strings.Contains(runtime.GOOS, "windows") {
|
||||
relativePath = strings.ReplaceAll(relativePath, "/", "\\")
|
||||
}
|
||||
|
||||
if fileUtil.Exists(goPath) {
|
||||
for _, s := range strings.Split(goPath, PathListSeparator) {
|
||||
path = s + PathSeparator + "src" + PathSeparator + relativePath
|
||||
if fileUtil.Exists(path) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if fileUtil.Exists(goPath) {
|
||||
for _, s := range strings.Split(goPath, PathListSeparator) {
|
||||
path = s + PathSeparator + "pkg" + PathSeparator + relativePath
|
||||
if fileUtil.Exists(path) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if workDir, _ := os.Getwd(); fileUtil.Exists(workDir) {
|
||||
// path = workDir + PathSeparator + "src" + PathSeparator + relativePath
|
||||
// if fileUtil.Exists(path) {
|
||||
// return path
|
||||
// }
|
||||
//}
|
||||
|
||||
//if fileUtil.Exists(goRoot) {
|
||||
// path = goRoot + PathSeparator + "src" + PathSeparator + relativePath
|
||||
// if fileUtil.Exists(path) {
|
||||
// return path
|
||||
// }
|
||||
//}
|
||||
|
||||
return ""
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2018, 达梦数据库有限公司.
|
||||
* All rights reserved.
|
||||
*/
|
||||
package util
|
||||
|
||||
const (
|
||||
LINE_SEPARATOR = "\n"
|
||||
)
|
||||
|
||||
// 执行f并忽略panic
|
||||
func AbsorbPanic(f func()){
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
// TODO do something
|
||||
}
|
||||
}()
|
||||
f()
|
||||
}
|
||||
|
||||
func SliceEquals(src []byte, dest []byte) bool {
|
||||
if len(src) != len(dest) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, _ := range src {
|
||||
if src[i] != dest[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 获取两个数的最大公约数,由调用者确保m、n>=0;如果m或n为0,返回1
|
||||
func GCD(m int32, n int32) int32 {
|
||||
if m == 0 || n == 0 {
|
||||
return 1
|
||||
}
|
||||
r := m % n
|
||||
m = n
|
||||
n = r
|
||||
if r == 0 {
|
||||
return m
|
||||
} else {
|
||||
return GCD(m, n)
|
||||
}
|
||||
}
|
||||
|
||||
// 返回切片中所有数的累加值
|
||||
func Sum(arr []int32) int32 {
|
||||
var sum int32 = 0
|
||||
for _, i := range arr {
|
||||
sum += i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2018, 达梦数据库有限公司.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type stringutil struct{}
|
||||
|
||||
var StringUtil = &stringutil{}
|
||||
|
||||
/*----------------------------------------------------*/
|
||||
func (StringUtil *stringutil) LineSeparator() string {
|
||||
var lineSeparator string
|
||||
if strings.Contains(runtime.GOOS, "windows") {
|
||||
lineSeparator = "\r\n"
|
||||
} else if strings.Contains(runtime.GOOS, "mac") {
|
||||
lineSeparator = "\r"
|
||||
} else {
|
||||
lineSeparator = "\n"
|
||||
}
|
||||
|
||||
return lineSeparator
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) Equals(str1 string, str2 string) bool {
|
||||
return str1 == str2
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) EqualsIgnoreCase(str1 string, str2 string) bool {
|
||||
return strings.ToUpper(str1) == strings.ToUpper(str2)
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) StartsWith(s string, subStr string) bool {
|
||||
return strings.Index(s, subStr) == 0
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) StartWithIgnoreCase(s string, subStr string) bool {
|
||||
return strings.HasPrefix(strings.ToLower(s), strings.ToLower(subStr))
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) EndsWith(s string, subStr string) bool {
|
||||
return strings.LastIndex(s, subStr) == len(s)-1
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) IsDigit(str string) bool {
|
||||
if str == "" {
|
||||
return false
|
||||
}
|
||||
sz := len(str)
|
||||
for i := 0; i < sz; i++ {
|
||||
if unicode.IsDigit(rune(str[i])) {
|
||||
continue
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) FormatDir(dir string) string {
|
||||
dir = strings.TrimSpace(dir)
|
||||
if dir != "" {
|
||||
if !StringUtil.EndsWith(dir, PathSeparator) {
|
||||
dir += PathSeparator
|
||||
}
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) HexStringToBytes(s string) []byte {
|
||||
str := s
|
||||
|
||||
bs := make([]byte, 0)
|
||||
flag := false
|
||||
|
||||
if strings.Index(str, "0x") == 0 || strings.Index(str, "0X") == 0 {
|
||||
str = str[2:]
|
||||
}
|
||||
|
||||
if len(str) == 0 {
|
||||
return bs
|
||||
}
|
||||
|
||||
var bsChr []byte
|
||||
l := len(str)
|
||||
|
||||
if l%2 == 0 {
|
||||
bsChr = []byte(str)
|
||||
} else {
|
||||
l += 1
|
||||
bsChr = make([]byte, l)
|
||||
bsChr[0] = '0'
|
||||
for i := 0; i < l-1; i++ {
|
||||
bsChr[i+1] = str[i]
|
||||
}
|
||||
}
|
||||
|
||||
bs = make([]byte, l/2)
|
||||
|
||||
pos := 0
|
||||
for i := 0; i < len(bsChr); i += 2 {
|
||||
bt := convertHex(bsChr[i])
|
||||
bt2 := convertHex(bsChr[i+1])
|
||||
if int(bt) == 0xff || int(bt2) == 0xff {
|
||||
flag = true
|
||||
break
|
||||
}
|
||||
|
||||
bs[pos] = byte(bt*16 + bt2)
|
||||
pos++
|
||||
}
|
||||
|
||||
if flag {
|
||||
bs = ([]byte)(str)
|
||||
}
|
||||
|
||||
return bs
|
||||
}
|
||||
|
||||
func convertHex(chr byte) byte {
|
||||
if chr >= '0' && chr <= '9' {
|
||||
return chr - '0'
|
||||
} else if chr >= 'a' && chr <= 'f' {
|
||||
return chr - 'a' + 10
|
||||
} else if chr >= 'A' && chr <= 'F' {
|
||||
return chr - 'A' + 10
|
||||
} else {
|
||||
return 0xff
|
||||
}
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) BytesToHexString(bs []byte, pre bool) string {
|
||||
if bs == nil {
|
||||
return ""
|
||||
}
|
||||
if len(bs) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
hexDigits := "0123456789ABCDEF"
|
||||
ret := new(strings.Builder)
|
||||
for _, b := range bs {
|
||||
ret.WriteByte(hexDigits[0x0F&(b>>4)])
|
||||
ret.WriteByte(hexDigits[0x0F&b])
|
||||
}
|
||||
if pre {
|
||||
return "0x" + ret.String()
|
||||
}
|
||||
return ret.String()
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) ProcessSingleQuoteOfName(name string) string {
|
||||
return StringUtil.processQuoteOfName(name, "'")
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) ProcessDoubleQuoteOfName(name string) string {
|
||||
return StringUtil.processQuoteOfName(name, "\"")
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) processQuoteOfName(name string, quote string) string {
|
||||
if quote == "" || name == "" {
|
||||
return name
|
||||
}
|
||||
|
||||
temp := name
|
||||
result := bytes.NewBufferString("")
|
||||
index := -1
|
||||
quetoLength := len(quote)
|
||||
index = strings.Index(temp, quote)
|
||||
for index != -1 {
|
||||
result.WriteString(temp[:index+quetoLength])
|
||||
result.WriteString(quote)
|
||||
temp = temp[index+quetoLength:]
|
||||
index = strings.Index(temp, quote)
|
||||
}
|
||||
result.WriteString(temp)
|
||||
return result.String()
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) FormatTime() string {
|
||||
return time.Now().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func (StringUtil *stringutil) SubstringBetween(str string, open string, close string) string {
|
||||
if str == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
iopen := -1
|
||||
if open != "" {
|
||||
iopen = strings.Index(str, open)
|
||||
}
|
||||
|
||||
iclose := -1
|
||||
if close != "" {
|
||||
iclose = strings.LastIndex(str, close)
|
||||
}
|
||||
|
||||
if iopen == -1 && iclose == -1 {
|
||||
return ""
|
||||
} else if iopen == -1 {
|
||||
return str[0:iclose]
|
||||
} else if iclose == -1 {
|
||||
return str[iopen:]
|
||||
} else {
|
||||
return str[iopen:iclose]
|
||||
}
|
||||
}
|
||||
|
||||
//bug656976 在常量参数化时,将\+任意字符的两个字符解析成一个转义后字符,如:
|
||||
// 字符串参数'a\nb'解析成字符串参数'a换行b'
|
||||
func (StringUtil *stringutil) Translate(s string) string {
|
||||
if !strings.ContainsRune(s, '\\') {
|
||||
return s
|
||||
}
|
||||
reader := strings.NewReader(s)
|
||||
trans := bytes.NewBufferString("")
|
||||
|
||||
for {
|
||||
curRune, _, err := reader.ReadRune()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if curRune != '\\' {
|
||||
trans.WriteRune(curRune)
|
||||
} else {
|
||||
//转义规则参考mysql,'\'作为转义符必须消除,不管是否作为有真正含义的特殊字符,如\x也需要变化为x
|
||||
nextRune, _, err := reader.ReadRune()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
switch nextRune {
|
||||
case 'b':
|
||||
trans.WriteRune('\b')
|
||||
break
|
||||
case 'f':
|
||||
trans.WriteRune('\f')
|
||||
break
|
||||
case 'n':
|
||||
trans.WriteRune('\n')
|
||||
break
|
||||
case 'r':
|
||||
trans.WriteRune('\r')
|
||||
break
|
||||
case 't':
|
||||
trans.WriteRune('\t')
|
||||
break
|
||||
default:
|
||||
trans.WriteRune(nextRune)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return trans.String()
|
||||
}
|
||||
Reference in New Issue
Block a user