xugu_stmt.go 2.9 KB

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