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.
14 // ValueConverter is the interface providing the ConvertValue method.
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:
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.
25 // * converting a value as given from the database into one of the
26 // driver Value types.
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
)
35 // Valuer is the interface providing the Value method.
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
)
44 // Bool is a ValueConverter that converts input values to bools.
46 // The conversion rules are:
47 // - booleans are returned unchanged
48 // - for integer types,
51 // other integers are an error
52 // - for strings and []byte, same rules as strconv.ParseBool
53 // - all other types are an error
56 type boolType
struct{}
58 var _ ValueConverter
= boolType
{}
60 func (boolType
) String() string { return "Bool" }
62 func (boolType
) ConvertValue(src
interface{}) (Value
, error
) {
63 switch s
:= src
.(type) {
67 b
, err
:= strconv
.ParseBool(s
)
69 return nil, fmt
.Errorf("sql/driver: couldn't convert %q into type bool", s
)
73 b
, err
:= strconv
.ParseBool(string(s
))
75 return nil, fmt
.Errorf("sql/driver: couldn't convert %q into type bool", s
)
80 sv
:= reflect
.ValueOf(src
)
82 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
84 if iv
== 1 || iv
== 0 {
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
:
90 if uv
== 1 || uv
== 0 {
93 return nil, fmt
.Errorf("sql/driver: couldn't convert %d into type bool", uv
)
96 return nil, fmt
.Errorf("sql/driver: couldn't convert %v (%T) into type bool", src
, src
)
99 // Int32 is a ValueConverter that converts input values to int64,
100 // respecting the limits of an int32 value.
103 type int32Type
struct{}
105 var _ ValueConverter
= int32Type
{}
107 func (int32Type
) ConvertValue(v
interface{}) (Value
, error
) {
108 rv
:= reflect
.ValueOf(v
)
110 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
112 if i64
> (1<<31)-1 || i64
< -(1<<31) {
113 return nil, fmt
.Errorf("sql/driver: value %d overflows int32", v
)
116 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
, reflect
.Uint64
:
119 return nil, fmt
.Errorf("sql/driver: value %d overflows int32", v
)
121 return int64(u64
), nil
123 i
, err
:= strconv
.Atoi(rv
.String())
125 return nil, fmt
.Errorf("sql/driver: value %q can't be converted to int32", v
)
129 return nil, fmt
.Errorf("sql/driver: unsupported value %v (type %T) converting to int32", v
, v
)
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
138 type stringType
struct{}
140 func (stringType
) ConvertValue(v
interface{}) (Value
, error
) {
145 return fmt
.Sprintf("%v", v
), nil
148 // Null is a type that implements ValueConverter by allowing nil
149 // values but otherwise delegating to another ValueConverter.
151 Converter ValueConverter
154 func (n Null
) ConvertValue(v
interface{}) (Value
, error
) {
158 return n
.Converter
.ConvertValue(v
)
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
167 func (n NotNull
) ConvertValue(v
interface{}) (Value
, error
) {
169 return nil, fmt
.Errorf("nil value not allowed")
171 return n
.Converter
.ConvertValue(v
)
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 {
180 if _
, ok
:= v
.(string); ok
{
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 {
193 case int64, float64, []byte, bool, time
.Time
:
199 // DefaultParameterConverter is the default implementation of
200 // ValueConverter that's used when a Stmt doesn't implement
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
207 var DefaultParameterConverter defaultConverter
209 type defaultConverter
struct{}
211 var _ ValueConverter
= defaultConverter
{}
213 func (defaultConverter
) ConvertValue(v
interface{}) (Value
, error
) {
218 if svi
, ok
:= v
.(Valuer
); ok
{
219 sv
, err
:= svi
.Value()
224 return nil, fmt
.Errorf("non-Value type %T returned from Value", sv
)
229 rv
:= reflect
.ValueOf(v
)
236 return defaultConverter
{}.ConvertValue(rv
.Elem().Interface())
238 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
240 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
:
241 return int64(rv
.Uint()), nil
245 return nil, fmt
.Errorf("uint64 values with high bit set are not supported")
247 return int64(u64
), nil
248 case reflect
.Float32
, reflect
.Float64
:
249 return rv
.Float(), nil
251 return nil, fmt
.Errorf("unsupported type %T, a %s", v
, rv
.Kind())