From b139307f5bdfab58712841628e701959749523ff Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Sun, 5 Mar 2017 13:05:49 -0600 Subject: [PATCH] Move OID to pgtype --- oid.go | 41 +++++++++++++++++++++++ oid_test.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ pguint32.go | 2 +- 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 oid.go create mode 100644 oid_test.go diff --git a/oid.go b/oid.go new file mode 100644 index 00000000..d137f352 --- /dev/null +++ b/oid.go @@ -0,0 +1,41 @@ +package pgtype + +import ( + "io" +) + +// OID (Object Identifier Type) is, according to +// https://www.postgresql.org/docs/current/static/datatype-oid.html, used +// internally by PostgreSQL as a primary key for various system tables. It is +// currently implemented as an unsigned four-byte integer. Its definition can be +// found in src/include/postgres_ext.h in the PostgreSQL sources. +type OID pguint32 + +// ConvertFrom converts from src to dst. Note that as OID is not a general +// number type ConvertFrom does not do automatic type conversion as other number +// types do. +func (dst *OID) ConvertFrom(src interface{}) error { + return (*pguint32)(dst).ConvertFrom(src) +} + +// AssignTo assigns from src to dst. Note that as OID is not a general number +// type AssignTo does not do automatic type conversion as other number types do. +func (src *OID) AssignTo(dst interface{}) error { + return (*pguint32)(src).AssignTo(dst) +} + +func (dst *OID) DecodeText(r io.Reader) error { + return (*pguint32)(dst).DecodeText(r) +} + +func (dst *OID) DecodeBinary(r io.Reader) error { + return (*pguint32)(dst).DecodeBinary(r) +} + +func (src OID) EncodeText(w io.Writer) error { + return (pguint32)(src).EncodeText(w) +} + +func (src OID) EncodeBinary(w io.Writer) error { + return (pguint32)(src).EncodeBinary(w) +} diff --git a/oid_test.go b/oid_test.go new file mode 100644 index 00000000..c8e0b2d6 --- /dev/null +++ b/oid_test.go @@ -0,0 +1,94 @@ +package pgtype_test + +import ( + "reflect" + "testing" + + "github.com/jackc/pgx/pgtype" +) + +func TestOIDTranscode(t *testing.T) { + testSuccessfulTranscode(t, "oid", []interface{}{ + pgtype.OID{Uint: 42, Status: pgtype.Present}, + pgtype.OID{Status: pgtype.Null}, + }) +} + +func TestOIDConvertFrom(t *testing.T) { + successfulTests := []struct { + source interface{} + result pgtype.OID + }{ + {source: uint32(1), result: pgtype.OID{Uint: 1, Status: pgtype.Present}}, + } + + for i, tt := range successfulTests { + var r pgtype.OID + 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 TestOIDAssignTo(t *testing.T) { + var ui32 uint32 + var pui32 *uint32 + + simpleTests := []struct { + src pgtype.OID + dst interface{} + expected interface{} + }{ + {src: pgtype.OID{Uint: 42, Status: pgtype.Present}, dst: &ui32, expected: uint32(42)}, + {src: pgtype.OID{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.OID + dst interface{} + expected interface{} + }{ + {src: pgtype.OID{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.OID + dst interface{} + }{ + {src: pgtype.OID{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) + } + } +} diff --git a/pguint32.go b/pguint32.go index 66b385fb..9c1ccd6c 100644 --- a/pguint32.go +++ b/pguint32.go @@ -89,7 +89,7 @@ func (dst *pguint32) DecodeBinary(r io.Reader) error { } if size != 4 { - return fmt.Errorf("invalid length for cid: %v", size) + return fmt.Errorf("invalid length: %v", size) } n, err := pgio.ReadUint32(r)