github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/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 // and strings to []byte. If the argument is a nil pointer, 202 // ConvertValue returns a nil Value. If the argument is a non-nil 203 // 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 func (defaultConverter) ConvertValue(v interface{}) (Value, error) { 212 if IsValue(v) { 213 return v, nil 214 } 215 216 if svi, ok := v.(Valuer); ok { 217 sv, err := svi.Value() 218 if err != nil { 219 return nil, err 220 } 221 if !IsValue(sv) { 222 return nil, fmt.Errorf("non-Value type %T returned from Value", sv) 223 } 224 return sv, nil 225 } 226 227 rv := reflect.ValueOf(v) 228 switch rv.Kind() { 229 case reflect.Ptr: 230 // indirect pointers 231 if rv.IsNil() { 232 return nil, nil 233 } else { 234 return defaultConverter{}.ConvertValue(rv.Elem().Interface()) 235 } 236 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 237 return rv.Int(), nil 238 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: 239 return int64(rv.Uint()), nil 240 case reflect.Uint64: 241 u64 := rv.Uint() 242 if u64 >= 1<<63 { 243 return nil, fmt.Errorf("uint64 values with high bit set are not supported") 244 } 245 return int64(u64), nil 246 case reflect.Float32, reflect.Float64: 247 return rv.Float(), nil 248 } 249 return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) 250 }