github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/go-sql-driver/mysql/rows.go (about)

     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  	// flip the buffer for this connection if we need to drain it.
   115  	// note that for a successful query (i.e. one where rows.next()
   116  	// has been called until it returns false), `rows.mc` will be nil
   117  	// by the time the user calls `(*Rows).Close`, so we won't reach this
   118  	// see: https://github.com/golang/go/commit/651ddbdb5056ded455f47f9c494c67b389622a47
   119  	mc.buf.flip()
   120  
   121  	// Remove unread packets from stream
   122  	if !rows.rs.done {
   123  		err = mc.readUntilEOF()
   124  	}
   125  	if err == nil {
   126  		if err = mc.discardResults(); err != nil {
   127  			return err
   128  		}
   129  	}
   130  
   131  	rows.mc = nil
   132  	return err
   133  }
   134  
   135  func (rows *mysqlRows) HasNextResultSet() (b bool) {
   136  	if rows.mc == nil {
   137  		return false
   138  	}
   139  	return rows.mc.status&statusMoreResultsExists != 0
   140  }
   141  
   142  func (rows *mysqlRows) nextResultSet() (int, error) {
   143  	if rows.mc == nil {
   144  		return 0, io.EOF
   145  	}
   146  	if err := rows.mc.error(); err != nil {
   147  		return 0, err
   148  	}
   149  
   150  	// Remove unread packets from stream
   151  	if !rows.rs.done {
   152  		if err := rows.mc.readUntilEOF(); err != nil {
   153  			return 0, err
   154  		}
   155  		rows.rs.done = true
   156  	}
   157  
   158  	if !rows.HasNextResultSet() {
   159  		rows.mc = nil
   160  		return 0, io.EOF
   161  	}
   162  	rows.rs = resultSet{}
   163  	return rows.mc.readResultSetHeaderPacket()
   164  }
   165  
   166  func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
   167  	for {
   168  		resLen, err := rows.nextResultSet()
   169  		if err != nil {
   170  			return 0, err
   171  		}
   172  
   173  		if resLen > 0 {
   174  			return resLen, nil
   175  		}
   176  
   177  		rows.rs.done = true
   178  	}
   179  }
   180  
   181  func (rows *binaryRows) NextResultSet() error {
   182  	resLen, err := rows.nextNotEmptyResultSet()
   183  	if err != nil {
   184  		return err
   185  	}
   186  
   187  	rows.rs.columns, err = rows.mc.readColumns(resLen)
   188  	return err
   189  }
   190  
   191  func (rows *binaryRows) Next(dest []driver.Value) error {
   192  	if mc := rows.mc; mc != nil {
   193  		if err := mc.error(); err != nil {
   194  			return err
   195  		}
   196  
   197  		// Fetch next row from stream
   198  		return rows.readRow(dest)
   199  	}
   200  	return io.EOF
   201  }
   202  
   203  func (rows *textRows) NextResultSet() (err error) {
   204  	resLen, err := rows.nextNotEmptyResultSet()
   205  	if err != nil {
   206  		return err
   207  	}
   208  
   209  	rows.rs.columns, err = rows.mc.readColumns(resLen)
   210  	return err
   211  }
   212  
   213  func (rows *textRows) Next(dest []driver.Value) error {
   214  	if mc := rows.mc; mc != nil {
   215  		if err := mc.error(); err != nil {
   216  			return err
   217  		}
   218  
   219  		// Fetch next row from stream
   220  		return rows.readRow(dest)
   221  	}
   222  	return io.EOF
   223  }