xugu_utils.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package xugu
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "strings"
  7. )
  8. func parseDSN(dsn string) dsnConfig {
  9. // Initialize a dsnConfig struct
  10. var config dsnConfig
  11. // Split the string by semicolons
  12. pairs := strings.Split(dsn, ";")
  13. // Iterate over the pairs and map them to the struct fields
  14. for _, pair := range pairs {
  15. // Split each pair by the equals sign
  16. kv := strings.SplitN(pair, "=", 2)
  17. if len(kv) != 2 {
  18. continue
  19. }
  20. key, value := strings.TrimSpace(kv[0]), strings.Trim(strings.TrimSpace(kv[1]), "'")
  21. keyL := strings.ToLower(key)
  22. // Map the key to the appropriate struct field
  23. switch keyL {
  24. case "ip":
  25. config.IP = value
  26. case "port":
  27. config.Port = value
  28. case "db":
  29. config.Database = value
  30. case "user":
  31. config.User = value
  32. case "pwd":
  33. config.Password = value
  34. case "encryptor":
  35. config.Encryptor = value
  36. case "char_set":
  37. config.CharSet = value
  38. case "time_zone":
  39. config.TimeZone = value
  40. case "iso_level":
  41. config.IsoLevel = value
  42. case "lock_timeout":
  43. config.LockTimeout = value
  44. case "auto_commit":
  45. config.AutoCommit = value
  46. case "strict_commit":
  47. config.StrictCommit = value
  48. case "result":
  49. config.Result = value
  50. case "return_schema":
  51. config.ReturnSchema = value
  52. case "return_cursor_id":
  53. config.ReturnCursorID = value
  54. case "lob_ret":
  55. config.LobRet = value
  56. case "return_rowid":
  57. config.ReturnRowid = value
  58. case "version":
  59. config.Version = value
  60. }
  61. }
  62. return config
  63. }
  64. func generateLoginString(config dsnConfig) string {
  65. baseString := "login database = '%s' user = '%s' password = '%s' "
  66. additionalParams := ""
  67. if config.Encryptor != "" {
  68. additionalParams += fmt.Sprintf(" encryptor='%s'", config.Encryptor)
  69. }
  70. if config.CharSet != "" {
  71. additionalParams += fmt.Sprintf(" char_set='%s'", config.CharSet)
  72. }
  73. if config.TimeZone != "" {
  74. additionalParams += fmt.Sprintf(" time_zone='%s'", config.TimeZone)
  75. }
  76. if config.IsoLevel != "" {
  77. additionalParams += fmt.Sprintf(" iso_level='%s'", config.IsoLevel)
  78. }
  79. if config.LockTimeout != "" {
  80. additionalParams += fmt.Sprintf(" lock_timeout='%s'", config.LockTimeout)
  81. }
  82. if config.AutoCommit != "" {
  83. additionalParams += fmt.Sprintf(" auto_commit='%s'", config.AutoCommit)
  84. }
  85. if config.StrictCommit != "" {
  86. additionalParams += fmt.Sprintf(" strict_commit='%s'", config.StrictCommit)
  87. }
  88. if config.Result != "" {
  89. additionalParams += fmt.Sprintf(" result='%s'", config.Result)
  90. }
  91. if config.ReturnSchema != "" {
  92. additionalParams += fmt.Sprintf(" return_schema='%s'", config.ReturnSchema)
  93. }
  94. if config.ReturnCursorID != "" {
  95. additionalParams += fmt.Sprintf(" return_cursor_id='%s'", config.ReturnCursorID)
  96. }
  97. if config.LobRet != "" {
  98. additionalParams += fmt.Sprintf(" lob_ret='%s'", config.LobRet)
  99. }
  100. if config.ReturnRowid != "" {
  101. additionalParams += fmt.Sprintf(" return_rowid='%s'", config.ReturnRowid)
  102. }
  103. if config.Version != "" {
  104. additionalParams += fmt.Sprintf(" version='%s'", config.Version)
  105. } else {
  106. additionalParams += " version='201'"
  107. }
  108. finalString := fmt.Sprintf(baseString, config.Database, config.User, config.Password)
  109. if additionalParams != "" {
  110. finalString += additionalParams
  111. }
  112. //finalString += " version='201'"
  113. return finalString
  114. }
  115. // cgo_xgc_sql_type -> fun_sql_type
  116. // 判断sql类型
  117. func switchSQLType(sql string) int {
  118. // 去掉首尾的空格、换行符和回车符
  119. sql = strings.TrimSpace(sql)
  120. if len(sql) < 6 {
  121. return SQL_OTHER
  122. }
  123. // 取前6个字符并转为大写
  124. kstr := strings.ToUpper(sql[:6])
  125. // 根据SQL语句前缀判断类型
  126. switch {
  127. case strings.HasPrefix(kstr, "SELECT"):
  128. if strings.Contains(sql, ";") && len(sql[strings.Index(sql, ";"):]) > 5 {
  129. return SQL_OTHER // 多结果集
  130. }
  131. return SQL_SELECT
  132. case strings.HasPrefix(kstr, "INSERT"):
  133. return SQL_INSERT
  134. case strings.HasPrefix(kstr, "UPDATE"):
  135. return SQL_UPDATE
  136. case strings.HasPrefix(kstr, "DELETE"):
  137. return SQL_DELETE
  138. case strings.HasPrefix(kstr, "CREATE"):
  139. return SQL_CREATE
  140. case strings.HasPrefix(kstr, "ALTER "):
  141. return SQL_ALTER
  142. case strings.HasPrefix(kstr, "EXEC "):
  143. return SQL_PROCEDURE
  144. case strings.HasPrefix(kstr, "EXECUT"):
  145. return SQL_PROCEDURE
  146. case strings.HasPrefix(kstr, "STC"):
  147. return SQL_SELECT
  148. default:
  149. return SQL_OTHER
  150. }
  151. }
  152. func getSQLCType(typeID uint32) int32 {
  153. switch typeID {
  154. case TYPE_BOOL:
  155. return XG_C_BOOL
  156. case TYPE_I1:
  157. return XG_C_TINYINT
  158. case TYPE_I2:
  159. return XG_C_SHORT
  160. case TYPE_I4:
  161. return XG_C_INTEGER
  162. case TYPE_I8:
  163. return XG_C_BIGINT
  164. case TYPE_R4:
  165. return XG_C_FLOAT
  166. case TYPE_R8:
  167. return XG_C_DOUBLE
  168. case TYPE_NUM:
  169. return XG_C_NUMERIC
  170. case TYPE_DATETIME:
  171. return XG_C_DATETIME
  172. case TYPE_DATETIME_TZ:
  173. return XG_C_DATETIME_TZ
  174. case TYPE_INTERVAL_Y2M:
  175. return XG_C_INTERVAL_YEAR_TO_MONTH
  176. case TYPE_INTERVAL_D2S:
  177. return XG_C_INTERVAL_DAY_TO_SECOND
  178. case TYPE_GUID:
  179. return TYPE_GUID + 40
  180. case TYPE_TIME_TZ:
  181. return XG_C_TIME_TZ
  182. case TYPE_DATE:
  183. return XG_C_DATE
  184. case TYPE_TIME:
  185. return XG_C_TIME
  186. case TYPE_BINARY:
  187. return XG_C_BINARY
  188. case TYPE_CLOB:
  189. return XG_C_CLOB
  190. case TYPE_BLOB:
  191. return XG_C_BLOB
  192. case TYPE_INTERVAL_Y, TYPE_INTERVAL_M, TYPE_INTERVAL_D, TYPE_INTERVAL_H,
  193. TYPE_INTERVAL_MI, TYPE_INTERVAL_S, TYPE_INTERVAL_D2H, TYPE_INTERVAL_D2M,
  194. TYPE_INTERVAL_H2M, TYPE_INTERVAL_H2S, TYPE_INTERVAL_M2S:
  195. return XG_C_INTERVAL
  196. default:
  197. return XG_C_CHAR
  198. }
  199. }
  200. func needCopyV(xgtype int) bool {
  201. switch xgtype {
  202. 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:
  203. return true
  204. default:
  205. return false
  206. }
  207. }
  208. // 整形转换成字节
  209. func IntToBytes(n uint32, b byte) ([]byte, error) {
  210. switch b {
  211. case 1:
  212. tmp := int8(n)
  213. bytesBuffer := bytes.NewBuffer([]byte{})
  214. binary.Write(bytesBuffer, binary.BigEndian, &tmp)
  215. return bytesBuffer.Bytes(), nil
  216. case 2:
  217. tmp := int16(n)
  218. bytesBuffer := bytes.NewBuffer([]byte{})
  219. binary.Write(bytesBuffer, binary.BigEndian, &tmp)
  220. return bytesBuffer.Bytes(), nil
  221. case 3, 4:
  222. tmp := int32(n)
  223. bytesBuffer := bytes.NewBuffer([]byte{})
  224. binary.Write(bytesBuffer, binary.BigEndian, &tmp)
  225. return bytesBuffer.Bytes(), nil
  226. }
  227. return nil, fmt.Errorf("IntToBytes b param is invaild")
  228. }
  229. // reverseBytes 反转 byte slice 的顺序
  230. func reverseBytes(b []byte) []byte {
  231. reversed := make([]byte, len(b))
  232. for i := range b {
  233. reversed[i] = b[len(b)-1-i]
  234. }
  235. return reversed
  236. }