xugu_stmt.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. package xugu
  2. import (
  3. "database/sql/driver"
  4. "errors"
  5. "fmt"
  6. )
  7. type xuguStmt struct {
  8. // 上下文连接句柄指针
  9. stmt_conn *xuguConn
  10. // 布尔值,用于标识执行的 SQL 语句是否已准备好
  11. prepared bool
  12. // 接受准备好的 SQL 语句的代码
  13. prename []byte
  14. // 布尔值,用于标识游标是否启用
  15. curopend bool
  16. // 游标名称
  17. curname []byte
  18. // 执行的 SQL 语句中的参数数量
  19. paramCount int
  20. mysql string
  21. //需替换的参数字段信息
  22. parser *xuguParse
  23. }
  24. /* Collect error information from the database server */
  25. func (self *xuguStmt) get_error() error {
  26. // message := cgo_c_calloc(ERROR_BUFF_SIZE)
  27. // defer func() {
  28. // cgo_c_free(unsafe.Pointer(message))
  29. // }()
  30. // var length C.int
  31. // cgo_xgc_error(&self.stmt_conn, message, &length)
  32. // return errors.New(C.GoString(message))
  33. return errors.New("xuguStmt error")
  34. }
  35. /* {{ */
  36. func (stmt *xuguStmt) Close() error {
  37. fmt.Println("\n>>>>>> (stmt *xuguStmt) Close method called")
  38. return nil
  39. }
  40. func (stmt *xuguStmt) NumInput() int {
  41. fmt.Println("\n>>>>>(stmt *xuguStmt) NumInput()")
  42. parser := &xuguParse{
  43. bind_type: 0,
  44. param_count: 0,
  45. }
  46. fmt.Println("stmt.mysql: ", stmt.mysql)
  47. return parser.assertParamCount(stmt.mysql)
  48. //return 0
  49. }
  50. func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) {
  51. fmt.Println(">>>>>>>Exec method called")
  52. fmt.Println("--args ", args)
  53. // result := &xuguResult{
  54. // affectedRows: 0,
  55. // insertId: 0,
  56. // }
  57. //参数类型绑定
  58. if stmt.paramCount > 0 && len(args) > 0 {
  59. for pos, param := range args {
  60. stmt.parser.assertParamType(param, pos)
  61. //fmt.Printf("Field Name: %s, Field Type: %s, Field Value: %v\n", v1, v1, v1)
  62. }
  63. sockSendPutStatement(stmt.stmt_conn, stmt.prename, &stmt.parser.values, stmt.paramCount)
  64. XGC_Execute(stmt.stmt_conn)
  65. } else {
  66. //最终发送消息给服务器
  67. sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
  68. XGC_Execute(stmt.stmt_conn)
  69. }
  70. //处理服务器返回
  71. stmt.stmt_conn.conn.Read(stmt.stmt_conn.readBuff.buf)
  72. readBuf := &stmt.stmt_conn.readBuff
  73. fmt.Println("Message from server EXEC:", readBuf.buf[readBuf.idx:])
  74. fmt.Println("Message from server EXEC:", string(stmt.stmt_conn.readBuff.buf))
  75. aR, err := parseMsg(readBuf, stmt.stmt_conn)
  76. if err != nil {
  77. return nil, err
  78. }
  79. switch aR.rt {
  80. case insertResult:
  81. fmt.Println("case insertResult:")
  82. return &xuguResult{
  83. affectedRows: int64(0),
  84. insertId: int64(0),
  85. }, nil
  86. case errInfo:
  87. return nil, errors.New(string(aR.e.ErrStr))
  88. case warnInfo:
  89. return nil, errors.New(string(aR.w.WarnStr))
  90. default:
  91. return &xuguResult{
  92. affectedRows: int64(0),
  93. insertId: int64(0),
  94. }, nil
  95. }
  96. // for {
  97. // char := readBuf.peekChar()
  98. // //fmt.Println("Exec 内的 peekChar: ", char)
  99. // switch char {
  100. // case 'K':
  101. // fmt.Println("消息类型为K")
  102. // return result, nil
  103. // case '$':
  104. // readBuf.idx++
  105. // fmt.Println("消息类型为$")
  106. // parseFormArgDescri(readBuf)
  107. // case 'I':
  108. // readBuf.idx++
  109. // fmt.Println("消息类型为I")
  110. // parseInsertResult(readBuf)
  111. // case 'U':
  112. // fmt.Println("消息类型为U")
  113. // readBuf.idx++
  114. // parseUpdateResult(readBuf)
  115. // case 'D':
  116. // fmt.Println("消息类型为D")
  117. // readBuf.idx++
  118. // parseDeleteResult(readBuf)
  119. // case 'E':
  120. // fmt.Println("消息类型为E")
  121. // readBuf.idx++
  122. // pErr, err := parseErrInfo(readBuf)
  123. // if err != nil {
  124. // return nil, err
  125. // }
  126. // // fmt.Println("E ReadBuf : ", readBuf.buf[readBuf.idx:])
  127. // // fmt.Println("E ReadBuf string: ", string(readBuf.buf[readBuf.idx:]))
  128. // stmt.stmt_conn.errStr = pErr.ErrStr
  129. // // char := readBuf.peekChar()
  130. // // fmt.Println("Exec 内的 peekChar: ", char)
  131. // case 'W':
  132. // fmt.Println("消息类型为W")
  133. // readBuf.idx++
  134. // parseWarnInfo(readBuf)
  135. // case 'M':
  136. // fmt.Println("消息类型为M")
  137. // readBuf.idx++
  138. // parseMessage(readBuf)
  139. // }
  140. // //return nil, errors.New("Exec not implemented")
  141. // }
  142. }
  143. func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) {
  144. fmt.Println("\n>>>>>>(stmt *xuguStmt) Query(args []driver.Value) ")
  145. fmt.Println("stmt.mysql: ", stmt.mysql)
  146. if switchSQLType(stmt.mysql) != SQL_SELECT {
  147. return nil, errors.New("The executed SQL statement is not a SELECT")
  148. }
  149. if !stmt.prepared {
  150. return nil, errors.New("SQL statement is not Prepared")
  151. }
  152. parser := &xuguParse{
  153. bind_type: 0,
  154. param_count: 0,
  155. }
  156. //参数绑定
  157. if len(args) != 0 {
  158. for pos, param := range args {
  159. err := parser.assertParamType(param, pos)
  160. if err != nil {
  161. return nil, err
  162. }
  163. }
  164. //fmt.Printf("len(parser.Val) = %d\n , parser.assertParamCount(stmt.mysql) = %d\n", len(parser.Val), parser.assertParamCount(stmt.mysql))
  165. if len(parser.values) != parser.assertParamCount(stmt.mysql) {
  166. return nil, errors.New("The number of parameters does not match")
  167. }
  168. switch parser.assertBindType(stmt.mysql) {
  169. case BIND_PARAM_BY_POS:
  170. fmt.Println("--BIND_PARAM_BY_POS")
  171. for pos, param := range parser.values {
  172. if !param.islob {
  173. fmt.Printf("pos: %d, param %#v \n", pos, param)
  174. stmt.mysql = parser.bindParamByPos(stmt.mysql)
  175. fmt.Println("? 号替换参数后的 sql", stmt.mysql)
  176. }
  177. }
  178. case BIND_PARAM_BY_NAME:
  179. fmt.Println("--BIND_PARAM_BY_NAME")
  180. parser.assertParamName(stmt.mysql)
  181. for pos, param := range parser.values {
  182. if !param.islob {
  183. fmt.Println("pos: ", pos, "param: ", param)
  184. }
  185. }
  186. default:
  187. fmt.Println("default")
  188. }
  189. }
  190. // if len(parser.Val) != parser.assertParamCount(stmt.mysql) {
  191. // return nil, errors.New("The number of parameters does not match")
  192. // }
  193. stmt.stmt_conn.mu.Lock()
  194. //最终发送消息给服务器
  195. sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
  196. XGC_Execute(stmt.stmt_conn)
  197. //----------------处理服务器查询返回
  198. stmt.stmt_conn.conn.Read(stmt.stmt_conn.readBuff.buf)
  199. //fmt.Println("Message from server:", (buffer[:n]))
  200. fmt.Println("Message from server:", string(stmt.stmt_conn.readBuff.buf))
  201. //fmt.Println("\nMessage from server2:", (stmt.stmt_conn.readBuff.buf))
  202. results, err := parseSelectResult(&stmt.stmt_conn.readBuff)
  203. if err != nil {
  204. fmt.Println("parseSelectResult parseSelectResult err", err.Error())
  205. return nil, err
  206. }
  207. a := &xuguRows{
  208. results: results,
  209. prepared: stmt.prepared,
  210. rows_conn: stmt.stmt_conn,
  211. }
  212. fmt.Println("\n>>>>>>stmt Query end==============================================================")
  213. stmt.stmt_conn.mu.Unlock()
  214. return a, nil
  215. }