github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/go-sql-driver/mysql/statement.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  	"fmt"
    14  	"reflect"
    15  	"strconv"
    16  )
    17  
    18  type mysqlStmt struct {
    19  	mc         *mysqlConn
    20  	id         uint32
    21  	paramCount int
    22  	columns    []mysqlField // cached from the first query
    23  }
    24  
    25  func (stmt *mysqlStmt) Close() error {
    26  	if stmt.mc == nil || stmt.mc.netConn == nil {
    27  		errLog.Print(ErrInvalidConn)
    28  		return driver.ErrBadConn
    29  	}
    30  
    31  	err := stmt.mc.writeCommandPacketUint32(comStmtClose, stmt.id)
    32  	stmt.mc = nil
    33  	return err
    34  }
    35  
    36  func (stmt *mysqlStmt) NumInput() int {
    37  	return stmt.paramCount
    38  }
    39  
    40  func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
    41  	return converter{}
    42  }
    43  
    44  func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
    45  	if stmt.mc.netConn == nil {
    46  		errLog.Print(ErrInvalidConn)
    47  		return nil, driver.ErrBadConn
    48  	}
    49  	// Send command
    50  	err := stmt.writeExecutePacket(args)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	mc := stmt.mc
    56  
    57  	mc.affectedRows = 0
    58  	mc.insertId = 0
    59  
    60  	// Read Result
    61  	resLen, err := mc.readResultSetHeaderPacket()
    62  	if err == nil {
    63  		if resLen > 0 {
    64  			// Columns
    65  			err = mc.readUntilEOF()
    66  			if err != nil {
    67  				return nil, err
    68  			}
    69  
    70  			// Rows
    71  			err = mc.readUntilEOF()
    72  		}
    73  		if err == nil {
    74  			return &mysqlResult{
    75  				affectedRows: int64(mc.affectedRows),
    76  				insertId:     int64(mc.insertId),
    77  			}, nil
    78  		}
    79  	}
    80  
    81  	return nil, err
    82  }
    83  
    84  func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
    85  	if stmt.mc.netConn == nil {
    86  		errLog.Print(ErrInvalidConn)
    87  		return nil, driver.ErrBadConn
    88  	}
    89  	// Send command
    90  	err := stmt.writeExecutePacket(args)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	mc := stmt.mc
    96  
    97  	// Read Result
    98  	resLen, err := mc.readResultSetHeaderPacket()
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	rows := new(binaryRows)
   104  
   105  	if resLen > 0 {
   106  		rows.mc = mc
   107  		// Columns
   108  		// If not cached, read them and cache them
   109  		if stmt.columns == nil {
   110  			rows.columns, err = mc.readColumns(resLen)
   111  			stmt.columns = rows.columns
   112  		} else {
   113  			rows.columns = stmt.columns
   114  			err = mc.readUntilEOF()
   115  		}
   116  	}
   117  
   118  	return rows, err
   119  }
   120  
   121  type converter struct{}
   122  
   123  func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
   124  	if driver.IsValue(v) {
   125  		return v, nil
   126  	}
   127  
   128  	rv := reflect.ValueOf(v)
   129  	switch rv.Kind() {
   130  	case reflect.Ptr:
   131  		// indirect pointers
   132  		if rv.IsNil() {
   133  			return nil, nil
   134  		}
   135  		return c.ConvertValue(rv.Elem().Interface())
   136  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   137  		return rv.Int(), nil
   138  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
   139  		return int64(rv.Uint()), nil
   140  	case reflect.Uint64:
   141  		u64 := rv.Uint()
   142  		if u64 >= 1<<63 {
   143  			return strconv.FormatUint(u64, 10), nil
   144  		}
   145  		return int64(u64), nil
   146  	case reflect.Float32, reflect.Float64:
   147  		return rv.Float(), nil
   148  	}
   149  	return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
   150  }