123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- package xugu
- import (
- "bytes"
- "encoding/binary"
- "fmt"
- "strings"
- )
- func parseDSN(dsn string) dsnConfig {
- // Initialize a dsnConfig struct
- var config dsnConfig
- // Split the string by semicolons
- pairs := strings.Split(dsn, ";")
- // Iterate over the pairs and map them to the struct fields
- for _, pair := range pairs {
- // Split each pair by the equals sign
- kv := strings.SplitN(pair, "=", 2)
- if len(kv) != 2 {
- continue
- }
- key, value := strings.TrimSpace(kv[0]), strings.Trim(strings.TrimSpace(kv[1]), "'")
- keyL := strings.ToLower(key)
- // Map the key to the appropriate struct field
- switch keyL {
- case "ip":
- config.IP = value
- case "port":
- config.Port = value
- case "db":
- config.Database = value
- case "user":
- config.User = value
- case "pwd":
- config.Password = value
- case "encryptor":
- config.Encryptor = value
- case "char_set":
- config.CharSet = value
- case "time_zone":
- config.TimeZone = value
- case "iso_level":
- config.IsoLevel = value
- case "lock_timeout":
- config.LockTimeout = value
- case "auto_commit":
- config.AutoCommit = value
- case "strict_commit":
- config.StrictCommit = value
- case "result":
- config.Result = value
- case "return_schema":
- config.ReturnSchema = value
- case "return_cursor_id":
- config.ReturnCursorID = value
- case "lob_ret":
- config.LobRet = value
- case "return_rowid":
- config.ReturnRowid = value
- case "version":
- config.Version = value
- }
- }
- return config
- }
- func generateLoginString(config dsnConfig) string {
- baseString := "login database = '%s' user = '%s' password = '%s' "
- additionalParams := ""
- if config.Encryptor != "" {
- additionalParams += fmt.Sprintf(" encryptor='%s'", config.Encryptor)
- }
- if config.CharSet != "" {
- additionalParams += fmt.Sprintf(" char_set='%s'", config.CharSet)
- }
- if config.TimeZone != "" {
- additionalParams += fmt.Sprintf(" time_zone='%s'", config.TimeZone)
- }
- if config.IsoLevel != "" {
- additionalParams += fmt.Sprintf(" iso_level='%s'", config.IsoLevel)
- }
- if config.LockTimeout != "" {
- additionalParams += fmt.Sprintf(" lock_timeout='%s'", config.LockTimeout)
- }
- if config.AutoCommit != "" {
- additionalParams += fmt.Sprintf(" auto_commit='%s'", config.AutoCommit)
- }
- if config.StrictCommit != "" {
- additionalParams += fmt.Sprintf(" strict_commit='%s'", config.StrictCommit)
- }
- if config.Result != "" {
- additionalParams += fmt.Sprintf(" result='%s'", config.Result)
- }
- if config.ReturnSchema != "" {
- additionalParams += fmt.Sprintf(" return_schema='%s'", config.ReturnSchema)
- }
- if config.ReturnCursorID != "" {
- additionalParams += fmt.Sprintf(" return_cursor_id='%s'", config.ReturnCursorID)
- }
- if config.LobRet != "" {
- additionalParams += fmt.Sprintf(" lob_ret='%s'", config.LobRet)
- }
- if config.ReturnRowid != "" {
- additionalParams += fmt.Sprintf(" return_rowid='%s'", config.ReturnRowid)
- }
- if config.Version != "" {
- additionalParams += fmt.Sprintf(" version='%s'", config.Version)
- } else {
- additionalParams += " version='201'"
- }
- finalString := fmt.Sprintf(baseString, config.Database, config.User, config.Password)
- if additionalParams != "" {
- finalString += additionalParams
- }
- //finalString += " version='201'"
- return finalString
- }
- // cgo_xgc_sql_type -> fun_sql_type
- // 判断sql类型
- func switchSQLType(sql string) int {
- // 去掉首尾的空格、换行符和回车符
- sql = strings.TrimSpace(sql)
- if len(sql) < 6 {
- return SQL_OTHER
- }
- // 取前6个字符并转为大写
- kstr := strings.ToUpper(sql[:6])
- // 根据SQL语句前缀判断类型
- switch {
- case strings.HasPrefix(kstr, "SELECT"):
- if strings.Contains(sql, ";") && len(sql[strings.Index(sql, ";"):]) > 5 {
- return SQL_OTHER // 多结果集
- }
- return SQL_SELECT
- case strings.HasPrefix(kstr, "INSERT"):
- return SQL_INSERT
- case strings.HasPrefix(kstr, "UPDATE"):
- return SQL_UPDATE
- case strings.HasPrefix(kstr, "DELETE"):
- return SQL_DELETE
- case strings.HasPrefix(kstr, "CREATE"):
- return SQL_CREATE
- case strings.HasPrefix(kstr, "ALTER "):
- return SQL_ALTER
- case strings.HasPrefix(kstr, "EXEC "):
- return SQL_PROCEDURE
- case strings.HasPrefix(kstr, "EXECUT"):
- return SQL_PROCEDURE
- case strings.HasPrefix(kstr, "STC"):
- return SQL_SELECT
- default:
- return SQL_OTHER
- }
- }
- func getSQLCType(typeID uint32) int32 {
- switch typeID {
- case TYPE_BOOL:
- return XG_C_BOOL
- case TYPE_I1:
- return XG_C_TINYINT
- case TYPE_I2:
- return XG_C_SHORT
- case TYPE_I4:
- return XG_C_INTEGER
- case TYPE_I8:
- return XG_C_BIGINT
- case TYPE_R4:
- return XG_C_FLOAT
- case TYPE_R8:
- return XG_C_DOUBLE
- case TYPE_NUM:
- return XG_C_NUMERIC
- case TYPE_DATETIME:
- return XG_C_DATETIME
- case TYPE_DATETIME_TZ:
- return XG_C_DATETIME_TZ
- case TYPE_INTERVAL_Y2M:
- return XG_C_INTERVAL_YEAR_TO_MONTH
- case TYPE_INTERVAL_D2S:
- return XG_C_INTERVAL_DAY_TO_SECOND
- case TYPE_GUID:
- return TYPE_GUID + 40
- case TYPE_TIME_TZ:
- return XG_C_TIME_TZ
- case TYPE_DATE:
- return XG_C_DATE
- case TYPE_TIME:
- return XG_C_TIME
- case TYPE_BINARY:
- return XG_C_BINARY
- case TYPE_CLOB:
- return XG_C_CLOB
- case TYPE_BLOB:
- return XG_C_BLOB
- case TYPE_INTERVAL_Y, TYPE_INTERVAL_M, TYPE_INTERVAL_D, TYPE_INTERVAL_H,
- TYPE_INTERVAL_MI, TYPE_INTERVAL_S, TYPE_INTERVAL_D2H, TYPE_INTERVAL_D2M,
- TYPE_INTERVAL_H2M, TYPE_INTERVAL_H2S, TYPE_INTERVAL_M2S:
- return XG_C_INTERVAL
- default:
- return XG_C_CHAR
- }
- }
- func needCopyV(xgtype int) bool {
- switch xgtype {
- case XG_C_DOUBLE, XG_C_FLOAT, DATETIME_ASLONG, XG_C_BIGINT, XG_C_INTEGER, XG_C_SHORT, XG_C_TINYINT, XG_C_CHARN1, XG_C_BOOL, XG_C_NUMERIC:
- return true
- default:
- return false
- }
- }
- // 整形转换成字节
- func IntToBytes(n uint32, b byte) ([]byte, error) {
- switch b {
- case 1:
- tmp := int8(n)
- bytesBuffer := bytes.NewBuffer([]byte{})
- binary.Write(bytesBuffer, binary.BigEndian, &tmp)
- return bytesBuffer.Bytes(), nil
- case 2:
- tmp := int16(n)
- bytesBuffer := bytes.NewBuffer([]byte{})
- binary.Write(bytesBuffer, binary.BigEndian, &tmp)
- return bytesBuffer.Bytes(), nil
- case 3, 4:
- tmp := int32(n)
- bytesBuffer := bytes.NewBuffer([]byte{})
- binary.Write(bytesBuffer, binary.BigEndian, &tmp)
- return bytesBuffer.Bytes(), nil
- }
- return nil, fmt.Errorf("IntToBytes b param is invaild")
- }
- // reverseBytes 反转 byte slice 的顺序
- func reverseBytes(b []byte) []byte {
- reversed := make([]byte, len(b))
- for i := range b {
- reversed[i] = b[len(b)-1-i]
- }
- return reversed
- }
|