...

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

View as plain text