diff options
Diffstat (limited to 'libgo/go/exp/sql/convert.go')
-rw-r--r-- | libgo/go/exp/sql/convert.go | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/libgo/go/exp/sql/convert.go b/libgo/go/exp/sql/convert.go index b1feef0eb82..e46cebe9a3d 100644 --- a/libgo/go/exp/sql/convert.go +++ b/libgo/go/exp/sql/convert.go @@ -8,6 +8,7 @@ package sql import ( "errors" + "exp/sql/driver" "fmt" "reflect" "strconv" @@ -36,10 +37,11 @@ func convertAssign(dest, src interface{}) error { } } - sv := reflect.ValueOf(src) + var sv reflect.Value switch d := dest.(type) { case *string: + sv = reflect.ValueOf(src) switch sv.Kind() { case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, @@ -48,6 +50,12 @@ func convertAssign(dest, src interface{}) error { *d = fmt.Sprintf("%v", src) return nil } + case *bool: + bv, err := driver.Bool.ConvertValue(src) + if err == nil { + *d = bv.(bool) + } + return err } if scanner, ok := dest.(ScannerInto); ok { @@ -59,6 +67,10 @@ func convertAssign(dest, src interface{}) error { return errors.New("destination not a pointer") } + if !sv.IsValid() { + sv = reflect.ValueOf(src) + } + dv := reflect.Indirect(dpv) if dv.Kind() == sv.Kind() { dv.Set(sv) @@ -67,40 +79,49 @@ func convertAssign(dest, src interface{}) error { switch dv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if s, ok := asString(src); ok { - i64, err := strconv.Atoi64(s) - if err != nil { - return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) - } - if dv.OverflowInt(i64) { - return fmt.Errorf("string %q overflows %s", s, dv.Kind()) - } - dv.SetInt(i64) - return nil + s := asString(src) + i64, err := strconv.Atoi64(s) + if err != nil { + return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) + } + if dv.OverflowInt(i64) { + return fmt.Errorf("string %q overflows %s", s, dv.Kind()) } + dv.SetInt(i64) + return nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if s, ok := asString(src); ok { - u64, err := strconv.Atoui64(s) - if err != nil { - return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) - } - if dv.OverflowUint(u64) { - return fmt.Errorf("string %q overflows %s", s, dv.Kind()) - } - dv.SetUint(u64) - return nil + s := asString(src) + u64, err := strconv.Atoui64(s) + if err != nil { + return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) + } + if dv.OverflowUint(u64) { + return fmt.Errorf("string %q overflows %s", s, dv.Kind()) + } + dv.SetUint(u64) + return nil + case reflect.Float32, reflect.Float64: + s := asString(src) + f64, err := strconv.Atof64(s) + if err != nil { + return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) + } + if dv.OverflowFloat(f64) { + return fmt.Errorf("value %q overflows %s", s, dv.Kind()) } + dv.SetFloat(f64) + return nil } return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest) } -func asString(src interface{}) (s string, ok bool) { +func asString(src interface{}) string { switch v := src.(type) { case string: - return v, true + return v case []byte: - return string(v), true + return string(v) } - return "", false + return fmt.Sprintf("%v", src) } |