github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/database/sql/driver/types.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 package driver 6 7 import ( 8 "fmt" 9 "reflect" 10 "strconv" 11 "time" 12 ) 13 14 // ValueConverter is the interface providing the ConvertValue method. 15 // 16 // Various implementations of ValueConverter are provided by the 17 // driver package to provide consistent implementations of conversions 18 // between drivers. The ValueConverters have several uses: 19 // 20 // * converting from the Value types as provided by the sql package 21 // into a database table's specific column type and making sure it 22 // fits, such as making sure a particular int64 fits in a 23 // table's uint16 column. 24 // 25 // * converting a value as given from the database into one of the 26 // driver Value types. 27 // 28 // * by the sql package, for converting from a driver's Value type 29 // to a user's type in a scan. 30 type ValueConverter interface { 31 // ConvertValue converts a value to a driver Value. 32 ConvertValue(v interface{}) (Value, error) 33 } 34 35 // Valuer is the interface providing the Value method. 36 // 37 // Types implementing Valuer interface are able to convert 38 // themselves to a driver Value. 39 type Valuer interface { 40 // Value returns a driver Value. 41 // Value must not panic. 42 Value() (Value, error) 43 } 44 45 // Bool is a ValueConverter that converts input values to bools. 46 // 47 // The conversion rules are: 48 // - booleans are returned unchanged 49 // - for integer types, 50 // 1 is true 51 // 0 is false, 52 // other integers are an error 53 // - for strings and []byte, same rules as strconv.ParseBool 54 // - all other types are an error 55 var Bool boolType 56 57 type boolType struct{} 58 59 var _ ValueConverter = boolType{} 60 61 func (boolType) String() string { return "Bool" } 62 63 func (boolType) ConvertValue(src interface{}) (Value, error) { 64 switch s := src.(type) { 65 case bool: 66 return s, nil 67 case string: 68 b, err := strconv.ParseBool(s) 69 if err != nil { 70 return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) 71 } 72 return b, nil 73 case []byte: 74 b, err := strconv.ParseBool(string(s)) 75 if err != nil { 76 return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) 77 } 78 return b, nil 79 } 80 81 sv := reflect.ValueOf(src) 82 switch sv.Kind() { 83 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 84 iv := sv.Int() 85 if iv == 1 || iv == 0 { 86 return iv == 1, nil 87 } 88 return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", iv) 89 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 90 uv := sv.Uint() 91 if uv == 1 || uv == 0 { 92 return uv == 1, nil 93 } 94 return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", uv) 95 } 96 97 return nil, fmt.Errorf("sql/driver: couldn't convert %v (%T) into type bool", src, src) 98 } 99 100 // Int32 is a ValueConverter that converts input values to int64, 101 // respecting the limits of an int32 value. 102 var Int32 int32Type 103 104 type int32Type struct{} 105 106 var _ ValueConverter = int32Type{} 107 108 func (int32Type) ConvertValue(v interface{}) (Value, error) { 109 rv := reflect.ValueOf(v) 110 switch rv.Kind() { 111 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 112 i64 := rv.Int() 113 if i64 > (1<<31)-1 || i64 < -(1<<31) { 114 return nil, fmt.Errorf("sql/driver: value %d overflows int32", v) 115 } 116 return i64, nil 117 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 118 u64 := rv.Uint() 119 if u64 > (1<<31)-1 { 120 return nil, fmt.Errorf("sql/driver: value %d overflows int32", v) 121 } 122 return int64(u64), nil 123 case reflect.String: 124 i, err := strconv.Atoi(rv.String()) 125 if err != nil { 126 return nil, fmt.Errorf("sql/driver: value %q can't be converted to int32", v) 127 } 128 return int64(i), nil 129 } 130 return nil, fmt.Errorf("sql/driver: unsupported value %v (type %T) converting to int32", v, v) 131 } 132 133 // String is a ValueConverter that converts its input to a string. 134 // If the value is already a string or []byte, it's unchanged. 135 // If the value is of another type, conversion to string is done 136 // with fmt.Sprintf("%v", v). 137 var String stringType 138 139 type stringType struct{} 140 141 func (stringType) ConvertValue(v interface{}) (Value, error) { 142 switch v.(type) { 143 case string, []byte: 144 return v, nil 145 } 146 return fmt.Sprintf("%v", v), nil 147 } 148 149 // Null is a type that implements ValueConverter by allowing nil 150 // values but otherwise delegating to another ValueConverter. 151 type Null struct { 152 Converter ValueConverter 153 } 154 155 func (n Null) ConvertValue(v interface{}) (Value, error) { 156 if v == nil { 157 return nil, nil 158 } 159 return n.Converter.ConvertValue(v) 160 } 161 162 // NotNull is a type that implements ValueConverter by disallowing nil 163 // values but otherwise delegating to another ValueConverter. 164 type NotNull struct { 165 Converter ValueConverter 166 } 167 168 func (n NotNull) ConvertValue(v interface{}) (Value, error) { 169 if v == nil { 170 return nil, fmt.Errorf("nil value not allowed") 171 } 172 return n.Converter.ConvertValue(v) 173 } 174 175 // IsValue reports whether v is a valid Value parameter type. 176 func IsValue(v interface{}) bool { 177 if v == nil { 178 return true 179 } 180 switch v.(type) { 181 case []byte, bool, float64, int64, string, time.Time: 182 return true 183 case decimalDecompose: 184 return true 185 } 186 return false 187 } 188 189 // IsScanValue is equivalent to IsValue. 190 // It exists for compatibility. 191 func IsScanValue(v interface{}) bool { 192 return IsValue(v) 193 } 194 195 // DefaultParameterConverter is the default implementation of 196 // ValueConverter that's used when a Stmt doesn't implement 197 // ColumnConverter. 198 // 199 // DefaultParameterConverter returns its argument directly if 200 // IsValue(arg). Otherwise, if the argument implements Valuer, its 201 // Value method is used to return a Value. As a fallback, the provided 202 // argument's underlying type is used to convert it to a Value: 203 // underlying integer types are converted to int64, floats to float64, 204 // bool, string, and []byte to themselves. If the argument is a nil 205 // pointer, ConvertValue returns a nil Value. If the argument is a 206 // non-nil pointer, it is dereferenced and ConvertValue is called 207 // recursively. Other types are an error. 208 var DefaultParameterConverter defaultConverter 209 210 type defaultConverter struct{} 211 212 var _ ValueConverter = defaultConverter{} 213 214 var valuerReflectType = reflect.TypeOf((*Valuer)(nil)).Elem() 215 216 // callValuerValue returns vr.Value(), with one exception: 217 // If vr.Value is an auto-generated method on a pointer type and the 218 // pointer is nil, it would panic at runtime in the panicwrap 219 // method. Treat it like nil instead. 220 // Issue 8415. 221 // 222 // This is so people can implement driver.Value on value types and 223 // still use nil pointers to those types to mean nil/NULL, just like 224 // string/*string. 225 // 226 // This function is mirrored in the database/sql package. 227 func callValuerValue(vr Valuer) (v Value, err error) { 228 if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr && 229 rv.IsNil() && 230 rv.Type().Elem().Implements(valuerReflectType) { 231 return nil, nil 232 } 233 return vr.Value() 234 } 235 236 func (defaultConverter) ConvertValue(v interface{}) (Value, error) { 237 if IsValue(v) { 238 return v, nil 239 } 240 241 switch vr := v.(type) { 242 case Valuer: 243 sv, err := callValuerValue(vr) 244 if err != nil { 245 return nil, err 246 } 247 if !IsValue(sv) { 248 return nil, fmt.Errorf("non-Value type %T returned from Value", sv) 249 } 250 return sv, nil 251 252 // For now, continue to prefer the Valuer interface over the decimal decompose interface. 253 case decimalDecompose: 254 return vr, nil 255 } 256 257 rv := reflect.ValueOf(v) 258 switch rv.Kind() { 259 case reflect.Ptr: 260 // indirect pointers 261 if rv.IsNil() { 262 return nil, nil 263 } else { 264 return defaultConverter{}.ConvertValue(rv.Elem().Interface()) 265 } 266 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 267 return rv.Int(), nil 268 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: 269 return int64(rv.Uint()), nil 270 case reflect.Uint64: 271 u64 := rv.Uint() 272 if u64 >= 1<<63 { 273 return nil, fmt.Errorf("uint64 values with high bit set are not supported") 274 } 275 return int64(u64), nil 276 case reflect.Float32, reflect.Float64: 277 return rv.Float(), nil 278 case reflect.Bool: 279 return rv.Bool(), nil 280 case reflect.Slice: 281 ek := rv.Type().Elem().Kind() 282 if ek == reflect.Uint8 { 283 return rv.Bytes(), nil 284 } 285 return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek) 286 case reflect.String: 287 return rv.String(), nil 288 } 289 return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) 290 } 291 292 type decimalDecompose interface { 293 // Decompose returns the internal decimal state into parts. 294 // If the provided buf has sufficient capacity, buf may be returned as the coefficient with 295 // the value set and length set as appropriate. 296 Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) 297 }