You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
4.3 KiB

  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. "math"
  13. "reflect"
  14. )
  15. type resultSet struct {
  16. columns []mysqlField
  17. columnNames []string
  18. done bool
  19. }
  20. type mysqlRows struct {
  21. mc *mysqlConn
  22. rs resultSet
  23. finish func()
  24. }
  25. type binaryRows struct {
  26. mysqlRows
  27. }
  28. type textRows struct {
  29. mysqlRows
  30. }
  31. func (rows *mysqlRows) Columns() []string {
  32. if rows.rs.columnNames != nil {
  33. return rows.rs.columnNames
  34. }
  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. rows.rs.columnNames = columns
  50. return columns
  51. }
  52. func (rows *mysqlRows) ColumnTypeDatabaseTypeName(i int) string {
  53. return rows.rs.columns[i].typeDatabaseName()
  54. }
  55. // func (rows *mysqlRows) ColumnTypeLength(i int) (length int64, ok bool) {
  56. // return int64(rows.rs.columns[i].length), true
  57. // }
  58. func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
  59. return rows.rs.columns[i].flags&flagNotNULL == 0, true
  60. }
  61. func (rows *mysqlRows) ColumnTypePrecisionScale(i int) (int64, int64, bool) {
  62. column := rows.rs.columns[i]
  63. decimals := int64(column.decimals)
  64. switch column.fieldType {
  65. case fieldTypeDecimal, fieldTypeNewDecimal:
  66. if decimals > 0 {
  67. return int64(column.length) - 2, decimals, true
  68. }
  69. return int64(column.length) - 1, decimals, true
  70. case fieldTypeTimestamp, fieldTypeDateTime, fieldTypeTime:
  71. return decimals, decimals, true
  72. case fieldTypeFloat, fieldTypeDouble:
  73. if decimals == 0x1f {
  74. return math.MaxInt64, math.MaxInt64, true
  75. }
  76. return math.MaxInt64, decimals, true
  77. }
  78. return 0, 0, false
  79. }
  80. func (rows *mysqlRows) ColumnTypeScanType(i int) reflect.Type {
  81. return rows.rs.columns[i].scanType()
  82. }
  83. func (rows *mysqlRows) Close() (err error) {
  84. if f := rows.finish; f != nil {
  85. f()
  86. rows.finish = nil
  87. }
  88. mc := rows.mc
  89. if mc == nil {
  90. return nil
  91. }
  92. if err := mc.error(); err != nil {
  93. return err
  94. }
  95. // Remove unread packets from stream
  96. if !rows.rs.done {
  97. err = mc.readUntilEOF()
  98. }
  99. if err == nil {
  100. if err = mc.discardResults(); err != nil {
  101. return err
  102. }
  103. }
  104. rows.mc = nil
  105. return err
  106. }
  107. func (rows *mysqlRows) HasNextResultSet() (b bool) {
  108. if rows.mc == nil {
  109. return false
  110. }
  111. return rows.mc.status&statusMoreResultsExists != 0
  112. }
  113. func (rows *mysqlRows) nextResultSet() (int, error) {
  114. if rows.mc == nil {
  115. return 0, io.EOF
  116. }
  117. if err := rows.mc.error(); err != nil {
  118. return 0, err
  119. }
  120. // Remove unread packets from stream
  121. if !rows.rs.done {
  122. if err := rows.mc.readUntilEOF(); err != nil {
  123. return 0, err
  124. }
  125. rows.rs.done = true
  126. }
  127. if !rows.HasNextResultSet() {
  128. rows.mc = nil
  129. return 0, io.EOF
  130. }
  131. rows.rs = resultSet{}
  132. return rows.mc.readResultSetHeaderPacket()
  133. }
  134. func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
  135. for {
  136. resLen, err := rows.nextResultSet()
  137. if err != nil {
  138. return 0, err
  139. }
  140. if resLen > 0 {
  141. return resLen, nil
  142. }
  143. rows.rs.done = true
  144. }
  145. }
  146. func (rows *binaryRows) NextResultSet() error {
  147. resLen, err := rows.nextNotEmptyResultSet()
  148. if err != nil {
  149. return err
  150. }
  151. rows.rs.columns, err = rows.mc.readColumns(resLen)
  152. return err
  153. }
  154. func (rows *binaryRows) Next(dest []driver.Value) error {
  155. if mc := rows.mc; mc != nil {
  156. if err := mc.error(); err != nil {
  157. return err
  158. }
  159. // Fetch next row from stream
  160. return rows.readRow(dest)
  161. }
  162. return io.EOF
  163. }
  164. func (rows *textRows) NextResultSet() (err error) {
  165. resLen, err := rows.nextNotEmptyResultSet()
  166. if err != nil {
  167. return err
  168. }
  169. rows.rs.columns, err = rows.mc.readColumns(resLen)
  170. return err
  171. }
  172. func (rows *textRows) Next(dest []driver.Value) error {
  173. if mc := rows.mc; mc != nil {
  174. if err := mc.error(); err != nil {
  175. return err
  176. }
  177. // Fetch next row from stream
  178. return rows.readRow(dest)
  179. }
  180. return io.EOF
  181. }