rows.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. columnNames []string
  23. done bool
  24. }
  25. type mysqlRows struct {
  26. mc *mysqlConn
  27. rs resultSet
  28. finish func()
  29. }
  30. type binaryRows struct {
  31. mysqlRows
  32. }
  33. type textRows struct {
  34. mysqlRows
  35. }
  36. func (rows *mysqlRows) Columns() []string {
  37. if rows.rs.columnNames != nil {
  38. return rows.rs.columnNames
  39. }
  40. columns := make([]string, len(rows.rs.columns))
  41. if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
  42. for i := range columns {
  43. if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {
  44. columns[i] = tableName + "." + rows.rs.columns[i].name
  45. } else {
  46. columns[i] = rows.rs.columns[i].name
  47. }
  48. }
  49. } else {
  50. for i := range columns {
  51. columns[i] = rows.rs.columns[i].name
  52. }
  53. }
  54. rows.rs.columnNames = columns
  55. return columns
  56. }
  57. func (rows *mysqlRows) Close() (err error) {
  58. if f := rows.finish; f != nil {
  59. f()
  60. rows.finish = nil
  61. }
  62. mc := rows.mc
  63. if mc == nil {
  64. return nil
  65. }
  66. if err := mc.error(); err != nil {
  67. return err
  68. }
  69. // Remove unread packets from stream
  70. if !rows.rs.done {
  71. err = mc.readUntilEOF()
  72. }
  73. if err == nil {
  74. if err = mc.discardResults(); err != nil {
  75. return err
  76. }
  77. }
  78. rows.mc = nil
  79. return err
  80. }
  81. func (rows *mysqlRows) HasNextResultSet() (b bool) {
  82. if rows.mc == nil {
  83. return false
  84. }
  85. return rows.mc.status&statusMoreResultsExists != 0
  86. }
  87. func (rows *mysqlRows) nextResultSet() (int, error) {
  88. if rows.mc == nil {
  89. return 0, io.EOF
  90. }
  91. if err := rows.mc.error(); err != nil {
  92. return 0, err
  93. }
  94. // Remove unread packets from stream
  95. if !rows.rs.done {
  96. if err := rows.mc.readUntilEOF(); err != nil {
  97. return 0, err
  98. }
  99. rows.rs.done = true
  100. }
  101. if !rows.HasNextResultSet() {
  102. rows.mc = nil
  103. return 0, io.EOF
  104. }
  105. rows.rs = resultSet{}
  106. return rows.mc.readResultSetHeaderPacket()
  107. }
  108. func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
  109. for {
  110. resLen, err := rows.nextResultSet()
  111. if err != nil {
  112. return 0, err
  113. }
  114. if resLen > 0 {
  115. return resLen, nil
  116. }
  117. rows.rs.done = true
  118. }
  119. }
  120. func (rows *binaryRows) NextResultSet() error {
  121. resLen, err := rows.nextNotEmptyResultSet()
  122. if err != nil {
  123. return err
  124. }
  125. rows.rs.columns, err = rows.mc.readColumns(resLen)
  126. return err
  127. }
  128. func (rows *binaryRows) Next(dest []driver.Value) error {
  129. if mc := rows.mc; mc != nil {
  130. if err := mc.error(); err != nil {
  131. return err
  132. }
  133. // Fetch next row from stream
  134. return rows.readRow(dest)
  135. }
  136. return io.EOF
  137. }
  138. func (rows *textRows) NextResultSet() (err error) {
  139. resLen, err := rows.nextNotEmptyResultSet()
  140. if err != nil {
  141. return err
  142. }
  143. rows.rs.columns, err = rows.mc.readColumns(resLen)
  144. return err
  145. }
  146. func (rows *textRows) Next(dest []driver.Value) error {
  147. if mc := rows.mc; mc != nil {
  148. if err := mc.error(); err != nil {
  149. return err
  150. }
  151. // Fetch next row from stream
  152. return rows.readRow(dest)
  153. }
  154. return io.EOF
  155. }