// driverArgs 将Stmt.Exec和Stmt.Query的调用参数转换成为driver中定义的值。 // // 若没有语句可用,则语句 ds 为 nil。 func driverArgs(ds *driverStmt, args []interface{}) ([]driver.Value, error) { dargs := make([]driver.Value, len(args)) var si driver.Stmt if ds != nil { si = ds.si } cc, ok := si.(driver.ColumnConverter) // Normal path, for a driver.Stmt that is not a ColumnConverter. if !ok { for n, arg := range args { var err error dargs[n], err = driver.DefaultParameterConverter.ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) } } return dargs, nil } // Let the Stmt convert its own arguments. for n, arg := range args { // First, see if the value itself knows how to convert // itself to a driver type. For example, a NullString // struct changing into a string or nil. if svi, ok := arg.(driver.Valuer); ok { sv, err := svi.Value() if err != nil { return nil, fmt.Errorf("sql: argument index %d from Value: %v", n, err) } if !driver.IsValue(sv) { return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from Value", n, sv) } arg = sv } // Second, ask the column to sanity check itself. For // example, drivers might use this to make sure that // an int64 values being inserted into a 16-bit // integer field is in range (before getting // truncated), or that a nil can't go into a NOT NULL // column before going across the network to get the // same error. var err error ds.Lock() dargs[n], err = cc.ColumnConverter(n).ConvertValue(arg) ds.Unlock() if err != nil { return nil, fmt.Errorf("sql: converting argument #%d's type: %v", n, err) } if !driver.IsValue(dargs[n]) { return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T", arg, dargs[n]) } } return dargs, nil }
func (e *queryBasedExpectation) argsMatches(args []driver.Value) error { if nil == e.args { return nil } if len(args) != len(e.args) { return fmt.Errorf("expected %d, but got %d arguments", len(e.args), len(args)) } for k, v := range args { // custom argument matcher matcher, ok := e.args[k].(Argument) if ok { if !matcher.Match(v) { return fmt.Errorf("matcher %T could not match %d argument %T - %+v", matcher, k, args[k], args[k]) } continue } // convert to driver converter darg, err := driver.DefaultParameterConverter.ConvertValue(e.args[k]) if err != nil { return fmt.Errorf("could not convert %d argument %T - %+v to driver value: %s", k, e.args[k], e.args[k], err) } if !driver.IsValue(darg) { return fmt.Errorf("argument %d: non-subset type %T returned from Value", k, darg) } if !reflect.DeepEqual(darg, args[k]) { return fmt.Errorf("argument %d expected [%T - %+v] does not match actual [%T - %+v]", k, darg, darg, args[k], args[k]) } } return nil }
func (converter) ConvertValue(v interface{}) (driver.Value, error) { if driver.IsValue(v) { return v, nil } rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.Ptr: // indirect pointers if rv.IsNil() { return nil, nil } return driver.DefaultParameterConverter.ConvertValue(rv.Elem().Interface()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return rv.Int(), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: return int64(rv.Uint()), nil case reflect.Uint64: u64 := rv.Uint() if u64 >= 1<<63 { return fmt.Sprintf("%d", u64), nil } return int64(u64), nil case reflect.Float32, reflect.Float64: return rv.Float(), nil } return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) }
func driverArgs(ds *driverStmt, args []interface{}) ([]driver.Value, error) { dargs := make([]driver.Value, len(args)) var si dirver.Stmt if ds != nil { si = ds.si } cc, ok := si.(driver.ColumnConverter) if !ok { for n, arg := range args { var err error vargs[n], err = driver.DefaultParameterConverter.ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql :converting Exec argument #%d's type :%v", n, err) } } } for n, arg := range args { if svi, ok := arg(driver.Valuer); ok { if err != nil { return nil, fmt.Errorf("sql:argument index %d from Value:%v", n, err) } if !driver.IsValue(sv) { return nil, fmt.Errorf("sql: argument index %d:non-subset type %T retruned from value", n, sv) } arg = sv } var err error ds.lock() dargs[n], err = cc.ColumnConverter(n).ConvertValue(arg) ds.Unlock() if err != nil { return nil, fmt.Errorf("sql: vonverting argument #%d's type :%v", n, err) } if !driver.IsValue(dargs[n]) { return nil, fmt.Errorf("sql :driver ColumnConverter error vonverted %T to unsupported type %T", arg, dargs[n]) } } return dargs, nil }
// Value implements the driver.Valuer interface. func (d Datum) Value() (driver.Value, error) { var val driver.Value switch t := d.Payload.(type) { case *Datum_BoolVal: val = t.BoolVal case *Datum_IntVal: val = t.IntVal case *Datum_FloatVal: val = t.FloatVal case *Datum_BytesVal: val = t.BytesVal case *Datum_StringVal: val = t.StringVal case *Datum_TimeVal: val = t.TimeVal.GoTime().UTC() } if driver.IsValue(val) { return val, nil } return nil, util.Errorf("unsupported type %T", val) }
// Value implements the driver.Valuer interface. func (d Datum) Value() (driver.Value, error) { val := d.GetValue() switch t := val.(type) { case *bool: val = *t case *int64: val = *t case *float64: val = *t case []byte: val = t case *string: val = *t case *Datum_Timestamp: val = time.Unix((*t).Sec, int64((*t).Nsec)).UTC() } if driver.IsValue(val) { return val, nil } return nil, util.Errorf("unsupported type %T", val) }
func valuesToStrings(args []driver.Value) []string { strargs := make([]string, len(args)) for i, valarg := range args { ogl.Debugf("valarg: %T: %v; isValue=%v\n", valarg, valarg, driver.IsValue(valarg)) // DEBUG switch valarg.(type) { case string: strargs[i] = valarg.(string) case int64: strargs[i] = strconv.FormatInt(valarg.(int64), 10) case float64: strargs[i] = strconv.FormatFloat(valarg.(float64), 'f', -1, 10) case bool: strargs[i] = strconv.FormatBool(valarg.(bool)) case []byte: strargs[i] = string(valarg.([]byte)) case time.Time: strargs[i] = valarg.(time.Time).String() // TODO: this is probably not the format we want -> fix it later default: _, file, line, _ := runtime.Caller(0) ogl.Warn(fmt.Sprintf("Unexpected type in ogonoriConn#Exec: %T. (%s:%d)", valarg, file, line)) } } return strargs }
// Exec executes a prepared statement with the given arguments and // returns a Result summarizing the effect of the statement. func (s *Stmt) Exec(args ...interface{}) (Result, error) { _, releaseConn, si, err := s.connStmt() if err != nil { return nil, err } defer releaseConn(nil) // -1 means the driver doesn't know how to count the number of // placeholders, so we won't sanity check input here and instead let the // driver deal with errors. if want := si.NumInput(); want != -1 && len(args) != want { return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args)) } sargs := make([]driver.Value, len(args)) // Convert args to subset types. if cc, ok := si.(driver.ColumnConverter); ok { for n, arg := range args { // First, see if the value itself knows how to convert // itself to a driver type. For example, a NullString // struct changing into a string or nil. if svi, ok := arg.(driver.Valuer); ok { sv, err := svi.Value() if err != nil { return nil, fmt.Errorf("sql: argument index %d from Value: %v", n, err) } if !driver.IsValue(sv) { return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from Value", n, sv) } arg = sv } // Second, ask the column to sanity check itself. For // example, drivers might use this to make sure that // an int64 values being inserted into a 16-bit // integer field is in range (before getting // truncated), or that a nil can't go into a NOT NULL // column before going across the network to get the // same error. sargs[n], err = cc.ColumnConverter(n).ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) } if !driver.IsValue(sargs[n]) { return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T", arg, sargs[n]) } } } else { for n, arg := range args { sargs[n], err = driver.DefaultParameterConverter.ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) } } } resi, err := si.Exec(sargs) if err != nil { return nil, err } return result{resi}, nil }
func (cv CypherValue) ConvertValue(v interface{}) (driver.Value, error) { if driver.IsValue(v) { return v, nil } if svi, ok := v.(driver.Valuer); ok { sv, err := svi.Value() if err != nil { return nil, err } if !driver.IsValue(sv) { return nil, fmt.Errorf("non-Value type %T returned from Value", sv) } return sv, nil } rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.Slice: b := CypherValue{} switch v.(type) { case []int: b.Type = CypherArrayInt b.Val = v case []int64: b.Type = CypherArrayInt64 b.Val = v case []float64: b.Type = CypherArrayFloat64 b.Val = v case []string: b.Type = CypherArrayString b.Val = v } return b.Value() case reflect.Map: b := CypherValue{} switch v.(type) { case map[string]string: b.Type = CypherMapStringString b.Val = v case map[string]CypherValue: b.Type = CypherMapStringCypherValue b.Val = v } return b.Value() case reflect.Ptr: // indirect pointers if rv.IsNil() { return nil, nil } return CypherValue{}.ConvertValue(rv.Elem().Interface()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return rv.Int(), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: return int64(rv.Uint()), nil case reflect.Uint64: u64 := rv.Uint() if u64 >= 1<<63 { return nil, fmt.Errorf("uint64 values with high bit set are not supported") } return int64(u64), nil case reflect.Float32, reflect.Float64: return rv.Float(), nil } return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) }
// driverArgs converts arguments from callers of Stmt.Exec and // Stmt.Query into driver Values. // // The statement ds may be nil, if no statement is available. func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) { nvargs := make([]driver.NamedValue, len(args)) var si driver.Stmt if ds != nil { si = ds.si } cc, ok := si.(driver.ColumnConverter) // Normal path, for a driver.Stmt that is not a ColumnConverter. if !ok { for n, arg := range args { var err error nv := &nvargs[n] nv.Ordinal = n + 1 if np, ok := arg.(NamedArg); ok { if err := validateNamedValueName(np.Name); err != nil { return nil, err } arg = np.Value nvargs[n].Name = np.Name } nv.Value, err = driver.DefaultParameterConverter.ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument %s type: %v", describeNamedValue(nv), err) } } return nvargs, nil } // Let the Stmt convert its own arguments. for n, arg := range args { nv := &nvargs[n] nv.Ordinal = n + 1 if np, ok := arg.(NamedArg); ok { if err := validateNamedValueName(np.Name); err != nil { return nil, err } arg = np.Value nv.Name = np.Name } // First, see if the value itself knows how to convert // itself to a driver type. For example, a NullString // struct changing into a string or nil. if vr, ok := arg.(driver.Valuer); ok { sv, err := callValuerValue(vr) if err != nil { return nil, fmt.Errorf("sql: argument %s from Value: %v", describeNamedValue(nv), err) } if !driver.IsValue(sv) { return nil, fmt.Errorf("sql: argument %s: non-subset type %T returned from Value", describeNamedValue(nv), sv) } arg = sv } // Second, ask the column to sanity check itself. For // example, drivers might use this to make sure that // an int64 values being inserted into a 16-bit // integer field is in range (before getting // truncated), or that a nil can't go into a NOT NULL // column before going across the network to get the // same error. var err error ds.Lock() nv.Value, err = cc.ColumnConverter(n).ConvertValue(arg) ds.Unlock() if err != nil { return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err) } if !driver.IsValue(nv.Value) { return nil, fmt.Errorf("sql: for argument %s, driver ColumnConverter error converted %T to unsupported type %T", describeNamedValue(nv), arg, nv.Value) } } return nvargs, nil }