github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/database/sql/driver/types.go (about)

     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  }