github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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 "unicode" 17 "unicode/utf8" 18 ) 19 20 var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error 21 22 func describeNamedValue(nv *driver.NamedValue) string { 23 if len(nv.Name) == 0 { 24 return fmt.Sprintf("$%d", nv.Ordinal) 25 } 26 return fmt.Sprintf("with name %q", nv.Name) 27 } 28 29 func validateNamedValueName(name string) error { 30 if len(name) == 0 { 31 return nil 32 } 33 r, _ := utf8.DecodeRuneInString(name) 34 if unicode.IsLetter(r) { 35 return nil 36 } 37 return fmt.Errorf("name %q does not begin with a letter", name) 38 } 39 40 // driverArgs converts arguments from callers of Stmt.Exec and 41 // Stmt.Query into driver Values. 42 // 43 // The statement ds may be nil, if no statement is available. 44 func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) { 45 nvargs := make([]driver.NamedValue, len(args)) 46 var si driver.Stmt 47 if ds != nil { 48 si = ds.si 49 } 50 cc, ok := si.(driver.ColumnConverter) 51 52 // Normal path, for a driver.Stmt that is not a ColumnConverter. 53 if !ok { 54 for n, arg := range args { 55 var err error 56 nv := &nvargs[n] 57 nv.Ordinal = n + 1 58 if np, ok := arg.(NamedArg); ok { 59 if err := validateNamedValueName(np.Name); err != nil { 60 return nil, err 61 } 62 arg = np.Value 63 nvargs[n].Name = np.Name 64 } 65 nv.Value, err = driver.DefaultParameterConverter.ConvertValue(arg) 66 67 if err != nil { 68 return nil, fmt.Errorf("sql: converting Exec argument %s type: %v", describeNamedValue(nv), err) 69 } 70 } 71 return nvargs, nil 72 } 73 74 // Let the Stmt convert its own arguments. 75 for n, arg := range args { 76 nv := &nvargs[n] 77 nv.Ordinal = n + 1 78 if np, ok := arg.(NamedArg); ok { 79 if err := validateNamedValueName(np.Name); err != nil { 80 return nil, err 81 } 82 arg = np.Value 83 nv.Name = np.Name 84 } 85 // First, see if the value itself knows how to convert 86 // itself to a driver type. For example, a NullString 87 // struct changing into a string or nil. 88 if vr, ok := arg.(driver.Valuer); ok { 89 sv, err := callValuerValue(vr) 90 if err != nil { 91 return nil, fmt.Errorf("sql: argument %s from Value: %v", describeNamedValue(nv), err) 92 } 93 if !driver.IsValue(sv) { 94 return nil, fmt.Errorf("sql: argument %s: non-subset type %T returned from Value", describeNamedValue(nv), sv) 95 } 96 arg = sv 97 } 98 99 // Second, ask the column to sanity check itself. For 100 // example, drivers might use this to make sure that 101 // an int64 values being inserted into a 16-bit 102 // integer field is in range (before getting 103 // truncated), or that a nil can't go into a NOT NULL 104 // column before going across the network to get the 105 // same error. 106 var err error 107 ds.Lock() 108 nv.Value, err = cc.ColumnConverter(n).ConvertValue(arg) 109 ds.Unlock() 110 if err != nil { 111 return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err) 112 } 113 if !driver.IsValue(nv.Value) { 114 return nil, fmt.Errorf("sql: for argument %s, driver ColumnConverter error converted %T to unsupported type %T", 115 describeNamedValue(nv), arg, nv.Value) 116 } 117 } 118 119 return nvargs, nil 120 } 121 122 // convertAssign copies to dest the value in src, converting it if possible. 123 // An error is returned if the copy would result in loss of information. 124 // dest should be a pointer type. 125 func convertAssign(dest, src interface{}) error { 126 // Common cases, without reflect. 127 switch s := src.(type) { 128 case string: 129 switch d := dest.(type) { 130 case *string: 131 if d == nil { 132 return errNilPtr 133 } 134 *d = s 135 return nil 136 case *[]byte: 137 if d == nil { 138 return errNilPtr 139 } 140 *d = []byte(s) 141 return nil 142 } 143 case []byte: 144 switch d := dest.(type) { 145 case *string: 146 if d == nil { 147 return errNilPtr 148 } 149 *d = string(s) 150 return nil 151 case *interface{}: 152 if d == nil { 153 return errNilPtr 154 } 155 *d = cloneBytes(s) 156 return nil 157 case *[]byte: 158 if d == nil { 159 return errNilPtr 160 } 161 *d = cloneBytes(s) 162 return nil 163 case *RawBytes: 164 if d == nil { 165 return errNilPtr 166 } 167 *d = s 168 return nil 169 } 170 case time.Time: 171 switch d := dest.(type) { 172 case *string: 173 *d = s.Format(time.RFC3339Nano) 174 return nil 175 case *[]byte: 176 if d == nil { 177 return errNilPtr 178 } 179 *d = []byte(s.Format(time.RFC3339Nano)) 180 return nil 181 } 182 case nil: 183 switch d := dest.(type) { 184 case *interface{}: 185 if d == nil { 186 return errNilPtr 187 } 188 *d = nil 189 return nil 190 case *[]byte: 191 if d == nil { 192 return errNilPtr 193 } 194 *d = nil 195 return nil 196 case *RawBytes: 197 if d == nil { 198 return errNilPtr 199 } 200 *d = nil 201 return nil 202 } 203 } 204 205 var sv reflect.Value 206 207 switch d := dest.(type) { 208 case *string: 209 sv = reflect.ValueOf(src) 210 switch sv.Kind() { 211 case reflect.Bool, 212 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 213 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 214 reflect.Float32, reflect.Float64: 215 *d = asString(src) 216 return nil 217 } 218 case *[]byte: 219 sv = reflect.ValueOf(src) 220 if b, ok := asBytes(nil, sv); ok { 221 *d = b 222 return nil 223 } 224 case *RawBytes: 225 sv = reflect.ValueOf(src) 226 if b, ok := asBytes([]byte(*d)[:0], sv); ok { 227 *d = RawBytes(b) 228 return nil 229 } 230 case *bool: 231 bv, err := driver.Bool.ConvertValue(src) 232 if err == nil { 233 *d = bv.(bool) 234 } 235 return err 236 case *interface{}: 237 *d = src 238 return nil 239 } 240 241 if scanner, ok := dest.(Scanner); ok { 242 return scanner.Scan(src) 243 } 244 245 dpv := reflect.ValueOf(dest) 246 if dpv.Kind() != reflect.Ptr { 247 return errors.New("destination not a pointer") 248 } 249 if dpv.IsNil() { 250 return errNilPtr 251 } 252 253 if !sv.IsValid() { 254 sv = reflect.ValueOf(src) 255 } 256 257 dv := reflect.Indirect(dpv) 258 if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { 259 switch b := src.(type) { 260 case []byte: 261 dv.Set(reflect.ValueOf(cloneBytes(b))) 262 default: 263 dv.Set(sv) 264 } 265 return nil 266 } 267 268 if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { 269 dv.Set(sv.Convert(dv.Type())) 270 return nil 271 } 272 273 switch dv.Kind() { 274 case reflect.Ptr: 275 if src == nil { 276 dv.Set(reflect.Zero(dv.Type())) 277 return nil 278 } else { 279 dv.Set(reflect.New(dv.Type().Elem())) 280 return convertAssign(dv.Interface(), src) 281 } 282 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 283 s := asString(src) 284 i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) 285 if err != nil { 286 err = strconvErr(err) 287 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 288 } 289 dv.SetInt(i64) 290 return nil 291 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 292 s := asString(src) 293 u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) 294 if err != nil { 295 err = strconvErr(err) 296 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 297 } 298 dv.SetUint(u64) 299 return nil 300 case reflect.Float32, reflect.Float64: 301 s := asString(src) 302 f64, err := strconv.ParseFloat(s, dv.Type().Bits()) 303 if err != nil { 304 err = strconvErr(err) 305 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 306 } 307 dv.SetFloat(f64) 308 return nil 309 } 310 311 return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) 312 } 313 314 func strconvErr(err error) error { 315 if ne, ok := err.(*strconv.NumError); ok { 316 return ne.Err 317 } 318 return err 319 } 320 321 func cloneBytes(b []byte) []byte { 322 if b == nil { 323 return nil 324 } else { 325 c := make([]byte, len(b)) 326 copy(c, b) 327 return c 328 } 329 } 330 331 func asString(src interface{}) string { 332 switch v := src.(type) { 333 case string: 334 return v 335 case []byte: 336 return string(v) 337 } 338 rv := reflect.ValueOf(src) 339 switch rv.Kind() { 340 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 341 return strconv.FormatInt(rv.Int(), 10) 342 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 343 return strconv.FormatUint(rv.Uint(), 10) 344 case reflect.Float64: 345 return strconv.FormatFloat(rv.Float(), 'g', -1, 64) 346 case reflect.Float32: 347 return strconv.FormatFloat(rv.Float(), 'g', -1, 32) 348 case reflect.Bool: 349 return strconv.FormatBool(rv.Bool()) 350 } 351 return fmt.Sprintf("%v", src) 352 } 353 354 func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { 355 switch rv.Kind() { 356 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 357 return strconv.AppendInt(buf, rv.Int(), 10), true 358 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 359 return strconv.AppendUint(buf, rv.Uint(), 10), true 360 case reflect.Float32: 361 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true 362 case reflect.Float64: 363 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true 364 case reflect.Bool: 365 return strconv.AppendBool(buf, rv.Bool()), true 366 case reflect.String: 367 s := rv.String() 368 return append(buf, s...), true 369 } 370 return 371 } 372 373 var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() 374 375 // callValuerValue returns vr.Value(), with one exception: 376 // If vr.Value is an auto-generated method on a pointer type and the 377 // pointer is nil, it would panic at runtime in the panicwrap 378 // method. Treat it like nil instead. 379 // Issue 8415. 380 // 381 // This is so people can implement driver.Value on value types and 382 // still use nil pointers to those types to mean nil/NULL, just like 383 // string/*string. 384 // 385 // This function is mirrored in the database/sql/driver package. 386 func callValuerValue(vr driver.Valuer) (v driver.Value, err error) { 387 if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr && 388 rv.IsNil() && 389 rv.Type().Elem().Implements(valuerReflectType) { 390 return nil, nil 391 } 392 return vr.Value() 393 }