xugusql_sock.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package xugu
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. )
  7. // cgo_xgc_sql_type -> fun_sql_type
  8. // 判断sql类型
  9. func xgSqlType(sql string) int {
  10. // 去掉首尾的空格、换行符和回车符
  11. sql = strings.TrimSpace(sql)
  12. if len(sql) < 6 {
  13. return SQL_OTHER
  14. }
  15. // 取前6个字符并转为大写
  16. kstr := strings.ToUpper(sql[:6])
  17. // 根据SQL语句前缀判断类型
  18. switch {
  19. case strings.HasPrefix(kstr, "SELECT"):
  20. if strings.Contains(sql, ";") && len(sql[strings.Index(sql, ";"):]) > 5 {
  21. return SQL_OTHER // 多结果集
  22. }
  23. return SQL_SELECT
  24. case strings.HasPrefix(kstr, "INSERT"):
  25. return SQL_INSERT
  26. case strings.HasPrefix(kstr, "UPDATE"):
  27. return SQL_UPDATE
  28. case strings.HasPrefix(kstr, "DELETE"):
  29. return SQL_DELETE
  30. case strings.HasPrefix(kstr, "CREATE"):
  31. return SQL_CREATE
  32. case strings.HasPrefix(kstr, "ALTER "):
  33. return SQL_ALTER
  34. case strings.HasPrefix(kstr, "EXEC "):
  35. return SQL_PROCEDURE
  36. case strings.HasPrefix(kstr, "EXECUT"):
  37. return SQL_PROCEDURE
  38. case strings.HasPrefix(kstr, "STC"):
  39. return SQL_SELECT
  40. default:
  41. return SQL_OTHER
  42. }
  43. }
  44. func xgSockPrepare(conn *xugusqlConn, sql string) (int, error) {
  45. ret := 0
  46. //p_params := &conn.params
  47. if conn.havePrepare != 0 {
  48. ret = xgCmdUnprepare(conn, conn.prepareName)
  49. if ret < 0 {
  50. return ret, nil
  51. }
  52. conn.prepareName = ""
  53. }
  54. conn.prepareName = fmt.Sprintf(conn.prepareName+"STC%d", conn.prepareNo)
  55. ret, err := xgCmdPrepare(conn, sql, &conn.prepareName)
  56. if err != nil {
  57. return ret, err
  58. }
  59. return ret, err
  60. }
  61. // SQL语句prepare准备执行
  62. func xgSockPrepare2(conn *xugusqlConn, cmd_sql string, prepareName *string) (int, error) {
  63. if "" == *prepareName {
  64. return xgSockPrepare(conn, cmd_sql)
  65. }
  66. ret := 0
  67. pconn := conn
  68. // XGCSParam* p_params= pconn->params;
  69. old_p := pconn.havePrepare
  70. // char* sql=strdup(cmd_sql);
  71. *prepareName = fmt.Sprintf("STC%d", pconn.prepareNo)
  72. pconn.prepareNo++ // 递增 prepare_no 的值
  73. ret, err := xgCmdPrepare(conn, cmd_sql, &conn.prepareName)
  74. if err != nil {
  75. return 0, err
  76. }
  77. pconn.havePrepare = old_p // this keeped by prepare_name
  78. return ret, nil
  79. }
  80. func xgCmdUnprepare(pconn *xugusqlConn, prepareName string) int {
  81. var ch byte
  82. var err error
  83. ret := XG_OK
  84. sql := fmt.Sprintf("DEALLOCATE %s ", prepareName)
  85. pconn.mu.Lock()
  86. sockSendCommand0(pconn, sql)
  87. boolRet, err := rhRecvChar(pconn, &ch)
  88. if boolRet || err != nil {
  89. ret = XG_NET_ERROR
  90. } else if ch == 'K' {
  91. pconn.havePrepare = 0
  92. } else {
  93. pconn.havePrepare = 0
  94. var errStre []byte
  95. ret, err = rhRecvStr(pconn, &errStre)
  96. if err != nil || ret < 0 {
  97. pconn.mu.Unlock()
  98. return ret
  99. }
  100. rhRecvChar(pconn, &ch)
  101. ret = XG_ERROR
  102. }
  103. pconn.mu.Unlock()
  104. return 0
  105. }
  106. func xgCmdPrepare(pconn *xugusqlConn, cmd_sql string, prepareName *string) (int, error) {
  107. sqlRet := fmt.Sprintf("PREPARE %s AS %s", prepareName, cmd_sql)
  108. //上锁
  109. //lockConnect(pconn)
  110. pconn.mu.Lock()
  111. sockSendCommand0(pconn, sqlRet)
  112. var ch byte
  113. var ret int
  114. for {
  115. recvRet, err := rhRecvChar(pconn, &ch)
  116. if err != nil {
  117. return 0, err
  118. }
  119. if !recvRet {
  120. pconn.mu.Unlock()
  121. return -4, errors.New("XG_NET_ERROR")
  122. }
  123. //A: SelectResult A在协议里为select返回
  124. if ch == 'A' {
  125. pres := Result{}
  126. pres.Type = HT_RS
  127. ret, err = recvFiledsInfo(pconn, &pres)
  128. if err != nil {
  129. return ret, err
  130. }
  131. pconn.presPrepareCata = &pres
  132. ret = RETURN_PREPARE_SELECT
  133. continue
  134. } else if ch == '$' {
  135. var params XGCSParam
  136. params.Type = HT_PARAMS
  137. params.ImpExpType = 2
  138. recvParamsInfo2(pconn, &params)
  139. pconn.params = &params
  140. continue
  141. } else if ch == 'K' {
  142. pconn.havePrepare = 1
  143. } else {
  144. var errStr []byte
  145. ret, err = rhRecvStr(pconn, &errStr)
  146. if ret < 0 || err != nil {
  147. pconn.mu.Unlock()
  148. return ret, err
  149. }
  150. pconn.errStr = errStr
  151. ret = XG_ERROR
  152. rhRecvChar(pconn, &ch)
  153. if ch != 'K' {
  154. pconn.bkChar = ch
  155. continue
  156. }
  157. }
  158. break
  159. }
  160. pconn.mu.Unlock()
  161. return ret, nil
  162. }