// 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 mysql

import (
	
	
	
	
)

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 ( *mysqlRows) () []string {
	if .rs.columnNames != nil {
		return .rs.columnNames
	}

	 := make([]string, len(.rs.columns))
	if .mc != nil && .mc.cfg.ColumnsWithAlias {
		for  := range  {
			if  := .rs.columns[].tableName; len() > 0 {
				[] =  + "." + .rs.columns[].name
			} else {
				[] = .rs.columns[].name
			}
		}
	} else {
		for  := range  {
			[] = .rs.columns[].name
		}
	}

	.rs.columnNames = 
	return 
}

func ( *mysqlRows) ( int) string {
	return .rs.columns[].typeDatabaseName()
}

// func (rows *mysqlRows) ColumnTypeLength(i int) (length int64, ok bool) {
// 	return int64(rows.rs.columns[i].length), true
// }

func ( *mysqlRows) ( int) (,  bool) {
	return .rs.columns[].flags&flagNotNULL == 0, true
}

func ( *mysqlRows) ( int) (int64, int64, bool) {
	 := .rs.columns[]
	 := int64(.decimals)

	switch .fieldType {
	case fieldTypeDecimal, fieldTypeNewDecimal:
		if  > 0 {
			return int64(.length) - 2, , true
		}
		return int64(.length) - 1, , true
	case fieldTypeTimestamp, fieldTypeDateTime, fieldTypeTime:
		return , , true
	case fieldTypeFloat, fieldTypeDouble:
		if  == 0x1f {
			return math.MaxInt64, math.MaxInt64, true
		}
		return math.MaxInt64, , true
	}

	return 0, 0, false
}

func ( *mysqlRows) ( int) reflect.Type {
	return .rs.columns[].scanType()
}

func ( *mysqlRows) () ( error) {
	if  := .finish;  != nil {
		()
		.finish = nil
	}

	 := .mc
	if  == nil {
		return nil
	}
	if  := .error();  != nil {
		return 
	}

	// flip the buffer for this connection if we need to drain it.
	// note that for a successful query (i.e. one where rows.next()
	// has been called until it returns false), `rows.mc` will be nil
	// by the time the user calls `(*Rows).Close`, so we won't reach this
	// see: https://github.com/golang/go/commit/651ddbdb5056ded455f47f9c494c67b389622a47
	.buf.flip()

	// Remove unread packets from stream
	if !.rs.done {
		 = .readUntilEOF()
	}
	if  == nil {
		if  = .discardResults();  != nil {
			return 
		}
	}

	.mc = nil
	return 
}

func ( *mysqlRows) () ( bool) {
	if .mc == nil {
		return false
	}
	return .mc.status&statusMoreResultsExists != 0
}

func ( *mysqlRows) () (int, error) {
	if .mc == nil {
		return 0, io.EOF
	}
	if  := .mc.error();  != nil {
		return 0, 
	}

	// Remove unread packets from stream
	if !.rs.done {
		if  := .mc.readUntilEOF();  != nil {
			return 0, 
		}
		.rs.done = true
	}

	if !.HasNextResultSet() {
		.mc = nil
		return 0, io.EOF
	}
	.rs = resultSet{}
	return .mc.readResultSetHeaderPacket()
}

func ( *mysqlRows) () (int, error) {
	for {
		,  := .nextResultSet()
		if  != nil {
			return 0, 
		}

		if  > 0 {
			return , nil
		}

		.rs.done = true
	}
}

func ( *binaryRows) () error {
	,  := .nextNotEmptyResultSet()
	if  != nil {
		return 
	}

	.rs.columns,  = .mc.readColumns()
	return 
}

func ( *binaryRows) ( []driver.Value) error {
	if  := .mc;  != nil {
		if  := .error();  != nil {
			return 
		}

		// Fetch next row from stream
		return .readRow()
	}
	return io.EOF
}

func ( *textRows) () ( error) {
	,  := .nextNotEmptyResultSet()
	if  != nil {
		return 
	}

	.rs.columns,  = .mc.readColumns()
	return 
}

func ( *textRows) ( []driver.Value) error {
	if  := .mc;  != nil {
		if  := .error();  != nil {
			return 
		}

		// Fetch next row from stream
		return .readRow()
	}
	return io.EOF
}