xugu_stmt.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package xugu
  2. import (
  3. "database/sql/driver"
  4. "encoding/binary"
  5. "errors"
  6. )
  7. type xuguStmt struct {
  8. stmt_conn *xuguConn
  9. prepared bool
  10. prename []byte
  11. // 布尔值,用于标识游标是否启用
  12. curopend bool
  13. // 游标名称
  14. curname []byte
  15. // 执行的 SQL 语句中的参数数量
  16. paramCount int
  17. mysql string
  18. //需替换的参数字段信息
  19. //parser *xuguParse
  20. }
  21. func (stmt *xuguStmt) Close() error {
  22. //关闭 prepare
  23. err := xuguUnPrepare(stmt.stmt_conn, stmt.stmt_conn.prepareName)
  24. //释放资源
  25. return err
  26. }
  27. func (stmt *xuguStmt) NumInput() int {
  28. return assertParamCount(stmt.mysql)
  29. //return 0
  30. }
  31. func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) {
  32. stmt.stmt_conn.mu.Lock()
  33. defer stmt.stmt_conn.mu.Unlock()
  34. //send msg
  35. //如果有参数
  36. if stmt.paramCount > 0 && len(args) > 0 {
  37. values := []xuguValue{}
  38. for _, param := range args {
  39. assertParamType(param, &values)
  40. }
  41. sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount)
  42. sockSendExecute(stmt.stmt_conn)
  43. //没有参数
  44. } else {
  45. sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
  46. sockSendExecute(stmt.stmt_conn)
  47. }
  48. //recv msg
  49. aR, err := xuguSockRecvMsg(stmt.stmt_conn)
  50. if err != nil {
  51. return nil, err
  52. }
  53. switch aR.rt {
  54. case selectResult:
  55. return nil, errors.New("exec is Query error")
  56. case updateResult:
  57. return &xuguResult{xgConn: stmt.stmt_conn, affectedRows: int64(aR.u.UpdateNum), insertId: int64(0)}, nil
  58. case insertResult:
  59. return &xuguResult{xgConn: stmt.stmt_conn, affectedRows: int64(aR.i.EffectNum), insertId: int64(binary.LittleEndian.Uint64(aR.i.RowidData))}, nil
  60. case errInfo:
  61. return nil, errors.New(string(aR.e.ErrStr))
  62. case warnInfo:
  63. return nil, errors.New(string(aR.w.WarnStr))
  64. default:
  65. return &xuguResult{
  66. xgConn: stmt.stmt_conn,
  67. affectedRows: int64(0),
  68. insertId: int64(0),
  69. }, nil
  70. }
  71. }
  72. func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) {
  73. stmt.stmt_conn.mu.Lock()
  74. defer stmt.stmt_conn.mu.Unlock()
  75. //send msg
  76. //如果有参数
  77. if stmt.paramCount > 0 && len(args) > 0 {
  78. values := []xuguValue{}
  79. for _, param := range args {
  80. assertParamType(param, &values)
  81. }
  82. sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount)
  83. sockSendExecute(stmt.stmt_conn)
  84. //没有参数
  85. } else {
  86. sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
  87. sockSendExecute(stmt.stmt_conn)
  88. }
  89. //recv msg
  90. aR, err := xuguSockRecvMsg(stmt.stmt_conn)
  91. if err != nil {
  92. return nil, err
  93. }
  94. switch aR.rt {
  95. case selectResult:
  96. rows := &xuguRows{
  97. rows_conn: stmt.stmt_conn,
  98. results: aR.s,
  99. colIdx: 0,
  100. prepared: false,
  101. }
  102. return rows, nil
  103. case errInfo:
  104. return nil, errors.New(string(aR.e.ErrStr))
  105. case warnInfo:
  106. return nil, errors.New(string(aR.w.WarnStr))
  107. default:
  108. }
  109. return nil, errors.New("xugu Query error")
  110. }