Add pgtype interfaces

pgxtype-experiment2
Jack Christensen 2017-02-24 16:15:38 -06:00
parent 0f93bfc2de
commit d984fcafab
9 changed files with 68 additions and 32 deletions

16
conn.go
View File

@ -7,7 +7,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"golang.org/x/net/context"
"io"
"net"
"net/url"
@ -20,7 +19,10 @@ import (
"sync/atomic"
"time"
"golang.org/x/net/context"
"github.com/jackc/pgx/chunkreader"
"github.com/jackc/pgx/pgtype"
)
const (
@ -102,6 +104,8 @@ type Conn struct {
ctxInProgress bool
doneChan chan struct{}
closedChan chan error
oidPgtypeValues map[OID]pgtype.Value
}
// PreparedStatement is a description of a prepared statement
@ -275,6 +279,16 @@ func (c *Conn) connect(config ConnConfig, network, address string, tlsConfig *tl
c.doneChan = make(chan struct{})
c.closedChan = make(chan error)
i2 := pgtype.Int2(0)
i4 := pgtype.Int4(0)
i8 := pgtype.Int8(0)
c.oidPgtypeValues = map[OID]pgtype.Value{
Int2OID: &i2,
Int4OID: &i4,
Int8OID: &i8,
}
if tlsConfig != nil {
if c.shouldLog(LogLevelDebug) {
c.log(LogLevelDebug, "Starting TLS handshake")

View File

@ -11,7 +11,7 @@ import (
type Int2 int16
func (i *Int2) Convert(src interface{}) error {
func (i *Int2) ConvertFrom(src interface{}) error {
switch value := src.(type) {
case Int2:
*i = value
@ -73,7 +73,7 @@ func (i *Int2) Convert(src interface{}) error {
*i = Int2(num)
default:
if originalSrc, ok := underlyingIntType(src); ok {
return i.Convert(originalSrc)
return i.ConvertFrom(originalSrc)
}
return fmt.Errorf("cannot convert %v to Int2", value)
}
@ -81,6 +81,10 @@ func (i *Int2) Convert(src interface{}) error {
return nil
}
func (i *Int2) AssignTo(dst interface{}) error {
return nil
}
func (i *Int2) DecodeText(r io.Reader) error {
size, err := pgio.ReadInt32(r)
if err != nil {

View File

@ -86,7 +86,7 @@ func TestInt2Transcode(t *testing.T) {
}
}
func TestInt2Convert(t *testing.T) {
func TestInt2ConvertFrom(t *testing.T) {
type _int8 int8
successfulTests := []struct {
@ -111,7 +111,7 @@ func TestInt2Convert(t *testing.T) {
for i, tt := range successfulTests {
var r pgtype.Int2
err := r.Convert(tt.source)
err := r.ConvertFrom(tt.source)
if err != nil {
t.Errorf("%d: %v", i, err)
}

View File

@ -11,7 +11,7 @@ import (
type Int4 int32
func (i *Int4) Convert(src interface{}) error {
func (i *Int4) ConvertFrom(src interface{}) error {
switch value := src.(type) {
case Int4:
*i = value
@ -64,7 +64,7 @@ func (i *Int4) Convert(src interface{}) error {
*i = Int4(num)
default:
if originalSrc, ok := underlyingIntType(src); ok {
return i.Convert(originalSrc)
return i.ConvertFrom(originalSrc)
}
return fmt.Errorf("cannot convert %v to Int8", value)
}
@ -72,6 +72,10 @@ func (i *Int4) Convert(src interface{}) error {
return nil
}
func (i *Int4) AssignTo(dst interface{}) error {
return nil
}
func (i *Int4) DecodeText(r io.Reader) error {
size, err := pgio.ReadInt32(r)
if err != nil {

View File

@ -86,7 +86,7 @@ func TestInt4Transcode(t *testing.T) {
}
}
func TestInt4Convert(t *testing.T) {
func TestInt4ConvertFrom(t *testing.T) {
type _int8 int8
successfulTests := []struct {
@ -111,7 +111,7 @@ func TestInt4Convert(t *testing.T) {
for i, tt := range successfulTests {
var r pgtype.Int4
err := r.Convert(tt.source)
err := r.ConvertFrom(tt.source)
if err != nil {
t.Errorf("%d: %v", i, err)
}

View File

@ -11,7 +11,7 @@ import (
type Int8 int64
func (i *Int8) Convert(src interface{}) error {
func (i *Int8) ConvertFrom(src interface{}) error {
switch value := src.(type) {
case Int8:
*i = value
@ -55,7 +55,7 @@ func (i *Int8) Convert(src interface{}) error {
*i = Int8(num)
default:
if originalSrc, ok := underlyingIntType(src); ok {
return i.Convert(originalSrc)
return i.ConvertFrom(originalSrc)
}
return fmt.Errorf("cannot convert %v to Int8", value)
}
@ -63,6 +63,10 @@ func (i *Int8) Convert(src interface{}) error {
return nil
}
func (i *Int8) AssignTo(dst interface{}) error {
return nil
}
func (i *Int8) DecodeText(r io.Reader) error {
size, err := pgio.ReadInt32(r)
if err != nil {

View File

@ -86,7 +86,7 @@ func TestInt8Transcode(t *testing.T) {
}
}
func TestInt8Convert(t *testing.T) {
func TestInt8ConvertFrom(t *testing.T) {
type _int8 int8
successfulTests := []struct {
@ -111,7 +111,7 @@ func TestInt8Convert(t *testing.T) {
for i, tt := range successfulTests {
var r pgtype.Int8
err := r.Convert(tt.source)
err := r.ConvertFrom(tt.source)
if err != nil {
t.Errorf("%d: %v", i, err)
}

26
pgtype/pgtype.go Normal file
View File

@ -0,0 +1,26 @@
package pgtype
import (
"io"
)
type Value interface {
ConvertFrom(src interface{}) error
AssignTo(dst interface{}) error
}
type BinaryDecoder interface {
DecodeBinary(r io.Reader) error
}
type TextDecoder interface {
DecodeText(r io.Reader) error
}
type BinaryEncoder interface {
EncodeBinary(w io.Writer) error
}
type TextEncoder interface {
EncodeText(w io.Writer) error
}

View File

@ -1060,28 +1060,12 @@ func Encode(wbuf *WriteBuf, oid OID, arg interface{}) error {
return encodeJSONB(wbuf, oid, arg)
}
switch oid {
case Int2OID:
var i2 pgtype.Int2
err := i2.Convert(arg)
if value, ok := wbuf.conn.oidPgtypeValues[oid]; ok {
err := value.ConvertFrom(arg)
if err != nil {
return err
}
return i2.EncodeBinary(wbuf)
case Int4OID:
var i4 pgtype.Int4
err := i4.Convert(arg)
if err != nil {
return err
}
return i4.EncodeBinary(wbuf)
case Int8OID:
var i8 pgtype.Int8
err := i8.Convert(arg)
if err != nil {
return err
}
return i8.EncodeBinary(wbuf)
return value.(pgtype.BinaryEncoder).EncodeBinary(wbuf)
}
switch arg := arg.(type) {