forked from ebhomengo/niki
1
0
Fork 0
niki/vendor/github.com/go-sql-driver/mysql/rows.go

361 lines
4.8 KiB
Go
Raw Normal View History

2024-02-18 10:42:21 +00:00
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2024-02-18 10:42:21 +00:00
//
2024-02-18 10:42:21 +00:00
// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
2024-02-18 10:42:21 +00:00
//
2024-02-18 10:42:21 +00:00
// This Source Code Form is subject to the terms of the Mozilla Public
2024-02-18 10:42:21 +00:00
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
2024-02-18 10:42:21 +00:00
// You can obtain one at http://mozilla.org/MPL/2.0/.
package mysql
import (
"database/sql/driver"
"io"
"math"
"reflect"
)
type resultSet struct {
columns []mysqlField
2024-02-18 10:42:21 +00:00
columnNames []string
done bool
2024-02-18 10:42:21 +00:00
}
type mysqlRows struct {
mc *mysqlConn
rs resultSet
2024-02-18 10:42:21 +00:00
finish func()
}
type binaryRows struct {
mysqlRows
}
type textRows struct {
mysqlRows
}
func (rows *mysqlRows) Columns() []string {
2024-02-18 10:42:21 +00:00
if rows.rs.columnNames != nil {
2024-02-18 10:42:21 +00:00
return rows.rs.columnNames
2024-02-18 10:42:21 +00:00
}
columns := make([]string, len(rows.rs.columns))
2024-02-18 10:42:21 +00:00
if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
2024-02-18 10:42:21 +00:00
for i := range columns {
2024-02-18 10:42:21 +00:00
if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {
2024-02-18 10:42:21 +00:00
columns[i] = tableName + "." + rows.rs.columns[i].name
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
columns[i] = rows.rs.columns[i].name
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
for i := range columns {
2024-02-18 10:42:21 +00:00
columns[i] = rows.rs.columns[i].name
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
rows.rs.columnNames = columns
2024-02-18 10:42:21 +00:00
return columns
2024-02-18 10:42:21 +00:00
}
func (rows *mysqlRows) ColumnTypeDatabaseTypeName(i int) string {
2024-02-18 10:42:21 +00:00
return rows.rs.columns[i].typeDatabaseName()
2024-02-18 10:42:21 +00:00
}
// func (rows *mysqlRows) ColumnTypeLength(i int) (length int64, ok bool) {
2024-02-18 10:42:21 +00:00
// return int64(rows.rs.columns[i].length), true
2024-02-18 10:42:21 +00:00
// }
func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
2024-02-18 10:42:21 +00:00
return rows.rs.columns[i].flags&flagNotNULL == 0, true
2024-02-18 10:42:21 +00:00
}
func (rows *mysqlRows) ColumnTypePrecisionScale(i int) (int64, int64, bool) {
2024-02-18 10:42:21 +00:00
column := rows.rs.columns[i]
2024-02-18 10:42:21 +00:00
decimals := int64(column.decimals)
switch column.fieldType {
2024-02-18 10:42:21 +00:00
case fieldTypeDecimal, fieldTypeNewDecimal:
2024-02-18 10:42:21 +00:00
if decimals > 0 {
2024-02-18 10:42:21 +00:00
return int64(column.length) - 2, decimals, true
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return int64(column.length) - 1, decimals, true
2024-02-18 10:42:21 +00:00
case fieldTypeTimestamp, fieldTypeDateTime, fieldTypeTime:
2024-02-18 10:42:21 +00:00
return decimals, decimals, true
2024-02-18 10:42:21 +00:00
case fieldTypeFloat, fieldTypeDouble:
2024-02-18 10:42:21 +00:00
if decimals == 0x1f {
2024-02-18 10:42:21 +00:00
return math.MaxInt64, math.MaxInt64, true
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return math.MaxInt64, decimals, true
2024-02-18 10:42:21 +00:00
}
return 0, 0, false
2024-02-18 10:42:21 +00:00
}
func (rows *mysqlRows) ColumnTypeScanType(i int) reflect.Type {
2024-02-18 10:42:21 +00:00
return rows.rs.columns[i].scanType()
2024-02-18 10:42:21 +00:00
}
func (rows *mysqlRows) Close() (err error) {
2024-02-18 10:42:21 +00:00
if f := rows.finish; f != nil {
2024-02-18 10:42:21 +00:00
f()
2024-02-18 10:42:21 +00:00
rows.finish = nil
2024-02-18 10:42:21 +00:00
}
mc := rows.mc
2024-02-18 10:42:21 +00:00
if mc == nil {
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if err := mc.error(); err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
// flip the buffer for this connection if we need to drain it.
2024-02-18 10:42:21 +00:00
// note that for a successful query (i.e. one where rows.next()
2024-02-18 10:42:21 +00:00
// has been called until it returns false), `rows.mc` will be nil
2024-02-18 10:42:21 +00:00
// by the time the user calls `(*Rows).Close`, so we won't reach this
2024-02-18 10:42:21 +00:00
// see: https://github.com/golang/go/commit/651ddbdb5056ded455f47f9c494c67b389622a47
2024-02-18 10:42:21 +00:00
mc.buf.flip()
// Remove unread packets from stream
2024-02-18 10:42:21 +00:00
if !rows.rs.done {
2024-02-18 10:42:21 +00:00
err = mc.readUntilEOF()
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if err == nil {
2024-02-18 10:42:21 +00:00
if err = mc.discardResults(); err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
rows.mc = nil
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
func (rows *mysqlRows) HasNextResultSet() (b bool) {
2024-02-18 10:42:21 +00:00
if rows.mc == nil {
2024-02-18 10:42:21 +00:00
return false
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return rows.mc.status&statusMoreResultsExists != 0
2024-02-18 10:42:21 +00:00
}
func (rows *mysqlRows) nextResultSet() (int, error) {
2024-02-18 10:42:21 +00:00
if rows.mc == nil {
2024-02-18 10:42:21 +00:00
return 0, io.EOF
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if err := rows.mc.error(); err != nil {
2024-02-18 10:42:21 +00:00
return 0, err
2024-02-18 10:42:21 +00:00
}
// Remove unread packets from stream
2024-02-18 10:42:21 +00:00
if !rows.rs.done {
2024-02-18 10:42:21 +00:00
if err := rows.mc.readUntilEOF(); err != nil {
2024-02-18 10:42:21 +00:00
return 0, err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
rows.rs.done = true
2024-02-18 10:42:21 +00:00
}
if !rows.HasNextResultSet() {
2024-02-18 10:42:21 +00:00
rows.mc = nil
2024-02-18 10:42:21 +00:00
return 0, io.EOF
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
rows.rs = resultSet{}
2024-02-18 10:42:21 +00:00
return rows.mc.readResultSetHeaderPacket()
2024-02-18 10:42:21 +00:00
}
func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
2024-02-18 10:42:21 +00:00
for {
2024-02-18 10:42:21 +00:00
resLen, err := rows.nextResultSet()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return 0, err
2024-02-18 10:42:21 +00:00
}
if resLen > 0 {
2024-02-18 10:42:21 +00:00
return resLen, nil
2024-02-18 10:42:21 +00:00
}
rows.rs.done = true
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
func (rows *binaryRows) NextResultSet() error {
2024-02-18 10:42:21 +00:00
resLen, err := rows.nextNotEmptyResultSet()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
rows.rs.columns, err = rows.mc.readColumns(resLen)
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
func (rows *binaryRows) Next(dest []driver.Value) error {
2024-02-18 10:42:21 +00:00
if mc := rows.mc; mc != nil {
2024-02-18 10:42:21 +00:00
if err := mc.error(); err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
// Fetch next row from stream
2024-02-18 10:42:21 +00:00
return rows.readRow(dest)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return io.EOF
2024-02-18 10:42:21 +00:00
}
func (rows *textRows) NextResultSet() (err error) {
2024-02-18 10:42:21 +00:00
resLen, err := rows.nextNotEmptyResultSet()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
rows.rs.columns, err = rows.mc.readColumns(resLen)
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
func (rows *textRows) Next(dest []driver.Value) error {
2024-02-18 10:42:21 +00:00
if mc := rows.mc; mc != nil {
2024-02-18 10:42:21 +00:00
if err := mc.error(); err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
// Fetch next row from stream
2024-02-18 10:42:21 +00:00
return rows.readRow(dest)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return io.EOF
2024-02-18 10:42:21 +00:00
}