Преглед изворни кода

updated const.go with master

Joshua Prunier пре 10 година
родитељ
комит
a807d31d9a
5 измењених фајлова са 91 додато и 2 уклоњено
  1. 1 0
      AUTHORS
  2. 3 1
      README.md
  3. 7 1
      const.go
  4. 43 0
      driver_test.go
  5. 37 0
      statement.go

+ 1 - 0
AUTHORS

@@ -32,6 +32,7 @@ Luke Scott <luke at webconnex.com>
 Michael Woolnough <michael.woolnough at gmail.com>
 Nicola Peduzzi <thenikso at gmail.com>
 Runrioter Wung <runrioter at gmail.com>
+Soroush Pour <me at soroushjp.com>
 Xiaobing Jiang <s7v7nislands at gmail.com>
 Xiuming Chen <cc at cxm.cc>
 

+ 3 - 1
README.md

@@ -214,6 +214,8 @@ Default:        UTC
 
 Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](http://golang.org/pkg/time/#LoadLocation) for details.
 
+Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter.
+
 Please keep in mind, that param values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
 
 
@@ -266,7 +268,7 @@ Default:        false
 
 All other parameters are interpreted as system variables:
   * `autocommit`: `"SET autocommit=<value>"`
-  * `time_zone`: `"SET time_zone=<value>"`
+  * [`time_zone`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `"SET time_zone=<value>"`
   * [`tx_isolation`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `"SET tx_isolation=<value>"`
   * `param`: `"SET <param>=<value>"`
 

+ 7 - 1
const.go

@@ -24,6 +24,7 @@ const (
 	iERR         byte = 0xff
 )
 
+// https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags
 type clientFlag uint32
 
 const (
@@ -47,6 +48,11 @@ const (
 	clientMultiResults
 	clientPSMultiResults
 	clientPluginAuth
+	clientConnectAttrs
+	clientPluginAuthLenEncClientData
+	clientCanHandleExpiredPasswords
+	clientSessionTrack
+	clientDeprecateEOF
 )
 
 const (
@@ -80,6 +86,7 @@ const (
 	comStmtFetch
 )
 
+// https://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnType
 const (
 	fieldTypeDecimal byte = iota
 	fieldTypeTiny
@@ -134,7 +141,6 @@ const (
 )
 
 // http://dev.mysql.com/doc/internals/en/status-flags.html
-
 type statusFlag uint16
 
 const (

+ 43 - 0
driver_test.go

@@ -780,6 +780,49 @@ func TestNULL(t *testing.T) {
 	})
 }
 
+func TestUint64(t *testing.T) {
+	const (
+		u0    = uint64(0)
+		uall  = ^u0
+		uhigh = uall >> 1
+		utop  = ^uhigh
+		s0    = int64(0)
+		sall  = ^s0
+		shigh = int64(uhigh)
+		stop  = ^shigh
+	)
+	runTests(t, dsn, func(dbt *DBTest) {
+		stmt, err := dbt.db.Prepare(`SELECT ?, ?, ? ,?, ?, ?, ?, ?`)
+		if err != nil {
+			dbt.Fatal(err)
+		}
+		defer stmt.Close()
+		row := stmt.QueryRow(
+			u0, uhigh, utop, uall,
+			s0, shigh, stop, sall,
+		)
+
+		var ua, ub, uc, ud uint64
+		var sa, sb, sc, sd int64
+
+		err = row.Scan(&ua, &ub, &uc, &ud, &sa, &sb, &sc, &sd)
+		if err != nil {
+			dbt.Fatal(err)
+		}
+		switch {
+		case ua != u0,
+			ub != uhigh,
+			uc != utop,
+			ud != uall,
+			sa != s0,
+			sb != shigh,
+			sc != stop,
+			sd != sall:
+			dbt.Fatal("Unexpected result value")
+		}
+	})
+}
+
 func TestLongData(t *testing.T) {
 	runTests(t, dsn, func(dbt *DBTest) {
 		var maxAllowedPacketSize int

+ 37 - 0
statement.go

@@ -10,6 +10,8 @@ package mysql
 
 import (
 	"database/sql/driver"
+	"fmt"
+	"reflect"
 )
 
 type mysqlStmt struct {
@@ -34,6 +36,10 @@ func (stmt *mysqlStmt) NumInput() int {
 	return stmt.paramCount
 }
 
+func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
+	return converter{}
+}
+
 func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
 	if stmt.mc.netConn == nil {
 		errLog.Print(ErrInvalidConn)
@@ -110,3 +116,34 @@ func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
 
 	return rows, err
 }
+
+type converter struct{}
+
+func (converter) ConvertValue(v interface{}) (driver.Value, error) {
+	if driver.IsValue(v) {
+		return v, nil
+	}
+
+	rv := reflect.ValueOf(v)
+	switch rv.Kind() {
+	case reflect.Ptr:
+		// indirect pointers
+		if rv.IsNil() {
+			return nil, nil
+		}
+		return driver.DefaultParameterConverter.ConvertValue(rv.Elem().Interface())
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return rv.Int(), nil
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
+		return int64(rv.Uint()), nil
+	case reflect.Uint64:
+		u64 := rv.Uint()
+		if u64 >= 1<<63 {
+			return fmt.Sprintf("%d", u64), nil
+		}
+		return int64(u64), nil
+	case reflect.Float32, reflect.Float64:
+		return rv.Float(), nil
+	}
+	return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
+}