rows.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public
  6. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  7. // You can obtain one at http://mozilla.org/MPL/2.0/.
  8. package mysql
  9. import (
  10. "database/sql/driver"
  11. "io"
  12. )
  13. type mysqlField struct {
  14. tableName string
  15. name string
  16. flags fieldFlag
  17. fieldType byte
  18. decimals byte
  19. }
  20. type resultSet struct {
  21. columns []mysqlField
  22. done bool
  23. }
  24. type mysqlRows struct {
  25. mc *mysqlConn
  26. rs resultSet
  27. }
  28. type binaryRows struct {
  29. mysqlRows
  30. // stmtCols is a pointer to the statement's cached columns for different
  31. // result sets.
  32. stmtCols *[][]mysqlField
  33. // i is a number of the current result set. It is used to fetch proper
  34. // columns from stmtCols.
  35. i int
  36. }
  37. type textRows struct {
  38. mysqlRows
  39. }
  40. func (rows *mysqlRows) Columns() []string {
  41. columns := make([]string, len(rows.rs.columns))
  42. if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
  43. for i := range columns {
  44. if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {
  45. columns[i] = tableName + "." + rows.rs.columns[i].name
  46. } else {
  47. columns[i] = rows.rs.columns[i].name
  48. }
  49. }
  50. } else {
  51. for i := range columns {
  52. columns[i] = rows.rs.columns[i].name
  53. }
  54. }
  55. return columns
  56. }
  57. func (rows *mysqlRows) Close() (err error) {
  58. mc := rows.mc
  59. if mc == nil {
  60. return nil
  61. }
  62. if mc.netConn == nil {
  63. return ErrInvalidConn
  64. }
  65. // Remove unread packets from stream
  66. if !rows.rs.done {
  67. err = mc.readUntilEOF()
  68. }
  69. if err == nil {
  70. if err = mc.discardResults(); err != nil {
  71. return err
  72. }
  73. }
  74. rows.mc = nil
  75. return err
  76. }
  77. func (rows *mysqlRows) HasNextResultSet() (b bool) {
  78. if rows.mc == nil {
  79. return false
  80. }
  81. return rows.mc.status&statusMoreResultsExists != 0
  82. }
  83. func (rows *mysqlRows) nextResultSet() (int, error) {
  84. if rows.mc == nil {
  85. return 0, io.EOF
  86. }
  87. if rows.mc.netConn == nil {
  88. return 0, ErrInvalidConn
  89. }
  90. // Remove unread packets from stream
  91. if !rows.rs.done {
  92. if err := rows.mc.readUntilEOF(); err != nil {
  93. return 0, err
  94. }
  95. rows.rs.done = true
  96. }
  97. if !rows.HasNextResultSet() {
  98. rows.mc = nil
  99. return 0, io.EOF
  100. }
  101. rows.rs = resultSet{}
  102. return rows.mc.readResultSetHeaderPacket()
  103. }
  104. func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
  105. for {
  106. resLen, err := rows.nextResultSet()
  107. if err != nil {
  108. return 0, err
  109. }
  110. if resLen > 0 {
  111. return resLen, nil
  112. }
  113. rows.rs.done = true
  114. }
  115. }
  116. func (rows *binaryRows) NextResultSet() (err error) {
  117. resLen, err := rows.nextNotEmptyResultSet()
  118. if err != nil {
  119. return err
  120. }
  121. // get columns, if not cached, read them and cache them.
  122. if rows.i >= len(*rows.stmtCols) {
  123. rows.rs.columns, err = rows.mc.readColumns(resLen)
  124. *rows.stmtCols = append(*rows.stmtCols, rows.rs.columns)
  125. } else {
  126. rows.rs.columns = (*rows.stmtCols)[rows.i]
  127. if err := rows.mc.readUntilEOF(); err != nil {
  128. return err
  129. }
  130. }
  131. rows.i++
  132. return nil
  133. }
  134. func (rows *binaryRows) Next(dest []driver.Value) error {
  135. if mc := rows.mc; mc != nil {
  136. if mc.netConn == nil {
  137. return ErrInvalidConn
  138. }
  139. // Fetch next row from stream
  140. return rows.readRow(dest)
  141. }
  142. return io.EOF
  143. }
  144. func (rows *textRows) NextResultSet() (err error) {
  145. resLen, err := rows.nextNotEmptyResultSet()
  146. if err != nil {
  147. return err
  148. }
  149. rows.rs.columns, err = rows.mc.readColumns(resLen)
  150. return err
  151. }
  152. func (rows *textRows) Next(dest []driver.Value) error {
  153. if mc := rows.mc; mc != nil {
  154. if mc.netConn == nil {
  155. return ErrInvalidConn
  156. }
  157. // Fetch next row from stream
  158. return rows.readRow(dest)
  159. }
  160. return io.EOF
  161. }