From ba5f97176a3e2bf1ff6f97f2a96f83966a64b7bc Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Mon, 13 Mar 2017 21:34:38 -0500 Subject: [PATCH] Move not null Oid to pgtype In preparation to ConnInfo implementation. --- conn.go | 40 ++++++------- conn_pool.go | 4 +- conn_test.go | 3 +- copy_to_test.go | 3 +- fastpath.go | 14 +++-- large_objects.go | 10 ++-- messages.go | 6 +- pgtype/oid.go | 58 +++++++++++-------- pgtype/oid_value.go | 45 +++++++++++++++ pgtype/{oid_test.go => oid_value_test.go} | 30 +++++----- query_test.go | 5 +- stdlib/sql.go | 5 +- value_reader.go | 6 +- values.go | 68 ++++------------------- values_test.go | 3 +- 15 files changed, 162 insertions(+), 138 deletions(-) create mode 100644 pgtype/oid_value.go rename pgtype/{oid_test.go => oid_value_test.go} (66%) diff --git a/conn.go b/conn.go index ae83fc77..cf34d267 100644 --- a/conn.go +++ b/conn.go @@ -74,11 +74,11 @@ type Conn struct { lastActivityTime time.Time // the last time the connection was used wbuf [1024]byte writeBuf WriteBuf - pid int32 // backend pid - secretKey int32 // key to use to send a cancel query message to the server - RuntimeParams map[string]string // parameters that have been reported by the server - PgTypes map[Oid]PgType // oids to PgTypes - config ConnConfig // config used when establishing this connection + pid int32 // backend pid + secretKey int32 // key to use to send a cancel query message to the server + RuntimeParams map[string]string // parameters that have been reported by the server + PgTypes map[pgtype.Oid]PgType // oids to PgTypes + config ConnConfig // config used when establishing this connection txStatus byte preparedStatements map[string]*PreparedStatement channels map[string]struct{} @@ -102,7 +102,7 @@ type Conn struct { doneChan chan struct{} closedChan chan error - oidPgtypeValues map[Oid]pgtype.Value + oidPgtypeValues map[pgtype.Oid]pgtype.Value } // PreparedStatement is a description of a prepared statement @@ -110,12 +110,12 @@ type PreparedStatement struct { Name string SQL string FieldDescriptions []FieldDescription - ParameterOids []Oid + ParameterOids []pgtype.Oid } // PrepareExOptions is an option struct that can be passed to PrepareEx type PrepareExOptions struct { - ParameterOids []Oid + ParameterOids []pgtype.Oid } // Notification is a message received from the PostgreSQL LISTEN/NOTIFY system @@ -180,13 +180,13 @@ func Connect(config ConnConfig) (c *Conn, err error) { return connect(config, nil) } -func connect(config ConnConfig, pgTypes map[Oid]PgType) (c *Conn, err error) { +func connect(config ConnConfig, pgTypes map[pgtype.Oid]PgType) (c *Conn, err error) { c = new(Conn) c.config = config if pgTypes != nil { - c.PgTypes = make(map[Oid]PgType, len(pgTypes)) + c.PgTypes = make(map[pgtype.Oid]PgType, len(pgTypes)) for k, v := range pgTypes { c.PgTypes[k] = v } @@ -361,7 +361,7 @@ where ( return err } - c.PgTypes = make(map[Oid]PgType, 128) + c.PgTypes = make(map[pgtype.Oid]PgType, 128) for rows.Next() { var oid uint32 @@ -372,14 +372,14 @@ where ( // The zero value is text format so we ignore any types without a default type format t.DefaultFormat, _ = DefaultTypeFormats[t.Name] - c.PgTypes[Oid(oid)] = t + c.PgTypes[pgtype.Oid(oid)] = t } return rows.Err() } func (c *Conn) loadStaticOidPgtypeValues() { - c.oidPgtypeValues = map[Oid]pgtype.Value{ + c.oidPgtypeValues = map[pgtype.Oid]pgtype.Value{ AclitemArrayOid: &pgtype.AclitemArray{}, AclitemOid: &pgtype.Aclitem{}, BoolArrayOid: &pgtype.BoolArray{}, @@ -407,7 +407,7 @@ func (c *Conn) loadStaticOidPgtypeValues() { JsonbOid: &pgtype.Jsonb{}, JsonOid: &pgtype.Json{}, NameOid: &pgtype.Name{}, - OidOid: &pgtype.Oid{}, + OidOid: &pgtype.OidValue{}, TextArrayOid: &pgtype.TextArray{}, TextOid: &pgtype.Text{}, TidOid: &pgtype.Tid{}, @@ -422,7 +422,7 @@ func (c *Conn) loadStaticOidPgtypeValues() { } func (c *Conn) loadDynamicOidPgtypeValues() { - nameOids := make(map[string]Oid, len(c.PgTypes)) + nameOids := make(map[string]pgtype.Oid, len(c.PgTypes)) for k, v := range c.PgTypes { nameOids[v.Name] = k } @@ -1204,9 +1204,9 @@ func (c *Conn) rxRowDescription(r *msgReader) (fields []FieldDescription) { for i := int16(0); i < fieldCount; i++ { f := &fields[i] f.Name = r.readCString() - f.Table = Oid(r.readUint32()) + f.Table = pgtype.Oid(r.readUint32()) f.AttributeNumber = r.readInt16() - f.DataType = Oid(r.readUint32()) + f.DataType = pgtype.Oid(r.readUint32()) f.DataTypeSize = r.readInt16() f.Modifier = r.readInt32() f.FormatCode = r.readInt16() @@ -1214,7 +1214,7 @@ func (c *Conn) rxRowDescription(r *msgReader) (fields []FieldDescription) { return } -func (c *Conn) rxParameterDescription(r *msgReader) (parameters []Oid) { +func (c *Conn) rxParameterDescription(r *msgReader) (parameters []pgtype.Oid) { // Internally, PostgreSQL supports greater than 64k parameters to a prepared // statement. But the parameter description uses a 16-bit integer for the // count of parameters. If there are more than 64K parameters, this count is @@ -1223,10 +1223,10 @@ func (c *Conn) rxParameterDescription(r *msgReader) (parameters []Oid) { r.readInt16() parameterCount := len(r.msgBody[r.rp:]) / 4 - parameters = make([]Oid, 0, parameterCount) + parameters = make([]pgtype.Oid, 0, parameterCount) for i := 0; i < parameterCount; i++ { - parameters = append(parameters, Oid(r.readUint32())) + parameters = append(parameters, pgtype.Oid(r.readUint32())) } return } diff --git a/conn_pool.go b/conn_pool.go index 3081105c..469f638b 100644 --- a/conn_pool.go +++ b/conn_pool.go @@ -5,6 +5,8 @@ import ( "errors" "sync" "time" + + "github.com/jackc/pgx/pgtype" ) type ConnPoolConfig struct { @@ -28,7 +30,7 @@ type ConnPool struct { closed bool preparedStatements map[string]*PreparedStatement acquireTimeout time.Duration - pgTypes map[Oid]PgType + pgTypes map[pgtype.Oid]PgType txAfterClose func(tx *Tx) rowsAfterClose func(rows *Rows) } diff --git a/conn_test.go b/conn_test.go index a6034be6..d863999c 100644 --- a/conn_test.go +++ b/conn_test.go @@ -14,6 +14,7 @@ import ( "time" "github.com/jackc/pgx" + "github.com/jackc/pgx/pgtype" ) func TestConnect(t *testing.T) { @@ -1042,7 +1043,7 @@ func TestPrepareEx(t *testing.T) { conn := mustConnect(t, *defaultConnConfig) defer closeConn(t, conn) - _, err := conn.PrepareEx("test", "select $1", &pgx.PrepareExOptions{ParameterOids: []pgx.Oid{pgx.TextOid}}) + _, err := conn.PrepareEx("test", "select $1", &pgx.PrepareExOptions{ParameterOids: []pgtype.Oid{pgx.TextOid}}) if err != nil { t.Errorf("Unable to prepare statement: %v", err) return diff --git a/copy_to_test.go b/copy_to_test.go index ee96054a..b65ea0f9 100644 --- a/copy_to_test.go +++ b/copy_to_test.go @@ -7,6 +7,7 @@ import ( "time" "github.com/jackc/pgx" + "github.com/jackc/pgx/pgtype" ) func TestConnCopyToSmall(t *testing.T) { @@ -125,7 +126,7 @@ func TestConnCopyToJSON(t *testing.T) { conn := mustConnect(t, *defaultConnConfig) defer closeConn(t, conn) - for _, oid := range []pgx.Oid{pgx.JsonOid, pgx.JsonbOid} { + for _, oid := range []pgtype.Oid{pgx.JsonOid, pgx.JsonbOid} { if _, ok := conn.PgTypes[oid]; !ok { return // No JSON/JSONB type -- must be running against old PostgreSQL } diff --git a/fastpath.go b/fastpath.go index d58a7754..0caba9d3 100644 --- a/fastpath.go +++ b/fastpath.go @@ -2,29 +2,31 @@ package pgx import ( "encoding/binary" + + "github.com/jackc/pgx/pgtype" ) func newFastpath(cn *Conn) *fastpath { - return &fastpath{cn: cn, fns: make(map[string]Oid)} + return &fastpath{cn: cn, fns: make(map[string]pgtype.Oid)} } type fastpath struct { cn *Conn - fns map[string]Oid + fns map[string]pgtype.Oid } -func (f *fastpath) functionOid(name string) Oid { +func (f *fastpath) functionOid(name string) pgtype.Oid { return f.fns[name] } -func (f *fastpath) addFunction(name string, oid Oid) { +func (f *fastpath) addFunction(name string, oid pgtype.Oid) { f.fns[name] = oid } func (f *fastpath) addFunctions(rows *Rows) error { for rows.Next() { var name string - var oid Oid + var oid pgtype.Oid if err := rows.Scan(&name, &oid); err != nil { return err } @@ -47,7 +49,7 @@ func fpInt64Arg(n int64) fpArg { return res } -func (f *fastpath) Call(oid Oid, args []fpArg) (res []byte, err error) { +func (f *fastpath) Call(oid pgtype.Oid, args []fpArg) (res []byte, err error) { if err := f.cn.ensureConnectionReadyForQuery(); err != nil { return nil, err } diff --git a/large_objects.go b/large_objects.go index 960e1e25..bb65e623 100644 --- a/large_objects.go +++ b/large_objects.go @@ -2,6 +2,8 @@ package pgx import ( "io" + + "github.com/jackc/pgx/pgtype" ) // LargeObjects is a structure used to access the large objects API. It is only @@ -60,19 +62,19 @@ const ( // Create creates a new large object. If id is zero, the server assigns an // unused Oid. -func (o *LargeObjects) Create(id Oid) (Oid, error) { +func (o *LargeObjects) Create(id pgtype.Oid) (pgtype.Oid, error) { newOid, err := fpInt32(o.fp.CallFn("lo_create", []fpArg{fpIntArg(int32(id))})) - return Oid(newOid), err + return pgtype.Oid(newOid), err } // Open opens an existing large object with the given mode. -func (o *LargeObjects) Open(oid Oid, mode LargeObjectMode) (*LargeObject, error) { +func (o *LargeObjects) Open(oid pgtype.Oid, mode LargeObjectMode) (*LargeObject, error) { fd, err := fpInt32(o.fp.CallFn("lo_open", []fpArg{fpIntArg(int32(oid)), fpIntArg(int32(mode))})) return &LargeObject{fd: fd, lo: o}, err } // Unlink removes a large object from the database. -func (o *LargeObjects) Unlink(oid Oid) error { +func (o *LargeObjects) Unlink(oid pgtype.Oid) error { _, err := o.fp.CallFn("lo_unlink", []fpArg{fpIntArg(int32(oid))}) return err } diff --git a/messages.go b/messages.go index 0c14c61d..68faf14c 100644 --- a/messages.go +++ b/messages.go @@ -2,6 +2,8 @@ package pgx import ( "encoding/binary" + + "github.com/jackc/pgx/pgtype" ) const ( @@ -55,9 +57,9 @@ func (s *startupMessage) Bytes() (buf []byte) { type FieldDescription struct { Name string - Table Oid + Table pgtype.Oid AttributeNumber int16 - DataType Oid + DataType pgtype.Oid DataTypeSize int16 DataTypeName string Modifier int32 diff --git a/pgtype/oid.go b/pgtype/oid.go index e57bb2e6..eab1fbcb 100644 --- a/pgtype/oid.go +++ b/pgtype/oid.go @@ -1,45 +1,57 @@ package pgtype import ( + "encoding/binary" + "fmt" "io" + "strconv" + + "github.com/jackc/pgx/pgio" ) // 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 - -// Set converts from src to dst. Note that as Oid is not a general -// number type Set does not do automatic type conversion as other number -// types do. -func (dst *Oid) Set(src interface{}) error { - return (*pguint32)(dst).Set(src) -} - -func (dst *Oid) Get() interface{} { - return (*pguint32)(dst).Get() -} - -// 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) -} +// found in src/include/postgres_ext.h in the PostgreSQL sources. Because it is +// so frequently required to be in a NOT NULL condition Oid cannot be NULL. To +// allow for NULL Oids use OidValue. +type Oid uint32 func (dst *Oid) DecodeText(src []byte) error { - return (*pguint32)(dst).DecodeText(src) + if src == nil { + return fmt.Errorf("cannot decode nil into Oid") + } + + n, err := strconv.ParseUint(string(src), 10, 32) + if err != nil { + return err + } + + *dst = Oid(n) + return nil } func (dst *Oid) DecodeBinary(src []byte) error { - return (*pguint32)(dst).DecodeBinary(src) + if src == nil { + return fmt.Errorf("cannot decode nil into Oid") + } + + if len(src) != 4 { + return fmt.Errorf("invalid length: %v", len(src)) + } + + n := binary.BigEndian.Uint32(src) + *dst = Oid(n) + return nil } func (src Oid) EncodeText(w io.Writer) (bool, error) { - return (pguint32)(src).EncodeText(w) + _, err := io.WriteString(w, strconv.FormatUint(uint64(src), 10)) + return false, err } func (src Oid) EncodeBinary(w io.Writer) (bool, error) { - return (pguint32)(src).EncodeBinary(w) + _, err := pgio.WriteUint32(w, uint32(src)) + return false, err } diff --git a/pgtype/oid_value.go b/pgtype/oid_value.go new file mode 100644 index 00000000..a2b2dcbe --- /dev/null +++ b/pgtype/oid_value.go @@ -0,0 +1,45 @@ +package pgtype + +import ( + "io" +) + +// OidValue (Object Identifier Type) is, according to +// https://www.postgresql.org/docs/current/static/datatype-OidValue.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 OidValue pguint32 + +// Set converts from src to dst. Note that as OidValue is not a general +// number type Set does not do automatic type conversion as other number +// types do. +func (dst *OidValue) Set(src interface{}) error { + return (*pguint32)(dst).Set(src) +} + +func (dst *OidValue) Get() interface{} { + return (*pguint32)(dst).Get() +} + +// AssignTo assigns from src to dst. Note that as OidValue is not a general number +// type AssignTo does not do automatic type conversion as other number types do. +func (src *OidValue) AssignTo(dst interface{}) error { + return (*pguint32)(src).AssignTo(dst) +} + +func (dst *OidValue) DecodeText(src []byte) error { + return (*pguint32)(dst).DecodeText(src) +} + +func (dst *OidValue) DecodeBinary(src []byte) error { + return (*pguint32)(dst).DecodeBinary(src) +} + +func (src OidValue) EncodeText(w io.Writer) (bool, error) { + return (pguint32)(src).EncodeText(w) +} + +func (src OidValue) EncodeBinary(w io.Writer) (bool, error) { + return (pguint32)(src).EncodeBinary(w) +} diff --git a/pgtype/oid_test.go b/pgtype/oid_value_test.go similarity index 66% rename from pgtype/oid_test.go rename to pgtype/oid_value_test.go index b3b96959..21dd6f9d 100644 --- a/pgtype/oid_test.go +++ b/pgtype/oid_value_test.go @@ -7,23 +7,23 @@ import ( "github.com/jackc/pgx/pgtype" ) -func TestOidTranscode(t *testing.T) { +func TestOidValueTranscode(t *testing.T) { testSuccessfulTranscode(t, "oid", []interface{}{ - pgtype.Oid{Uint: 42, Status: pgtype.Present}, - pgtype.Oid{Status: pgtype.Null}, + pgtype.OidValue{Uint: 42, Status: pgtype.Present}, + pgtype.OidValue{Status: pgtype.Null}, }) } -func TestOidSet(t *testing.T) { +func TestOidValueSet(t *testing.T) { successfulTests := []struct { source interface{} - result pgtype.Oid + result pgtype.OidValue }{ - {source: uint32(1), result: pgtype.Oid{Uint: 1, Status: pgtype.Present}}, + {source: uint32(1), result: pgtype.OidValue{Uint: 1, Status: pgtype.Present}}, } for i, tt := range successfulTests { - var r pgtype.Oid + var r pgtype.OidValue err := r.Set(tt.source) if err != nil { t.Errorf("%d: %v", i, err) @@ -35,17 +35,17 @@ func TestOidSet(t *testing.T) { } } -func TestOidAssignTo(t *testing.T) { +func TestOidValueAssignTo(t *testing.T) { var ui32 uint32 var pui32 *uint32 simpleTests := []struct { - src pgtype.Oid + src pgtype.OidValue 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))}, + {src: pgtype.OidValue{Uint: 42, Status: pgtype.Present}, dst: &ui32, expected: uint32(42)}, + {src: pgtype.OidValue{Status: pgtype.Null}, dst: &pui32, expected: ((*uint32)(nil))}, } for i, tt := range simpleTests { @@ -60,11 +60,11 @@ func TestOidAssignTo(t *testing.T) { } pointerAllocTests := []struct { - src pgtype.Oid + src pgtype.OidValue dst interface{} expected interface{} }{ - {src: pgtype.Oid{Uint: 42, Status: pgtype.Present}, dst: &pui32, expected: uint32(42)}, + {src: pgtype.OidValue{Uint: 42, Status: pgtype.Present}, dst: &pui32, expected: uint32(42)}, } for i, tt := range pointerAllocTests { @@ -79,10 +79,10 @@ func TestOidAssignTo(t *testing.T) { } errorTests := []struct { - src pgtype.Oid + src pgtype.OidValue dst interface{} }{ - {src: pgtype.Oid{Status: pgtype.Null}, dst: &ui32}, + {src: pgtype.OidValue{Status: pgtype.Null}, dst: &ui32}, } for i, tt := range errorTests { diff --git a/query_test.go b/query_test.go index 8838329c..01889444 100644 --- a/query_test.go +++ b/query_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/jackc/pgx" + "github.com/jackc/pgx/pgtype" "github.com/shopspring/decimal" ) @@ -335,7 +336,7 @@ func TestQueryRowCoreTypes(t *testing.T) { f64 float64 b bool t time.Time - oid pgx.Oid + oid pgtype.Oid } var actual, zero allTypes @@ -353,7 +354,7 @@ func TestQueryRowCoreTypes(t *testing.T) { {"select $1::timestamptz", []interface{}{time.Unix(123, 5000)}, []interface{}{&actual.t}, allTypes{t: time.Unix(123, 5000)}}, {"select $1::timestamp", []interface{}{time.Date(2010, 1, 2, 3, 4, 5, 0, time.UTC)}, []interface{}{&actual.t}, allTypes{t: time.Date(2010, 1, 2, 3, 4, 5, 0, time.UTC)}}, {"select $1::date", []interface{}{time.Date(1987, 1, 2, 0, 0, 0, 0, time.UTC)}, []interface{}{&actual.t}, allTypes{t: time.Date(1987, 1, 2, 0, 0, 0, 0, time.UTC)}}, - {"select $1::oid", []interface{}{pgx.Oid(42)}, []interface{}{&actual.oid}, allTypes{oid: 42}}, + {"select $1::oid", []interface{}{pgtype.Oid(42)}, []interface{}{&actual.oid}, allTypes{oid: 42}}, } for i, tt := range tests { diff --git a/stdlib/sql.go b/stdlib/sql.go index 07cca7e0..7ab4cdbe 100644 --- a/stdlib/sql.go +++ b/stdlib/sql.go @@ -52,19 +52,20 @@ import ( "io" "github.com/jackc/pgx" + "github.com/jackc/pgx/pgtype" ) var openFromConnPoolCount int // oids that map to intrinsic database/sql types. These will be allowed to be // binary, anything else will be forced to text format -var databaseSqlOids map[pgx.Oid]bool +var databaseSqlOids map[pgtype.Oid]bool func init() { d := &Driver{} sql.Register("pgx", d) - databaseSqlOids = make(map[pgx.Oid]bool) + databaseSqlOids = make(map[pgtype.Oid]bool) databaseSqlOids[pgx.BoolOid] = true databaseSqlOids[pgx.ByteaOid] = true databaseSqlOids[pgx.Int2Oid] = true diff --git a/value_reader.go b/value_reader.go index 364581c9..fea21d49 100644 --- a/value_reader.go +++ b/value_reader.go @@ -2,6 +2,8 @@ package pgx import ( "errors" + + "github.com/jackc/pgx/pgtype" ) // ValueReader is used by the Scanner interface to decode values. @@ -116,8 +118,8 @@ func (r *ValueReader) ReadInt64() int64 { return r.mr.readInt64() } -func (r *ValueReader) ReadOid() Oid { - return Oid(r.ReadUint32()) +func (r *ValueReader) ReadOid() pgtype.Oid { + return pgtype.Oid(r.ReadUint32()) } // ReadString reads count bytes and returns as string diff --git a/values.go b/values.go index 0749be92..d90c363b 100644 --- a/values.go +++ b/values.go @@ -3,16 +3,12 @@ package pgx import ( "bytes" "database/sql/driver" - "encoding/binary" "encoding/json" "fmt" - "io" "math" "reflect" - "strconv" "time" - "github.com/jackc/pgx/pgio" "github.com/jackc/pgx/pgtype" ) @@ -80,7 +76,7 @@ const minInt = -maxInt - 1 var DefaultTypeFormats map[string]int16 // internalNativeGoTypeFormats lists the encoding type for native Go types (not handled with Encoder interface) -var internalNativeGoTypeFormats map[Oid]int16 +var internalNativeGoTypeFormats map[pgtype.Oid]int16 func init() { DefaultTypeFormats = map[string]int16{ @@ -119,7 +115,7 @@ func init() { "xid": BinaryFormatCode, } - internalNativeGoTypeFormats = map[Oid]int16{ + internalNativeGoTypeFormats = map[pgtype.Oid]int16{ BoolArrayOid: BinaryFormatCode, BoolOid: BinaryFormatCode, ByteaArrayOid: BinaryFormatCode, @@ -159,54 +155,10 @@ func (e SerializationError) Error() string { return string(e) } -// 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. Oid cannot be NULL. To allow for NULL Oids use pgtype.Oid. -type Oid uint32 - -func (dst *Oid) DecodeText(src []byte) error { - if src == nil { - return fmt.Errorf("cannot decode nil into Oid") - } - - n, err := strconv.ParseUint(string(src), 10, 32) - if err != nil { - return err - } - - *dst = Oid(n) - return nil -} - -func (dst *Oid) DecodeBinary(src []byte) error { - if src == nil { - return fmt.Errorf("cannot decode nil into Oid") - } - - if len(src) != 4 { - return fmt.Errorf("invalid length: %v", len(src)) - } - - n := binary.BigEndian.Uint32(src) - *dst = Oid(n) - return nil -} - -func (src Oid) EncodeText(w io.Writer) (bool, error) { - _, err := io.WriteString(w, strconv.FormatUint(uint64(src), 10)) - return false, err -} - -func (src Oid) EncodeBinary(w io.Writer) (bool, error) { - _, err := pgio.WriteUint32(w, uint32(src)) - return false, err -} - // Encode encodes arg into wbuf as the type oid. This allows implementations // of the Encoder interface to delegate the actual work of encoding to the // built-in functionality. -func Encode(wbuf *WriteBuf, oid Oid, arg interface{}) error { +func Encode(wbuf *WriteBuf, oid pgtype.Oid, arg interface{}) error { if arg == nil { wbuf.WriteInt32(-1) return nil @@ -542,7 +494,7 @@ func decodeFloat4(vr *ValueReader) float32 { return math.Float32frombits(uint32(i)) } -func encodeFloat32(w *WriteBuf, oid Oid, value float32) error { +func encodeFloat32(w *WriteBuf, oid pgtype.Oid, value float32) error { switch oid { case Float4Oid: w.WriteInt32(4) @@ -582,7 +534,7 @@ func decodeFloat8(vr *ValueReader) float64 { return math.Float64frombits(uint64(i)) } -func encodeFloat64(w *WriteBuf, oid Oid, value float64) error { +func encodeFloat64(w *WriteBuf, oid pgtype.Oid, value float64) error { switch oid { case Float8Oid: w.WriteInt32(8) @@ -617,7 +569,7 @@ func decodeTextAllowBinary(vr *ValueReader) string { return vr.ReadString(vr.Len()) } -func encodeString(w *WriteBuf, oid Oid, value string) error { +func encodeString(w *WriteBuf, oid pgtype.Oid, value string) error { w.WriteInt32(int32(len(value))) w.WriteBytes([]byte(value)) return nil @@ -641,7 +593,7 @@ func decodeBytea(vr *ValueReader) []byte { return vr.ReadBytes(vr.Len()) } -func encodeByteSlice(w *WriteBuf, oid Oid, value []byte) error { +func encodeByteSlice(w *WriteBuf, oid pgtype.Oid, value []byte) error { w.WriteInt32(int32(len(value))) w.WriteBytes(value) @@ -665,7 +617,7 @@ func decodeJSON(vr *ValueReader, d interface{}) error { return err } -func encodeJSON(w *WriteBuf, oid Oid, value interface{}) error { +func encodeJSON(w *WriteBuf, oid pgtype.Oid, value interface{}) error { if oid != JsonOid { return fmt.Errorf("cannot encode JSON into oid %v", oid) } @@ -709,7 +661,7 @@ func decodeJSONB(vr *ValueReader, d interface{}) error { return err } -func encodeJSONB(w *WriteBuf, oid Oid, value interface{}) error { +func encodeJSONB(w *WriteBuf, oid pgtype.Oid, value interface{}) error { if oid != JsonbOid { return fmt.Errorf("cannot encode JSON into oid %v", oid) } @@ -757,7 +709,7 @@ func decodeDate(vr *ValueReader) time.Time { return d.Time } -func encodeTime(w *WriteBuf, oid Oid, value time.Time) error { +func encodeTime(w *WriteBuf, oid pgtype.Oid, value time.Time) error { switch oid { case DateOid: var d pgtype.Date diff --git a/values_test.go b/values_test.go index 69a91d4e..e7ae7e1d 100644 --- a/values_test.go +++ b/values_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/jackc/pgx" + "github.com/jackc/pgx/pgtype" ) func TestDateTranscode(t *testing.T) { @@ -83,7 +84,7 @@ func TestJSONAndJSONBTranscode(t *testing.T) { conn := mustConnect(t, *defaultConnConfig) defer closeConn(t, conn) - for _, oid := range []pgx.Oid{pgx.JsonOid, pgx.JsonbOid} { + for _, oid := range []pgtype.Oid{pgx.JsonOid, pgx.JsonbOid} { if _, ok := conn.PgTypes[oid]; !ok { return // No JSON/JSONB type -- must be running against old PostgreSQL }