From 867bef93b9a60ef07f068bc8d2d4398b76331e3c Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 26 Jan 2016 20:58:00 +0000 Subject: database/sql: implement Scan of time.Time, document, clarify Scan error text Fixes #9157 Change-Id: Iadf305a172a0ec53ae91e1b2db3f3351691a48ff Reviewed-on: https://go-review.googlesource.com/18935 Reviewed-by: Russ Cox Reviewed-by: Andrew Gerrand --- src/database/sql/convert.go | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'src/database/sql/convert.go') diff --git a/src/database/sql/convert.go b/src/database/sql/convert.go index bba5a8843a..740fd9d6e7 100644 --- a/src/database/sql/convert.go +++ b/src/database/sql/convert.go @@ -12,6 +12,7 @@ import ( "fmt" "reflect" "strconv" + "time" ) var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error @@ -127,6 +128,18 @@ func convertAssign(dest, src interface{}) error { *d = s return nil } + case time.Time: + switch d := dest.(type) { + case *string: + *d = s.Format(time.RFC3339Nano) + return nil + case *[]byte: + if d == nil { + return errNilPtr + } + *d = []byte(s.Format(time.RFC3339Nano)) + return nil + } case nil: switch d := dest.(type) { case *interface{}: @@ -226,7 +239,8 @@ func convertAssign(dest, src interface{}) error { s := asString(src) i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) if err != nil { - return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) } dv.SetInt(i64) return nil @@ -234,7 +248,8 @@ func convertAssign(dest, src interface{}) error { s := asString(src) u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) if err != nil { - return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) } dv.SetUint(u64) return nil @@ -242,13 +257,21 @@ func convertAssign(dest, src interface{}) error { s := asString(src) f64, err := strconv.ParseFloat(s, dv.Type().Bits()) if err != nil { - return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) } dv.SetFloat(f64) return nil } - return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest) + return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) +} + +func strconvErr(err error) error { + if ne, ok := err.(*strconv.NumError); ok { + return ne.Err + } + return err } func cloneBytes(b []byte) []byte { -- cgit v1.3