...
Run Format

Source file src/database/sql/driver/types.go

     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	}
   283	

View as plain text