github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/src/database/sql/convert.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Type conversions for Scan. 6 7 package sql 8 9 import ( 10 "database/sql/driver" 11 "errors" 12 "fmt" 13 "reflect" 14 "strconv" 15 "time" 16 ) 17 18 var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error 19 20 // driverArgs converts arguments from callers of Stmt.Exec and 21 // Stmt.Query into driver Values. 22 // 23 // The statement ds may be nil, if no statement is available. 24 func driverArgs(ds *driverStmt, args []interface{}) ([]driver.Value, error) { 25 dargs := make([]driver.Value, len(args)) 26 var si driver.Stmt 27 if ds != nil { 28 si = ds.si 29 } 30 cc, ok := si.(driver.ColumnConverter) 31 32 // Normal path, for a driver.Stmt that is not a ColumnConverter. 33 if !ok { 34 for n, arg := range args { 35 var err error 36 dargs[n], err = driver.DefaultParameterConverter.ConvertValue(arg) 37 if err != nil { 38 return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) 39 } 40 } 41 return dargs, nil 42 } 43 44 // Let the Stmt convert its own arguments. 45 for n, arg := range args { 46 // First, see if the value itself knows how to convert 47 // itself to a driver type. For example, a NullString 48 // struct changing into a string or nil. 49 if svi, ok := arg.(driver.Valuer); ok { 50 sv, err := svi.Value() 51 if err != nil { 52 return nil, fmt.Errorf("sql: argument index %d from Value: %v", n, err) 53 } 54 if !driver.IsValue(sv) { 55 return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from Value", n, sv) 56 } 57 arg = sv 58 } 59 60 // Second, ask the column to sanity check itself. For 61 // example, drivers might use this to make sure that 62 // an int64 values being inserted into a 16-bit 63 // integer field is in range (before getting 64 // truncated), or that a nil can't go into a NOT NULL 65 // column before going across the network to get the 66 // same error. 67 var err error 68 ds.Lock() 69 dargs[n], err = cc.ColumnConverter(n).ConvertValue(arg) 70 ds.Unlock() 71 if err != nil { 72 return nil, fmt.Errorf("sql: converting argument #%d's type: %v", n, err) 73 } 74 if !driver.IsValue(dargs[n]) { 75 return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T", 76 arg, dargs[n]) 77 } 78 } 79 80 return dargs, nil 81 } 82 83 // convertAssign copies to dest the value in src, converting it if possible. 84 // An error is returned if the copy would result in loss of information. 85 // dest should be a pointer type. 86 func convertAssign(dest, src interface{}) error { 87 // Common cases, without reflect. 88 switch s := src.(type) { 89 case string: 90 switch d := dest.(type) { 91 case *string: 92 if d == nil { 93 return errNilPtr 94 } 95 *d = s 96 return nil 97 case *[]byte: 98 if d == nil { 99 return errNilPtr 100 } 101 *d = []byte(s) 102 return nil 103 } 104 case []byte: 105 switch d := dest.(type) { 106 case *string: 107 if d == nil { 108 return errNilPtr 109 } 110 *d = string(s) 111 return nil 112 case *interface{}: 113 if d == nil { 114 return errNilPtr 115 } 116 *d = cloneBytes(s) 117 return nil 118 case *[]byte: 119 if d == nil { 120 return errNilPtr 121 } 122 *d = cloneBytes(s) 123 return nil 124 case *RawBytes: 125 if d == nil { 126 return errNilPtr 127 } 128 *d = s 129 return nil 130 } 131 case time.Time: 132 switch d := dest.(type) { 133 case *string: 134 *d = s.Format(time.RFC3339Nano) 135 return nil 136 case *[]byte: 137 if d == nil { 138 return errNilPtr 139 } 140 *d = []byte(s.Format(time.RFC3339Nano)) 141 return nil 142 } 143 case nil: 144 switch d := dest.(type) { 145 case *interface{}: 146 if d == nil { 147 return errNilPtr 148 } 149 *d = nil 150 return nil 151 case *[]byte: 152 if d == nil { 153 return errNilPtr 154 } 155 *d = nil 156 return nil 157 case *RawBytes: 158 if d == nil { 159 return errNilPtr 160 } 161 *d = nil 162 return nil 163 } 164 } 165 166 var sv reflect.Value 167 168 switch d := dest.(type) { 169 case *string: 170 sv = reflect.ValueOf(src) 171 switch sv.Kind() { 172 case reflect.Bool, 173 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 174 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 175 reflect.Float32, reflect.Float64: 176 *d = asString(src) 177 return nil 178 } 179 case *[]byte: 180 sv = reflect.ValueOf(src) 181 if b, ok := asBytes(nil, sv); ok { 182 *d = b 183 return nil 184 } 185 case *RawBytes: 186 sv = reflect.ValueOf(src) 187 if b, ok := asBytes([]byte(*d)[:0], sv); ok { 188 *d = RawBytes(b) 189 return nil 190 } 191 case *bool: 192 bv, err := driver.Bool.ConvertValue(src) 193 if err == nil { 194 *d = bv.(bool) 195 } 196 return err 197 case *interface{}: 198 *d = src 199 return nil 200 } 201 202 if scanner, ok := dest.(Scanner); ok { 203 return scanner.Scan(src) 204 } 205 206 dpv := reflect.ValueOf(dest) 207 if dpv.Kind() != reflect.Ptr { 208 return errors.New("destination not a pointer") 209 } 210 if dpv.IsNil() { 211 return errNilPtr 212 } 213 214 if !sv.IsValid() { 215 sv = reflect.ValueOf(src) 216 } 217 218 dv := reflect.Indirect(dpv) 219 if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { 220 switch b := src.(type) { 221 case []byte: 222 dv.Set(reflect.ValueOf(cloneBytes(b))) 223 default: 224 dv.Set(sv) 225 } 226 return nil 227 } 228 229 if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { 230 dv.Set(sv.Convert(dv.Type())) 231 return nil 232 } 233 234 switch dv.Kind() { 235 case reflect.Ptr: 236 if src == nil { 237 dv.Set(reflect.Zero(dv.Type())) 238 return nil 239 } else { 240 dv.Set(reflect.New(dv.Type().Elem())) 241 return convertAssign(dv.Interface(), src) 242 } 243 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 244 s := asString(src) 245 i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) 246 if err != nil { 247 err = strconvErr(err) 248 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 249 } 250 dv.SetInt(i64) 251 return nil 252 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 253 s := asString(src) 254 u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) 255 if err != nil { 256 err = strconvErr(err) 257 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 258 } 259 dv.SetUint(u64) 260 return nil 261 case reflect.Float32, reflect.Float64: 262 s := asString(src) 263 f64, err := strconv.ParseFloat(s, dv.Type().Bits()) 264 if err != nil { 265 err = strconvErr(err) 266 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 267 } 268 dv.SetFloat(f64) 269 return nil 270 } 271 272 return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) 273 } 274 275 func strconvErr(err error) error { 276 if ne, ok := err.(*strconv.NumError); ok { 277 return ne.Err 278 } 279 return err 280 } 281 282 func cloneBytes(b []byte) []byte { 283 if b == nil { 284 return nil 285 } else { 286 c := make([]byte, len(b)) 287 copy(c, b) 288 return c 289 } 290 } 291 292 func asString(src interface{}) string { 293 switch v := src.(type) { 294 case string: 295 return v 296 case []byte: 297 return string(v) 298 } 299 rv := reflect.ValueOf(src) 300 switch rv.Kind() { 301 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 302 return strconv.FormatInt(rv.Int(), 10) 303 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 304 return strconv.FormatUint(rv.Uint(), 10) 305 case reflect.Float64: 306 return strconv.FormatFloat(rv.Float(), 'g', -1, 64) 307 case reflect.Float32: 308 return strconv.FormatFloat(rv.Float(), 'g', -1, 32) 309 case reflect.Bool: 310 return strconv.FormatBool(rv.Bool()) 311 } 312 return fmt.Sprintf("%v", src) 313 } 314 315 func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { 316 switch rv.Kind() { 317 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 318 return strconv.AppendInt(buf, rv.Int(), 10), true 319 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 320 return strconv.AppendUint(buf, rv.Uint(), 10), true 321 case reflect.Float32: 322 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true 323 case reflect.Float64: 324 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true 325 case reflect.Bool: 326 return strconv.AppendBool(buf, rv.Bool()), true 327 case reflect.String: 328 s := rv.String() 329 return append(buf, s...), true 330 } 331 return 332 }