From 8922421ad60854c5387cd7a863b1a1d0b21b0e14 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Sun, 5 Mar 2017 09:07:07 -0600 Subject: [PATCH] Move XID to pgypte --- pgtype.go | 2 +- xid.go | 45 +++++++++++++++++++++++++ xid_test.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 xid.go create mode 100644 xid_test.go diff --git a/pgtype.go b/pgtype.go index 1200bf12..15c0cc76 100644 --- a/pgtype.go +++ b/pgtype.go @@ -19,7 +19,7 @@ const ( TextOID = 25 OIDOID = 26 TidOID = 27 - XidOID = 28 + XIDOID = 28 CIDOID = 29 JSONOID = 114 CidrOID = 650 diff --git a/xid.go b/xid.go new file mode 100644 index 00000000..f4d087a5 --- /dev/null +++ b/xid.go @@ -0,0 +1,45 @@ +package pgtype + +import ( + "io" +) + +// Xid is PostgreSQL's Transaction ID type. +// +// In later versions of PostgreSQL, it is the type used for the backend_xid +// and backend_xmin columns of the pg_stat_activity system view. +// +// Also, when one does +// +// select xmin, xmax, * from some_table; +// +// it is the data type of the xmin and xmax hidden system columns. +// +// It is currently implemented as an unsigned four byte integer. +// Its definition can be found in src/include/postgres_ext.h as TransactionId +// in the PostgreSQL sources. +type XID CID + +func (dst *XID) ConvertFrom(src interface{}) error { + return (*CID)(dst).ConvertFrom(src) +} + +func (src *XID) AssignTo(dst interface{}) error { + return (*CID)(src).AssignTo(dst) +} + +func (dst *XID) DecodeText(r io.Reader) error { + return (*CID)(dst).DecodeText(r) +} + +func (dst *XID) DecodeBinary(r io.Reader) error { + return (*CID)(dst).DecodeBinary(r) +} + +func (src XID) EncodeText(w io.Writer) error { + return (CID)(src).EncodeText(w) +} + +func (src XID) EncodeBinary(w io.Writer) error { + return (CID)(src).EncodeBinary(w) +} diff --git a/xid_test.go b/xid_test.go new file mode 100644 index 00000000..664920bc --- /dev/null +++ b/xid_test.go @@ -0,0 +1,94 @@ +package pgtype_test + +import ( + "reflect" + "testing" + + "github.com/jackc/pgx/pgtype" +) + +func TestXIDTranscode(t *testing.T) { + testSuccessfulTranscode(t, "xid", []interface{}{ + pgtype.XID{Uint: 42, Status: pgtype.Present}, + pgtype.XID{Status: pgtype.Null}, + }) +} + +func TestXIDConvertFrom(t *testing.T) { + successfulTests := []struct { + source interface{} + result pgtype.XID + }{ + {source: uint32(1), result: pgtype.XID{Uint: 1, Status: pgtype.Present}}, + } + + for i, tt := range successfulTests { + var r pgtype.XID + err := r.ConvertFrom(tt.source) + if err != nil { + t.Errorf("%d: %v", i, err) + } + + if r != tt.result { + t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r) + } + } +} + +func TestXIDAssignTo(t *testing.T) { + var ui32 uint32 + var pui32 *uint32 + + simpleTests := []struct { + src pgtype.XID + dst interface{} + expected interface{} + }{ + {src: pgtype.XID{Uint: 42, Status: pgtype.Present}, dst: &ui32, expected: uint32(42)}, + {src: pgtype.XID{Status: pgtype.Null}, dst: &pui32, expected: ((*uint32)(nil))}, + } + + 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(); dst != tt.expected { + t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst) + } + } + + pointerAllocTests := []struct { + src pgtype.XID + dst interface{} + expected interface{} + }{ + {src: pgtype.XID{Uint: 42, Status: pgtype.Present}, dst: &pui32, expected: uint32(42)}, + } + + for i, tt := range pointerAllocTests { + err := tt.src.AssignTo(tt.dst) + if err != nil { + t.Errorf("%d: %v", i, err) + } + + if dst := reflect.ValueOf(tt.dst).Elem().Elem().Interface(); dst != tt.expected { + t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst) + } + } + + errorTests := []struct { + src pgtype.XID + dst interface{} + }{ + {src: pgtype.XID{Status: pgtype.Null}, dst: &ui32}, + } + + for i, tt := range errorTests { + err := tt.src.AssignTo(tt.dst) + if err == nil { + t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst) + } + } +}