...

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

Documentation: database/sql/driver

		 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