...
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	// and strings to []byte. If the argument is a nil pointer,
   202	// ConvertValue returns a nil Value. If the argument is a non-nil
   203	// 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	func (defaultConverter) ConvertValue(v interface{}) (Value, error) {
   212		if IsValue(v) {
   213			return v, nil
   214		}
   215	
   216		if svi, ok := v.(Valuer); ok {
   217			sv, err := svi.Value()
   218			if err != nil {
   219				return nil, err
   220			}
   221			if !IsValue(sv) {
   222				return nil, fmt.Errorf("non-Value type %T returned from Value", sv)
   223			}
   224			return sv, nil
   225		}
   226	
   227		rv := reflect.ValueOf(v)
   228		switch rv.Kind() {
   229		case reflect.Ptr:
   230			// indirect pointers
   231			if rv.IsNil() {
   232				return nil, nil
   233			} else {
   234				return defaultConverter{}.ConvertValue(rv.Elem().Interface())
   235			}
   236		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   237			return rv.Int(), nil
   238		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
   239			return int64(rv.Uint()), nil
   240		case reflect.Uint64:
   241			u64 := rv.Uint()
   242			if u64 >= 1<<63 {
   243				return nil, fmt.Errorf("uint64 values with high bit set are not supported")
   244			}
   245			return int64(u64), nil
   246		case reflect.Float32, reflect.Float64:
   247			return rv.Float(), nil
   248		}
   249		return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
   250	}
   251	

View as plain text