src/pkg/database/sql/driver/types.go - The Go Programming Language

Golang

Source file src/pkg/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	// 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	}