...
Run Format

Source file src/database/sql/convert.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	// Type conversions for Scan.
     6	
     7	package sql
     8	
     9	import (
    10		"database/sql/driver"
    11		"errors"
    12		"fmt"
    13		"reflect"
    14		"strconv"
    15		"time"
    16		"unicode"
    17		"unicode/utf8"
    18	)
    19	
    20	var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
    21	
    22	func describeNamedValue(nv *driver.NamedValue) string {
    23		if len(nv.Name) == 0 {
    24			return fmt.Sprintf("$%d", nv.Ordinal)
    25		}
    26		return fmt.Sprintf("with name %q", nv.Name)
    27	}
    28	
    29	func validateNamedValueName(name string) error {
    30		if len(name) == 0 {
    31			return nil
    32		}
    33		r, _ := utf8.DecodeRuneInString(name)
    34		if unicode.IsLetter(r) {
    35			return nil
    36		}
    37		return fmt.Errorf("name %q does not begin with a letter", name)
    38	}
    39	
    40	// driverArgs converts arguments from callers of Stmt.Exec and
    41	// Stmt.Query into driver Values.
    42	//
    43	// The statement ds may be nil, if no statement is available.
    44	func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) {
    45		nvargs := make([]driver.NamedValue, len(args))
    46		var si driver.Stmt
    47		if ds != nil {
    48			si = ds.si
    49		}
    50		cc, ok := si.(driver.ColumnConverter)
    51	
    52		// Normal path, for a driver.Stmt that is not a ColumnConverter.
    53		if !ok {
    54			for n, arg := range args {
    55				var err error
    56				nv := &nvargs[n]
    57				nv.Ordinal = n + 1
    58				if np, ok := arg.(NamedArg); ok {
    59					if err := validateNamedValueName(np.Name); err != nil {
    60						return nil, err
    61					}
    62					arg = np.Value
    63					nvargs[n].Name = np.Name
    64				}
    65				nv.Value, err = driver.DefaultParameterConverter.ConvertValue(arg)
    66	
    67				if err != nil {
    68					return nil, fmt.Errorf("sql: converting Exec argument %s type: %v", describeNamedValue(nv), err)
    69				}
    70			}
    71			return nvargs, nil
    72		}
    73	
    74		// Let the Stmt convert its own arguments.
    75		for n, arg := range args {
    76			nv := &nvargs[n]
    77			nv.Ordinal = n + 1
    78			if np, ok := arg.(NamedArg); ok {
    79				if err := validateNamedValueName(np.Name); err != nil {
    80					return nil, err
    81				}
    82				arg = np.Value
    83				nv.Name = np.Name
    84			}
    85			// First, see if the value itself knows how to convert
    86			// itself to a driver type. For example, a NullString
    87			// struct changing into a string or nil.
    88			if vr, ok := arg.(driver.Valuer); ok {
    89				sv, err := callValuerValue(vr)
    90				if err != nil {
    91					return nil, fmt.Errorf("sql: argument %s from Value: %v", describeNamedValue(nv), err)
    92				}
    93				if !driver.IsValue(sv) {
    94					return nil, fmt.Errorf("sql: argument %s: non-subset type %T returned from Value", describeNamedValue(nv), sv)
    95				}
    96				arg = sv
    97			}
    98	
    99			// Second, ask the column to sanity check itself. For
   100			// example, drivers might use this to make sure that
   101			// an int64 values being inserted into a 16-bit
   102			// integer field is in range (before getting
   103			// truncated), or that a nil can't go into a NOT NULL
   104			// column before going across the network to get the
   105			// same error.
   106			var err error
   107			ds.Lock()
   108			nv.Value, err = cc.ColumnConverter(n).ConvertValue(arg)
   109			ds.Unlock()
   110			if err != nil {
   111				return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err)
   112			}
   113			if !driver.IsValue(nv.Value) {
   114				return nil, fmt.Errorf("sql: for argument %s, driver ColumnConverter error converted %T to unsupported type %T",
   115					describeNamedValue(nv), arg, nv.Value)
   116			}
   117		}
   118	
   119		return nvargs, nil
   120	}
   121	
   122	// convertAssign copies to dest the value in src, converting it if possible.
   123	// An error is returned if the copy would result in loss of information.
   124	// dest should be a pointer type.
   125	func convertAssign(dest, src interface{}) error {
   126		// Common cases, without reflect.
   127		switch s := src.(type) {
   128		case string:
   129			switch d := dest.(type) {
   130			case *string:
   131				if d == nil {
   132					return errNilPtr
   133				}
   134				*d = s
   135				return nil
   136			case *[]byte:
   137				if d == nil {
   138					return errNilPtr
   139				}
   140				*d = []byte(s)
   141				return nil
   142			}
   143		case []byte:
   144			switch d := dest.(type) {
   145			case *string:
   146				if d == nil {
   147					return errNilPtr
   148				}
   149				*d = string(s)
   150				return nil
   151			case *interface{}:
   152				if d == nil {
   153					return errNilPtr
   154				}
   155				*d = cloneBytes(s)
   156				return nil
   157			case *[]byte:
   158				if d == nil {
   159					return errNilPtr
   160				}
   161				*d = cloneBytes(s)
   162				return nil
   163			case *RawBytes:
   164				if d == nil {
   165					return errNilPtr
   166				}
   167				*d = s
   168				return nil
   169			}
   170		case time.Time:
   171			switch d := dest.(type) {
   172			case *string:
   173				*d = s.Format(time.RFC3339Nano)
   174				return nil
   175			case *[]byte:
   176				if d == nil {
   177					return errNilPtr
   178				}
   179				*d = []byte(s.Format(time.RFC3339Nano))
   180				return nil
   181			}
   182		case nil:
   183			switch d := dest.(type) {
   184			case *interface{}:
   185				if d == nil {
   186					return errNilPtr
   187				}
   188				*d = nil
   189				return nil
   190			case *[]byte:
   191				if d == nil {
   192					return errNilPtr
   193				}
   194				*d = nil
   195				return nil
   196			case *RawBytes:
   197				if d == nil {
   198					return errNilPtr
   199				}
   200				*d = nil
   201				return nil
   202			}
   203		}
   204	
   205		var sv reflect.Value
   206	
   207		switch d := dest.(type) {
   208		case *string:
   209			sv = reflect.ValueOf(src)
   210			switch sv.Kind() {
   211			case reflect.Bool,
   212				reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
   213				reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
   214				reflect.Float32, reflect.Float64:
   215				*d = asString(src)
   216				return nil
   217			}
   218		case *[]byte:
   219			sv = reflect.ValueOf(src)
   220			if b, ok := asBytes(nil, sv); ok {
   221				*d = b
   222				return nil
   223			}
   224		case *RawBytes:
   225			sv = reflect.ValueOf(src)
   226			if b, ok := asBytes([]byte(*d)[:0], sv); ok {
   227				*d = RawBytes(b)
   228				return nil
   229			}
   230		case *bool:
   231			bv, err := driver.Bool.ConvertValue(src)
   232			if err == nil {
   233				*d = bv.(bool)
   234			}
   235			return err
   236		case *interface{}:
   237			*d = src
   238			return nil
   239		}
   240	
   241		if scanner, ok := dest.(Scanner); ok {
   242			return scanner.Scan(src)
   243		}
   244	
   245		dpv := reflect.ValueOf(dest)
   246		if dpv.Kind() != reflect.Ptr {
   247			return errors.New("destination not a pointer")
   248		}
   249		if dpv.IsNil() {
   250			return errNilPtr
   251		}
   252	
   253		if !sv.IsValid() {
   254			sv = reflect.ValueOf(src)
   255		}
   256	
   257		dv := reflect.Indirect(dpv)
   258		if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
   259			switch b := src.(type) {
   260			case []byte:
   261				dv.Set(reflect.ValueOf(cloneBytes(b)))
   262			default:
   263				dv.Set(sv)
   264			}
   265			return nil
   266		}
   267	
   268		if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
   269			dv.Set(sv.Convert(dv.Type()))
   270			return nil
   271		}
   272	
   273		switch dv.Kind() {
   274		case reflect.Ptr:
   275			if src == nil {
   276				dv.Set(reflect.Zero(dv.Type()))
   277				return nil
   278			} else {
   279				dv.Set(reflect.New(dv.Type().Elem()))
   280				return convertAssign(dv.Interface(), src)
   281			}
   282		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   283			s := asString(src)
   284			i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
   285			if err != nil {
   286				err = strconvErr(err)
   287				return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
   288			}
   289			dv.SetInt(i64)
   290			return nil
   291		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   292			s := asString(src)
   293			u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
   294			if err != nil {
   295				err = strconvErr(err)
   296				return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
   297			}
   298			dv.SetUint(u64)
   299			return nil
   300		case reflect.Float32, reflect.Float64:
   301			s := asString(src)
   302			f64, err := strconv.ParseFloat(s, dv.Type().Bits())
   303			if err != nil {
   304				err = strconvErr(err)
   305				return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
   306			}
   307			dv.SetFloat(f64)
   308			return nil
   309		}
   310	
   311		return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
   312	}
   313	
   314	func strconvErr(err error) error {
   315		if ne, ok := err.(*strconv.NumError); ok {
   316			return ne.Err
   317		}
   318		return err
   319	}
   320	
   321	func cloneBytes(b []byte) []byte {
   322		if b == nil {
   323			return nil
   324		} else {
   325			c := make([]byte, len(b))
   326			copy(c, b)
   327			return c
   328		}
   329	}
   330	
   331	func asString(src interface{}) string {
   332		switch v := src.(type) {
   333		case string:
   334			return v
   335		case []byte:
   336			return string(v)
   337		}
   338		rv := reflect.ValueOf(src)
   339		switch rv.Kind() {
   340		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   341			return strconv.FormatInt(rv.Int(), 10)
   342		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   343			return strconv.FormatUint(rv.Uint(), 10)
   344		case reflect.Float64:
   345			return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
   346		case reflect.Float32:
   347			return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
   348		case reflect.Bool:
   349			return strconv.FormatBool(rv.Bool())
   350		}
   351		return fmt.Sprintf("%v", src)
   352	}
   353	
   354	func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
   355		switch rv.Kind() {
   356		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   357			return strconv.AppendInt(buf, rv.Int(), 10), true
   358		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   359			return strconv.AppendUint(buf, rv.Uint(), 10), true
   360		case reflect.Float32:
   361			return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
   362		case reflect.Float64:
   363			return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
   364		case reflect.Bool:
   365			return strconv.AppendBool(buf, rv.Bool()), true
   366		case reflect.String:
   367			s := rv.String()
   368			return append(buf, s...), true
   369		}
   370		return
   371	}
   372	
   373	var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
   374	
   375	// callValuerValue returns vr.Value(), with one exception:
   376	// If vr.Value is an auto-generated method on a pointer type and the
   377	// pointer is nil, it would panic at runtime in the panicwrap
   378	// method. Treat it like nil instead.
   379	// Issue 8415.
   380	//
   381	// This is so people can implement driver.Value on value types and
   382	// still use nil pointers to those types to mean nil/NULL, just like
   383	// string/*string.
   384	//
   385	// This function is mirrored in the database/sql/driver package.
   386	func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
   387		if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr &&
   388			rv.IsNil() &&
   389			rv.Type().Elem().Implements(valuerReflectType) {
   390			return nil, nil
   391		}
   392		return vr.Value()
   393	}
   394	

View as plain text