Added bytea support to prepared statements

fixes #9, fixes #10
pgx-vs-pq
Jack Christensen 2013-07-01 17:12:07 -05:00
parent 52c26ba14c
commit a98db507b7
2 changed files with 52 additions and 3 deletions

View File

@ -1,6 +1,7 @@
package pgx
import (
"bytes"
"testing"
)
@ -291,6 +292,7 @@ func TestPrepare(t *testing.T) {
if err != nil {
t.Fatal("Unable to establish connection")
}
defer conn.Close()
testTranscode := func(sql string, value interface{}) {
if err = conn.Prepare("testTranscode", sql); err != nil {
@ -313,7 +315,6 @@ func TestPrepare(t *testing.T) {
t.Errorf("Expected: %#v Received: %#v", value, result)
}
}
}
// Test parameter encoding and decoding for simple supported data types
@ -329,7 +330,33 @@ func TestPrepare(t *testing.T) {
// Ensure that unknown types are just treated as strings
testTranscode("select $1::point", "(0,0)")
// case []byte:
// s = `E'\\x` + hex.EncodeToString(arg) + `'`
if err = conn.Prepare("testByteSliceTranscode", "select $1::bytea"); err != nil {
t.Errorf("Unable to prepare statement: %v", err)
return
}
defer func() {
err := conn.Deallocate("testByteSliceTranscode")
if err != nil {
t.Errorf("Deallocate failed: %v", err)
}
}()
bytea := make([]byte, 4)
bytea[0] = 0 // 0x00
bytea[1] = 15 // 0x0F
bytea[2] = 255 // 0xFF
bytea[3] = 17 // 0x11
if conn.SanitizeSql("select $1", bytea) != `select E'\\x000fff11'` {
t.Error("Failed to sanitize []byte")
}
var result interface{}
result, err = conn.SelectValue("testByteSliceTranscode", bytea)
if err != nil {
t.Errorf("%v while running %v", err, "testByteSliceTranscode")
} else {
if bytes.Compare(result.([]byte), bytea) != 0 {
t.Errorf("Expected: %#v Received: %#v", bytea, result)
}
}
}

View File

@ -3,6 +3,7 @@ package pgx
import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"strconv"
)
@ -25,6 +26,12 @@ func init() {
DecodeText: decodeBoolFromText,
EncodeTo: encodeBool}
// bytea
valueTranscoders[oid(17)] = &valueTranscoder{
DecodeText: decodeByteaFromText,
EncodeTo: encodeBytea,
EncodeFormat: 1}
// int8
valueTranscoders[oid(20)] = &valueTranscoder{
DecodeText: decodeInt8FromText,
@ -170,3 +177,18 @@ func encodeText(buf *bytes.Buffer, value interface{}) {
binary.Write(buf, binary.BigEndian, int32(len(s)))
buf.WriteString(s)
}
func decodeByteaFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadByteString(size)
b, err := hex.DecodeString(s[2:])
if err != nil {
panic("Can't decode byte array")
}
return b
}
func encodeBytea(buf *bytes.Buffer, value interface{}) {
b := value.([]byte)
binary.Write(buf, binary.BigEndian, int32(len(b)))
buf.Write(b)
}