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