...

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

View as plain text