2
0

More pluggable value transcoding

This commit is contained in:
Jack Christensen
2013-06-30 09:25:19 -05:00
parent d6a0f417c6
commit 1042f095ee
2 changed files with 103 additions and 54 deletions
+9 -54
View File
@@ -1,13 +1,9 @@
package pgx
import (
"fmt"
"strconv"
)
type DataRowReader struct {
mr *MessageReader
fields []FieldDescription
mr *MessageReader
fields []FieldDescription
currentFieldIdx int
}
func newDataRowReader(mr *MessageReader, fields []FieldDescription) (r *DataRowReader) {
@@ -24,55 +20,14 @@ func newDataRowReader(mr *MessageReader, fields []FieldDescription) (r *DataRowR
}
func (r *DataRowReader) ReadValue() interface{} {
dataType := r.fields[r.currentFieldIdx].DataType
r.currentFieldIdx++
size := r.mr.ReadInt32()
if size > -1 {
switch r.fields[0].DataType {
case oid(16): // bool
s := r.mr.ReadByteString(size)
switch s {
case "t":
return true
case "f":
return false
default:
panic(fmt.Sprintf("Received invalid bool: %v", s))
}
case oid(20): // int8
s := r.mr.ReadByteString(size)
n, err := strconv.ParseInt(s, 10, 64)
if err != nil {
panic(fmt.Sprintf("Received invalid int8: %v", s))
}
return n
case oid(21): // int2
s := r.mr.ReadByteString(size)
n, err := strconv.ParseInt(s, 10, 16)
if err != nil {
panic(fmt.Sprintf("Received invalid int2: %v", s))
}
return int16(n)
case oid(23): // int4
s := r.mr.ReadByteString(size)
n, err := strconv.ParseInt(s, 10, 32)
if err != nil {
panic(fmt.Sprintf("Received invalid int4: %v", s))
}
return int32(n)
case oid(700): // float4
s := r.mr.ReadByteString(size)
n, err := strconv.ParseFloat(s, 32)
if err != nil {
panic(fmt.Sprintf("Received invalid float4: %v", s))
}
return float32(n)
case oid(701): //float8
s := r.mr.ReadByteString(size)
v, err := strconv.ParseFloat(s, 64)
if err != nil {
panic(fmt.Sprintf("Received invalid float8: %v", s))
}
return v
default:
if vt, present := valueTranscoders[dataType]; present {
return vt.FromText(r.mr, size)
} else {
return r.mr.ReadByteString(size)
}
} else {
+94
View File
@@ -0,0 +1,94 @@
package pgx
import (
"fmt"
"strconv"
)
type valueTranscoder struct {
FromText func(*MessageReader, int32) interface{}
// FromBinary func(*MessageReader, int32) interface{}
// ToText func(interface{}) string
// ToBinary func(interface{}) []byte
}
var valueTranscoders map[oid]*valueTranscoder
func init() {
valueTranscoders = make(map[oid]*valueTranscoder)
// bool
valueTranscoders[oid(16)] = &valueTranscoder{FromText: decodeBoolFromText}
// int8
valueTranscoders[oid(20)] = &valueTranscoder{FromText: decodeInt8FromText}
// int2
valueTranscoders[oid(21)] = &valueTranscoder{FromText: decodeInt2FromText}
// int4
valueTranscoders[oid(23)] = &valueTranscoder{FromText: decodeInt4FromText}
// float4
valueTranscoders[oid(700)] = &valueTranscoder{FromText: decodeFloat4FromText}
// float8
valueTranscoders[oid(701)] = &valueTranscoder{FromText: decodeFloat8FromText}
}
func decodeBoolFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadByteString(size)
switch s {
case "t":
return true
case "f":
return false
default:
panic(fmt.Sprintf("Received invalid bool: %v", s))
}
}
func decodeInt8FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadByteString(size)
n, err := strconv.ParseInt(s, 10, 64)
if err != nil {
panic(fmt.Sprintf("Received invalid int8: %v", s))
}
return n
}
func decodeInt2FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadByteString(size)
n, err := strconv.ParseInt(s, 10, 16)
if err != nil {
panic(fmt.Sprintf("Received invalid int2: %v", s))
}
return int16(n)
}
func decodeInt4FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadByteString(size)
n, err := strconv.ParseInt(s, 10, 32)
if err != nil {
panic(fmt.Sprintf("Received invalid int4: %v", s))
}
return int32(n)
}
func decodeFloat4FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadByteString(size)
n, err := strconv.ParseFloat(s, 32)
if err != nil {
panic(fmt.Sprintf("Received invalid float4: %v", s))
}
return float32(n)
}
func decodeFloat8FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadByteString(size)
v, err := strconv.ParseFloat(s, 64)
if err != nil {
panic(fmt.Sprintf("Received invalid float8: %v", s))
}
return v
}