github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/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 // Unlike IsScanValue, IsValue permits the string type. 176 func IsValue(v interface{}) bool { 177 if IsScanValue(v) { 178 return true 179 } 180 if _, ok := v.(string); ok { 181 return true 182 } 183 return false 184 } 185 186 // IsScanValue reports whether v is a valid Value scan type. 187 // Unlike IsValue, IsScanValue does not permit the string type. 188 func IsScanValue(v interface{}) bool { 189 if v == nil { 190 return true 191 } 192 switch v.(type) { 193 case int64, float64, []byte, bool, time.Time: 194 return true 195 } 196 return false 197 } 198 199 // DefaultParameterConverter is the default implementation of 200 // ValueConverter that's used when a Stmt doesn't implement 201 // ColumnConverter. 202 // 203 // DefaultParameterConverter returns the given value directly if 204 // IsValue(value). Otherwise integer type are converted to 205 // int64, floats to float64, and strings to []byte. Other types are 206 // an error. 207 var DefaultParameterConverter defaultConverter 208 209 type defaultConverter struct{} 210 211 var _ ValueConverter = defaultConverter{} 212 213 func (defaultConverter) ConvertValue(v interface{}) (Value, error) { 214 if IsValue(v) { 215 return v, nil 216 } 217 218 if svi, ok := v.(Valuer); ok { 219 sv, err := svi.Value() 220 if err != nil { 221 return nil, err 222 } 223 if !IsValue(sv) { 224 return nil, fmt.Errorf("non-Value type %T returned from Value", sv) 225 } 226 return sv, nil 227 } 228 229 rv := reflect.ValueOf(v) 230 switch rv.Kind() { 231 case reflect.Ptr: 232 // indirect pointers 233 if rv.IsNil() { 234 return nil, nil 235 } else { 236 return defaultConverter{}.ConvertValue(rv.Elem().Interface()) 237 } 238 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 239 return rv.Int(), nil 240 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: 241 return int64(rv.Uint()), nil 242 case reflect.Uint64: 243 u64 := rv.Uint() 244 if u64 >= 1<<63 { 245 return nil, fmt.Errorf("uint64 values with high bit set are not supported") 246 } 247 return int64(u64), nil 248 case reflect.Float32, reflect.Float64: 249 return rv.Float(), nil 250 } 251 return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) 252 }