| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package//// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.//// This Source Code Form is subject to the terms of the Mozilla Public// License, v. 2.0. If a copy of the MPL was not distributed with this file,// You can obtain one at http://mozilla.org/MPL/2.0/.package mysqlimport (	"database/sql/driver"	"io"	"math"	"reflect")type resultSet struct {	columns     []mysqlField	columnNames []string	done        bool}type mysqlRows struct {	mc     *mysqlConn	rs     resultSet	finish func()}type binaryRows struct {	mysqlRows}type textRows struct {	mysqlRows}func (rows *mysqlRows) Columns() []string {	if rows.rs.columnNames != nil {		return rows.rs.columnNames	}	columns := make([]string, len(rows.rs.columns))	if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {		for i := range columns {			if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {				columns[i] = tableName + "." + rows.rs.columns[i].name			} else {				columns[i] = rows.rs.columns[i].name			}		}	} else {		for i := range columns {			columns[i] = rows.rs.columns[i].name		}	}	rows.rs.columnNames = columns	return columns}func (rows *mysqlRows) ColumnTypeDatabaseTypeName(i int) string {	return rows.rs.columns[i].typeDatabaseName()}// func (rows *mysqlRows) ColumnTypeLength(i int) (length int64, ok bool) {// 	return int64(rows.rs.columns[i].length), true// }func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {	return rows.rs.columns[i].flags&flagNotNULL == 0, true}func (rows *mysqlRows) ColumnTypePrecisionScale(i int) (int64, int64, bool) {	column := rows.rs.columns[i]	decimals := int64(column.decimals)	switch column.fieldType {	case fieldTypeDecimal, fieldTypeNewDecimal:		if decimals > 0 {			return int64(column.length) - 2, decimals, true		}		return int64(column.length) - 1, decimals, true	case fieldTypeTimestamp, fieldTypeDateTime, fieldTypeTime:		return decimals, decimals, true	case fieldTypeFloat, fieldTypeDouble:		if decimals == 0x1f {			return math.MaxInt64, math.MaxInt64, true		}		return math.MaxInt64, decimals, true	}	return 0, 0, false}func (rows *mysqlRows) ColumnTypeScanType(i int) reflect.Type {	return rows.rs.columns[i].scanType()}func (rows *mysqlRows) Close() (err error) {	if f := rows.finish; f != nil {		f()		rows.finish = nil	}	mc := rows.mc	if mc == nil {		return nil	}	if err := mc.error(); err != nil {		return err	}	// Remove unread packets from stream	if !rows.rs.done {		err = mc.readUntilEOF()	}	if err == nil {		if err = mc.discardResults(); err != nil {			return err		}	}	rows.mc = nil	return err}func (rows *mysqlRows) HasNextResultSet() (b bool) {	if rows.mc == nil {		return false	}	return rows.mc.status&statusMoreResultsExists != 0}func (rows *mysqlRows) nextResultSet() (int, error) {	if rows.mc == nil {		return 0, io.EOF	}	if err := rows.mc.error(); err != nil {		return 0, err	}	// Remove unread packets from stream	if !rows.rs.done {		if err := rows.mc.readUntilEOF(); err != nil {			return 0, err		}		rows.rs.done = true	}	if !rows.HasNextResultSet() {		rows.mc = nil		return 0, io.EOF	}	rows.rs = resultSet{}	return rows.mc.readResultSetHeaderPacket()}func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {	for {		resLen, err := rows.nextResultSet()		if err != nil {			return 0, err		}		if resLen > 0 {			return resLen, nil		}		rows.rs.done = true	}}func (rows *binaryRows) NextResultSet() error {	resLen, err := rows.nextNotEmptyResultSet()	if err != nil {		return err	}	rows.rs.columns, err = rows.mc.readColumns(resLen)	return err}func (rows *binaryRows) Next(dest []driver.Value) error {	if mc := rows.mc; mc != nil {		if err := mc.error(); err != nil {			return err		}		// Fetch next row from stream		return rows.readRow(dest)	}	return io.EOF}func (rows *textRows) NextResultSet() (err error) {	resLen, err := rows.nextNotEmptyResultSet()	if err != nil {		return err	}	rows.rs.columns, err = rows.mc.readColumns(resLen)	return err}func (rows *textRows) Next(dest []driver.Value) error {	if mc := rows.mc; mc != nil {		if err := mc.error(); err != nil {			return err		}		// Fetch next row from stream		return rows.readRow(dest)	}	return io.EOF}
 |