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