func valueToString(v reflect.Value) (string, os.Error) { if v == nil { return "null", nil } switch v := v.(type) { case *reflect.PtrValue: return valueToString(reflect.Indirect(v)) case *reflect.InterfaceValue: return valueToString(v.Elem()) case *reflect.BoolValue: x := v.Get() if x { return "true", nil } else { return "false", nil } case *reflect.IntValue: return strconv.Itoa(v.Get()), nil case *reflect.Int8Value: return strconv.Itoa(int(v.Get())), nil case *reflect.Int16Value: return strconv.Itoa(int(v.Get())), nil case *reflect.Int32Value: return strconv.Itoa(int(v.Get())), nil case *reflect.Int64Value: return strconv.Itoa64(v.Get()), nil case *reflect.UintValue: return strconv.Uitoa(v.Get()), nil case *reflect.Uint8Value: return strconv.Uitoa(uint(v.Get())), nil case *reflect.Uint16Value: return strconv.Uitoa(uint(v.Get())), nil case *reflect.Uint32Value: return strconv.Uitoa(uint(v.Get())), nil case *reflect.Uint64Value: return strconv.Uitoa64(v.Get()), nil case *reflect.UintptrValue: return strconv.Uitoa64(uint64(v.Get())), nil case *reflect.FloatValue: return strconv.Ftoa(v.Get(), 'g', -1), nil case *reflect.Float32Value: return strconv.Ftoa32(v.Get(), 'g', -1), nil case *reflect.Float64Value: return strconv.Ftoa64(v.Get(), 'g', -1), nil case *reflect.StringValue: return v.Get(), nil case *reflect.SliceValue: typ := v.Type().(*reflect.SliceType) if _, ok := typ.Elem().(*reflect.Uint8Type); ok { return string(v.Interface().([]byte)), nil } } return "", os.NewError("Unsupported type") }
// Encode values fro each field func encodeParamValues(a []interface{}) ([]byte, int) { var b []byte for i := 0; i < len(a); i++ { f := a[i] switch t := f.(type) { case string: b = append(b, packString(string(t))...) case int: b = append(b, packString(strconv.Itoa(int(t)))...) case float: b = append(b, packString(strconv.Ftoa(float(t), 'f', -1))...) } } return b, len(b) }
func (i Num) f_Str(Capture) *Any { return toStr(strconv.Ftoa(float(i), 'g', -1)) }
func (e *encodeState) reflectValue(v reflect.Value) { if v == nil { e.WriteString("null") return } if j, ok := v.Interface().(Marshaler); ok { b, err := j.MarshalJSON() if err == nil { // copy JSON into buffer, checking validity. err = Compact(&e.Buffer, b) } if err != nil { e.error(&MarshalerError{v.Type(), err}) } return } switch v := v.(type) { case *reflect.BoolValue: x := v.Get() if x { e.WriteString("true") } else { e.WriteString("false") } case *reflect.IntValue: e.WriteString(strconv.Itoa(v.Get())) case *reflect.Int8Value: e.WriteString(strconv.Itoa(int(v.Get()))) case *reflect.Int16Value: e.WriteString(strconv.Itoa(int(v.Get()))) case *reflect.Int32Value: e.WriteString(strconv.Itoa(int(v.Get()))) case *reflect.Int64Value: e.WriteString(strconv.Itoa64(v.Get())) case *reflect.UintValue: e.WriteString(strconv.Uitoa(v.Get())) case *reflect.Uint8Value: e.WriteString(strconv.Uitoa(uint(v.Get()))) case *reflect.Uint16Value: e.WriteString(strconv.Uitoa(uint(v.Get()))) case *reflect.Uint32Value: e.WriteString(strconv.Uitoa(uint(v.Get()))) case *reflect.Uint64Value: e.WriteString(strconv.Uitoa64(v.Get())) case *reflect.UintptrValue: e.WriteString(strconv.Uitoa64(uint64(v.Get()))) case *reflect.FloatValue: e.WriteString(strconv.Ftoa(v.Get(), 'g', -1)) case *reflect.Float32Value: e.WriteString(strconv.Ftoa32(v.Get(), 'g', -1)) case *reflect.Float64Value: e.WriteString(strconv.Ftoa64(v.Get(), 'g', -1)) case *reflect.StringValue: e.string(v.Get()) case *reflect.StructValue: e.WriteByte('{') t := v.Type().(*reflect.StructType) n := v.NumField() for i := 0; i < n; i++ { if i > 0 { e.WriteByte(',') } f := t.Field(i) if f.Tag != "" { e.string(f.Tag) } else { e.string(f.Name) } e.WriteByte(':') e.reflectValue(v.Field(i)) } e.WriteByte('}') case *reflect.MapValue: if _, ok := v.Type().(*reflect.MapType).Key().(*reflect.StringType); !ok { e.error(&UnsupportedTypeError{v.Type()}) } if v.IsNil() { e.WriteString("null") break } e.WriteByte('{') var sv stringValues = v.Keys() sort.Sort(sv) for i, k := range sv { if i > 0 { e.WriteByte(',') } e.string(k.(*reflect.StringValue).Get()) e.WriteByte(':') e.reflectValue(v.Elem(k)) } e.WriteByte('}') case reflect.ArrayOrSliceValue: e.WriteByte('[') n := v.Len() for i := 0; i < n; i++ { if i > 0 { e.WriteByte(',') } e.reflectValue(v.Elem(i)) } e.WriteByte(']') case interfaceOrPtrValue: if v.IsNil() { e.WriteString("null") return } e.reflectValue(v.Elem()) default: e.error(&UnsupportedTypeError{v.Type()}) } return }
func (conn *Conn) writeBind(stmt *Statement) { values := make([]string, len(stmt.params)) var paramValuesLen int for i, param := range stmt.params { value := param.value if val, ok := value.(uint64); ok { value = int64(val) } switch val := value.(type) { case bool: if val { values[i] = "t" } else { values[i] = "f" } case byte: values[i] = string([]byte{val}) case float: values[i] = strconv.Ftoa(val, 'f', -1) case float32: values[i] = strconv.Ftoa32(val, 'f', -1) case float64: values[i] = strconv.Ftoa64(val, 'f', -1) case int: values[i] = strconv.Itoa(val) case int16: values[i] = strconv.Itoa(int(val)) case int32: values[i] = strconv.Itoa(int(val)) case int64: switch param.typ { case Date: values[i] = time.SecondsToUTC(val).Format("2006-01-02") case Time, TimeTZ: values[i] = time.SecondsToUTC(val).Format("15:04:05") case Timestamp, TimestampTZ: values[i] = time.SecondsToUTC(val).Format("2006-01-02 15:04:05") default: values[i] = strconv.Itoa64(val) } case nil: case *big.Rat: if val.IsInt() { values[i] = val.Num().String() } else { // FIXME: Find a better way to do this. prec999 := val.FloatString(999) trimmed := strings.TrimRight(prec999, "0") sepIndex := strings.Index(trimmed, ".") prec := len(trimmed) - sepIndex - 1 values[i] = val.FloatString(prec) } case string: values[i] = val case *time.Time: switch param.typ { case Date: values[i] = val.Format("2006-01-02") case Time, TimeTZ: values[i] = val.Format("15:04:05") case Timestamp, TimestampTZ: values[i] = val.Format("2006-01-02 15:04:05") default: panic("invalid use of *time.Time") } default: panic("unsupported parameter type") } paramValuesLen += len(values[i]) } msgLen := int32(4 + len(stmt.portalName) + 1 + len(stmt.name) + 1 + 2 + 2 + 2 + len(stmt.params)*4 + paramValuesLen + 2 + 2) conn.writeFrontendMessageCode(_Bind) conn.writeInt32(msgLen) conn.writeString0(stmt.portalName) conn.writeString0(stmt.name) conn.writeInt16(1) conn.writeInt16(int16(textFormat)) conn.writeInt16(int16(len(stmt.params))) for i, param := range stmt.params { if param.value == nil { conn.writeInt32(-1) } else { conn.writeInt32(int32(len(values[i]))) conn.writeString(values[i]) } } conn.writeInt16(1) conn.writeInt16(int16(textFormat)) conn.writeFlush() }