...

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

View as plain text