2
0

Convert bytea to Codec

This commit is contained in:
Jack Christensen
2022-01-08 18:33:08 -06:00
parent c6f3e03a61
commit f573cde09c
7 changed files with 297 additions and 909 deletions
+76 -55
View File
@@ -1,73 +1,94 @@
package pgtype_test
import (
"reflect"
"bytes"
"context"
"testing"
"github.com/jackc/pgx/v5/pgtype"
"github.com/jackc/pgx/v5/pgtype/testutil"
"github.com/stretchr/testify/require"
)
func TestByteaTranscode(t *testing.T) {
testutil.TestSuccessfulTranscode(t, "bytea", []interface{}{
&pgtype.Bytea{Bytes: []byte{1, 2, 3}, Valid: true},
&pgtype.Bytea{Bytes: []byte{}, Valid: true},
&pgtype.Bytea{Bytes: nil},
func isExpectedEqBytes(a interface{}) func(interface{}) bool {
return func(v interface{}) bool {
ab := a.([]byte)
vb := v.([]byte)
if (ab == nil) != (vb == nil) {
return false
}
if ab == nil {
return true
}
return bytes.Compare(ab, vb) == 0
}
}
func TestByteaCodec(t *testing.T) {
testPgxCodec(t, "bytea", []PgxTranscodeTestCase{
{[]byte{1, 2, 3}, new([]byte), isExpectedEqBytes([]byte{1, 2, 3})},
{[]byte{}, new([]byte), isExpectedEqBytes([]byte{})},
{[]byte(nil), new([]byte), isExpectedEqBytes([]byte(nil))},
{nil, new([]byte), isExpectedEqBytes([]byte(nil))},
})
}
func TestByteaSet(t *testing.T) {
successfulTests := []struct {
source interface{}
result pgtype.Bytea
}{
{source: []byte{1, 2, 3}, result: pgtype.Bytea{Bytes: []byte{1, 2, 3}, Valid: true}},
{source: []byte{}, result: pgtype.Bytea{Bytes: []byte{}, Valid: true}},
{source: []byte(nil), result: pgtype.Bytea{}},
{source: _byteSlice{1, 2, 3}, result: pgtype.Bytea{Bytes: []byte{1, 2, 3}, Valid: true}},
{source: _byteSlice(nil), result: pgtype.Bytea{}},
}
func TestDriverBytes(t *testing.T) {
conn := testutil.MustConnectPgx(t)
defer testutil.MustCloseContext(t, conn)
for i, tt := range successfulTests {
var r pgtype.Bytea
err := r.Set(tt.source)
if err != nil {
t.Errorf("%d: %v", i, err)
}
ctx := context.Background()
if !reflect.DeepEqual(r, tt.result) {
t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
}
}
}
func TestByteaAssignTo(t *testing.T) {
var buf []byte
var _buf _byteSlice
var pbuf *[]byte
var _pbuf *_byteSlice
err := conn.QueryRow(ctx, `select $1::bytea`, []byte{1, 2}).Scan((*pgtype.DriverBytes)(&buf))
require.NoError(t, err)
simpleTests := []struct {
src pgtype.Bytea
dst interface{}
expected interface{}
}{
{src: pgtype.Bytea{Bytes: []byte{1, 2, 3}, Valid: true}, dst: &buf, expected: []byte{1, 2, 3}},
{src: pgtype.Bytea{Bytes: []byte{1, 2, 3}, Valid: true}, dst: &_buf, expected: _byteSlice{1, 2, 3}},
{src: pgtype.Bytea{Bytes: []byte{1, 2, 3}, Valid: true}, dst: &pbuf, expected: &[]byte{1, 2, 3}},
{src: pgtype.Bytea{Bytes: []byte{1, 2, 3}, Valid: true}, dst: &_pbuf, expected: &_byteSlice{1, 2, 3}},
{src: pgtype.Bytea{}, dst: &pbuf, expected: ((*[]byte)(nil))},
{src: pgtype.Bytea{}, dst: &_pbuf, expected: ((*_byteSlice)(nil))},
}
require.Len(t, buf, 2)
require.Equal(t, buf, []byte{1, 2})
require.Equalf(t, cap(buf), len(buf), "cap(buf) is larger than len(buf)")
for i, tt := range simpleTests {
err := tt.src.AssignTo(tt.dst)
if err != nil {
t.Errorf("%d: %v", i, err)
}
if dst := reflect.ValueOf(tt.dst).Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) {
t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
}
}
// Don't actually have any way to be sure that the bytes are from the driver at the moment as underlying driver
// doesn't reuse buffers at the present.
}
func TestPreallocBytes(t *testing.T) {
conn := testutil.MustConnectPgx(t)
defer testutil.MustCloseContext(t, conn)
ctx := context.Background()
origBuf := []byte{5, 6, 7, 8}
buf := origBuf
err := conn.QueryRow(ctx, `select $1::bytea`, []byte{1, 2}).Scan((*pgtype.PreallocBytes)(&buf))
require.NoError(t, err)
require.Len(t, buf, 2)
require.Equal(t, 4, cap(buf))
require.Equal(t, buf, []byte{1, 2})
require.Equal(t, []byte{1, 2, 7, 8}, origBuf)
err = conn.QueryRow(ctx, `select $1::bytea`, []byte{3, 4, 5, 6, 7}).Scan((*pgtype.PreallocBytes)(&buf))
require.NoError(t, err)
require.Len(t, buf, 5)
require.Equal(t, 5, cap(buf))
require.Equal(t, []byte{1, 2, 7, 8}, origBuf)
}
func TestUndecodedBytes(t *testing.T) {
conn := testutil.MustConnectPgx(t)
defer testutil.MustCloseContext(t, conn)
ctx := context.Background()
var buf []byte
err := conn.QueryRow(ctx, `select 1`).Scan((*pgtype.UndecodedBytes)(&buf))
require.NoError(t, err)
require.Len(t, buf, 4)
require.Equal(t, buf, []byte{0, 0, 0, 1})
}