rows.go 3.1 KB

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