OSDN Git Service

feat: init cross_tx keepers (#146)
[bytom/vapor.git] / vendor / github.com / go-sql-driver / mysql / rows.go
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
9 package mysql
10
11 import (
12         "database/sql/driver"
13         "io"
14         "math"
15         "reflect"
16 )
17
18 type resultSet struct {
19         columns     []mysqlField
20         columnNames []string
21         done        bool
22 }
23
24 type mysqlRows struct {
25         mc     *mysqlConn
26         rs     resultSet
27         finish func()
28 }
29
30 type binaryRows struct {
31         mysqlRows
32 }
33
34 type textRows struct {
35         mysqlRows
36 }
37
38 func (rows *mysqlRows) Columns() []string {
39         if rows.rs.columnNames != nil {
40                 return rows.rs.columnNames
41         }
42
43         columns := make([]string, len(rows.rs.columns))
44         if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
45                 for i := range columns {
46                         if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {
47                                 columns[i] = tableName + "." + rows.rs.columns[i].name
48                         } else {
49                                 columns[i] = rows.rs.columns[i].name
50                         }
51                 }
52         } else {
53                 for i := range columns {
54                         columns[i] = rows.rs.columns[i].name
55                 }
56         }
57
58         rows.rs.columnNames = columns
59         return columns
60 }
61
62 func (rows *mysqlRows) ColumnTypeDatabaseTypeName(i int) string {
63         return rows.rs.columns[i].typeDatabaseName()
64 }
65
66 // func (rows *mysqlRows) ColumnTypeLength(i int) (length int64, ok bool) {
67 //      return int64(rows.rs.columns[i].length), true
68 // }
69
70 func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
71         return rows.rs.columns[i].flags&flagNotNULL == 0, true
72 }
73
74 func (rows *mysqlRows) ColumnTypePrecisionScale(i int) (int64, int64, bool) {
75         column := rows.rs.columns[i]
76         decimals := int64(column.decimals)
77
78         switch column.fieldType {
79         case fieldTypeDecimal, fieldTypeNewDecimal:
80                 if decimals > 0 {
81                         return int64(column.length) - 2, decimals, true
82                 }
83                 return int64(column.length) - 1, decimals, true
84         case fieldTypeTimestamp, fieldTypeDateTime, fieldTypeTime:
85                 return decimals, decimals, true
86         case fieldTypeFloat, fieldTypeDouble:
87                 if decimals == 0x1f {
88                         return math.MaxInt64, math.MaxInt64, true
89                 }
90                 return math.MaxInt64, decimals, true
91         }
92
93         return 0, 0, false
94 }
95
96 func (rows *mysqlRows) ColumnTypeScanType(i int) reflect.Type {
97         return rows.rs.columns[i].scanType()
98 }
99
100 func (rows *mysqlRows) Close() (err error) {
101         if f := rows.finish; f != nil {
102                 f()
103                 rows.finish = nil
104         }
105
106         mc := rows.mc
107         if mc == nil {
108                 return nil
109         }
110         if err := mc.error(); err != nil {
111                 return err
112         }
113
114         // Remove unread packets from stream
115         if !rows.rs.done {
116                 err = mc.readUntilEOF()
117         }
118         if err == nil {
119                 if err = mc.discardResults(); err != nil {
120                         return err
121                 }
122         }
123
124         rows.mc = nil
125         return err
126 }
127
128 func (rows *mysqlRows) HasNextResultSet() (b bool) {
129         if rows.mc == nil {
130                 return false
131         }
132         return rows.mc.status&statusMoreResultsExists != 0
133 }
134
135 func (rows *mysqlRows) nextResultSet() (int, error) {
136         if rows.mc == nil {
137                 return 0, io.EOF
138         }
139         if err := rows.mc.error(); err != nil {
140                 return 0, err
141         }
142
143         // Remove unread packets from stream
144         if !rows.rs.done {
145                 if err := rows.mc.readUntilEOF(); err != nil {
146                         return 0, err
147                 }
148                 rows.rs.done = true
149         }
150
151         if !rows.HasNextResultSet() {
152                 rows.mc = nil
153                 return 0, io.EOF
154         }
155         rows.rs = resultSet{}
156         return rows.mc.readResultSetHeaderPacket()
157 }
158
159 func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
160         for {
161                 resLen, err := rows.nextResultSet()
162                 if err != nil {
163                         return 0, err
164                 }
165
166                 if resLen > 0 {
167                         return resLen, nil
168                 }
169
170                 rows.rs.done = true
171         }
172 }
173
174 func (rows *binaryRows) NextResultSet() error {
175         resLen, err := rows.nextNotEmptyResultSet()
176         if err != nil {
177                 return err
178         }
179
180         rows.rs.columns, err = rows.mc.readColumns(resLen)
181         return err
182 }
183
184 func (rows *binaryRows) Next(dest []driver.Value) error {
185         if mc := rows.mc; mc != nil {
186                 if err := mc.error(); err != nil {
187                         return err
188                 }
189
190                 // Fetch next row from stream
191                 return rows.readRow(dest)
192         }
193         return io.EOF
194 }
195
196 func (rows *textRows) NextResultSet() (err error) {
197         resLen, err := rows.nextNotEmptyResultSet()
198         if err != nil {
199                 return err
200         }
201
202         rows.rs.columns, err = rows.mc.readColumns(resLen)
203         return err
204 }
205
206 func (rows *textRows) Next(dest []driver.Value) error {
207         if mc := rows.mc; mc != nil {
208                 if err := mc.error(); err != nil {
209                         return err
210                 }
211
212                 // Fetch next row from stream
213                 return rows.readRow(dest)
214         }
215         return io.EOF
216 }