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 }