OLD | NEW |
(Empty) | |
| 1 /* |
| 2 Copyright 2011 Google Inc. |
| 3 |
| 4 Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 you may not use this file except in compliance with the License. |
| 6 You may obtain a copy of the License at |
| 7 |
| 8 http://www.apache.org/licenses/LICENSE-2.0 |
| 9 |
| 10 Unless required by applicable law or agreed to in writing, software |
| 11 distributed under the License is distributed on an "AS IS" BASIS, |
| 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 See the License for the specific language governing permissions and |
| 14 limitations under the License. |
| 15 */ |
| 16 |
| 17 // Type conversions for Scan. |
| 18 |
| 19 package sql |
| 20 |
| 21 import ( |
| 22 "fmt" |
| 23 "os" |
| 24 "reflect" |
| 25 "strconv" |
| 26 ) |
| 27 |
| 28 // copyConvert copies to dest the value in src, converting it if possible |
| 29 // An error is returned if the copy would result in loss of information. |
| 30 // dest should be a pointer type. |
| 31 func copyConvert(dest, src interface{}) os.Error { |
| 32 // Common cases, without reflect. Fall through. |
| 33 switch s := src.(type) { |
| 34 case string: |
| 35 switch d := dest.(type) { |
| 36 case *string: |
| 37 *d = s |
| 38 return nil |
| 39 } |
| 40 case []byte: |
| 41 switch d := dest.(type) { |
| 42 case *string: |
| 43 *d = string(s) |
| 44 return nil |
| 45 case *[]byte: |
| 46 *d = s |
| 47 return nil |
| 48 } |
| 49 } |
| 50 |
| 51 sv := reflect.ValueOf(src) |
| 52 |
| 53 switch d := dest.(type) { |
| 54 case *string: |
| 55 switch sv.Kind() { |
| 56 case reflect.Bool, |
| 57 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
reflect.Int64, |
| 58 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uin
t32, reflect.Uint64, |
| 59 reflect.Float32, reflect.Float64: |
| 60 *d = fmt.Sprintf("%v", src) |
| 61 return nil |
| 62 } |
| 63 } |
| 64 |
| 65 if scanner, ok := dest.(ScannerInto); ok { |
| 66 return scanner.ScanInto(src) |
| 67 } |
| 68 |
| 69 dpv := reflect.ValueOf(dest) |
| 70 if dpv.Kind() != reflect.Ptr { |
| 71 return os.NewError("destination not a pointer") |
| 72 } |
| 73 |
| 74 dv := reflect.Indirect(dpv) |
| 75 if dv.Kind() == sv.Kind() { |
| 76 dv.Set(sv) |
| 77 return nil |
| 78 } |
| 79 |
| 80 switch dv.Kind() { |
| 81 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In
t64: |
| 82 if s, ok := asString(src); ok { |
| 83 i64, err := strconv.Atoi64(s) |
| 84 if err != nil { |
| 85 return fmt.Errorf("converting string %q to a %s:
%v", s, dv.Kind(), err) |
| 86 } |
| 87 if dv.OverflowInt(i64) { |
| 88 return fmt.Errorf("string %q overflows %s", s, d
v.Kind()) |
| 89 } |
| 90 dv.SetInt(i64) |
| 91 return nil |
| 92 } |
| 93 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflec
t.Uint64: |
| 94 if s, ok := asString(src); ok { |
| 95 u64, err := strconv.Atoui64(s) |
| 96 if err != nil { |
| 97 return fmt.Errorf("converting string %q to a %s:
%v", s, dv.Kind(), err) |
| 98 } |
| 99 if dv.OverflowUint(u64) { |
| 100 return fmt.Errorf("string %q overflows %s", s, d
v.Kind()) |
| 101 } |
| 102 dv.SetUint(u64) |
| 103 return nil |
| 104 } |
| 105 } |
| 106 |
| 107 return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest
) |
| 108 } |
| 109 |
| 110 func asString(src interface{}) (s string, ok bool) { |
| 111 switch v := src.(type) { |
| 112 case string: |
| 113 return v, true |
| 114 case []byte: |
| 115 return string(v), true |
| 116 } |
| 117 return "", false |
| 118 } |
OLD | NEW |