2
0

Decode(Text|Binary) now accepts []byte instead of io.Reader

This commit is contained in:
Jack Christensen
2017-03-10 16:08:47 -06:00
parent bb7122d4a8
commit 361a54abb7
35 changed files with 476 additions and 771 deletions
+22 -24
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
"strconv" "strconv"
@@ -25,40 +26,37 @@ type ArrayDimension struct {
LowerBound int32 LowerBound int32
} }
func (dst *ArrayHeader) DecodeBinary(r io.Reader) error { func (dst *ArrayHeader) DecodeBinary(src []byte) (int, error) {
numDims, err := pgio.ReadInt32(r) if len(src) < 12 {
if err != nil { return 0, fmt.Errorf("array header too short: %d", len(src))
return err
} }
rp := 0
numDims := int(binary.BigEndian.Uint32(src[rp:]))
rp += 4
dst.ContainsNull = binary.BigEndian.Uint32(src[rp:]) == 1
rp += 4
dst.ElementOID = int32(binary.BigEndian.Uint32(src[rp:]))
rp += 4
if numDims > 0 { if numDims > 0 {
dst.Dimensions = make([]ArrayDimension, numDims) dst.Dimensions = make([]ArrayDimension, numDims)
} }
if len(src) < 12+numDims*8 {
containsNull, err := pgio.ReadInt32(r) return 0, fmt.Errorf("array header too short for %d dimensions: %d", numDims, len(src))
if err != nil {
return err
} }
dst.ContainsNull = containsNull == 1
dst.ElementOID, err = pgio.ReadInt32(r)
if err != nil {
return err
}
for i := range dst.Dimensions { for i := range dst.Dimensions {
dst.Dimensions[i].Length, err = pgio.ReadInt32(r) dst.Dimensions[i].Length = int32(binary.BigEndian.Uint32(src[rp:]))
if err != nil { rp += 4
return err
}
dst.Dimensions[i].LowerBound, err = pgio.ReadInt32(r) dst.Dimensions[i].LowerBound = int32(binary.BigEndian.Uint32(src[rp:]))
if err != nil { rp += 4
return err
}
} }
return nil return rp, nil
} }
func (src *ArrayHeader) EncodeBinary(w io.Writer) error { func (src *ArrayHeader) EncodeBinary(w io.Writer) error {
+10 -30
View File
@@ -72,51 +72,31 @@ func (src *Bool) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Bool) DecodeText(r io.Reader) error { func (dst *Bool) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Bool{Status: Null} *dst = Bool{Status: Null}
return nil return nil
} }
if size != 1 { if len(src) != 1 {
return fmt.Errorf("invalid length for bool: %v", size) return fmt.Errorf("invalid length for bool: %v", len(src))
} }
byt, err := pgio.ReadByte(r) *dst = Bool{Bool: src[0] == 't', Status: Present}
if err != nil {
return err
}
*dst = Bool{Bool: byt == 't', Status: Present}
return nil return nil
} }
func (dst *Bool) DecodeBinary(r io.Reader) error { func (dst *Bool) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Bool{Status: Null} *dst = Bool{Status: Null}
return nil return nil
} }
if size != 1 { if len(src) != 1 {
return fmt.Errorf("invalid length for bool: %v", size) return fmt.Errorf("invalid length for bool: %v", len(src))
} }
byt, err := pgio.ReadByte(r) *dst = Bool{Bool: src[0] == 1, Status: Present}
if err != nil {
return err
}
*dst = Bool{Bool: byt == 1, Status: Present}
return nil return nil
} }
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
@@ -73,29 +74,17 @@ func (src *BoolArray) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *BoolArray) DecodeText(r io.Reader) error { func (dst *BoolArray) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = BoolArray{Status: Null} *dst = BoolArray{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Bool var elements []Bool
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -103,8 +92,11 @@ func (dst *BoolArray) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Bool var elem Bool
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -118,19 +110,14 @@ func (dst *BoolArray) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *BoolArray) DecodeBinary(r io.Reader) error { func (dst *BoolArray) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = BoolArray{Status: Null} *dst = BoolArray{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -148,7 +135,14 @@ func (dst *BoolArray) DecodeBinary(r io.Reader) error {
elements := make([]Bool, elementCount) elements := make([]Bool, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -236,6 +230,10 @@ func (src *BoolArray) EncodeText(w io.Writer) error {
} }
func (src *BoolArray) EncodeBinary(w io.Writer) error { func (src *BoolArray) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, BoolOID)
}
func (src *BoolArray) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -256,7 +254,7 @@ func (src *BoolArray) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = BoolOID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+8 -31
View File
@@ -71,29 +71,18 @@ func (src *Bytea) AssignTo(dst interface{}) error {
// DecodeText only supports the hex format. This has been the default since // DecodeText only supports the hex format. This has been the default since
// PostgreSQL 9.0. // PostgreSQL 9.0.
func (dst *Bytea) DecodeText(r io.Reader) error { func (dst *Bytea) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Bytea{Status: Null} *dst = Bytea{Status: Null}
return nil return nil
} }
sbuf := make([]byte, int(size)) if len(src) < 2 || src[0] != '\\' || src[1] != 'x' {
_, err = io.ReadFull(r, sbuf)
if err != nil {
return err
}
if len(sbuf) < 2 || sbuf[0] != '\\' || sbuf[1] != 'x' {
return fmt.Errorf("invalid hex format") return fmt.Errorf("invalid hex format")
} }
buf := make([]byte, (len(sbuf)-2)/2) buf := make([]byte, (len(src)-2)/2)
_, err = hex.Decode(buf, sbuf[2:]) _, err := hex.Decode(buf, src[2:])
if err != nil { if err != nil {
return err return err
} }
@@ -102,25 +91,13 @@ func (dst *Bytea) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Bytea) DecodeBinary(r io.Reader) error { func (dst *Bytea) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Bytea{Status: Null} *dst = Bytea{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) *dst = Bytea{Bytes: src, Status: Present}
_, err = io.ReadFull(r, buf)
if err != nil {
return err
}
*dst = Bytea{Bytes: buf, Status: Present}
return nil return nil
} }
+4 -4
View File
@@ -30,12 +30,12 @@ func (src *CID) AssignTo(dst interface{}) error {
return (*pguint32)(src).AssignTo(dst) return (*pguint32)(src).AssignTo(dst)
} }
func (dst *CID) DecodeText(r io.Reader) error { func (dst *CID) DecodeText(src []byte) error {
return (*pguint32)(dst).DecodeText(r) return (*pguint32)(dst).DecodeText(src)
} }
func (dst *CID) DecodeBinary(r io.Reader) error { func (dst *CID) DecodeBinary(src []byte) error {
return (*pguint32)(dst).DecodeBinary(r) return (*pguint32)(dst).DecodeBinary(src)
} }
func (src CID) EncodeText(w io.Writer) error { func (src CID) EncodeText(w io.Writer) error {
+4 -4
View File
@@ -14,12 +14,12 @@ func (src *CidrArray) AssignTo(dst interface{}) error {
return (*InetArray)(src).AssignTo(dst) return (*InetArray)(src).AssignTo(dst)
} }
func (dst *CidrArray) DecodeText(r io.Reader) error { func (dst *CidrArray) DecodeText(src []byte) error {
return (*InetArray)(dst).DecodeText(r) return (*InetArray)(dst).DecodeText(src)
} }
func (dst *CidrArray) DecodeBinary(r io.Reader) error { func (dst *CidrArray) DecodeBinary(src []byte) error {
return (*InetArray)(dst).DecodeBinary(r) return (*InetArray)(dst).DecodeBinary(src)
} }
func (src *CidrArray) EncodeText(w io.Writer) error { func (src *CidrArray) EncodeText(w io.Writer) error {
+9 -27
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
@@ -66,24 +67,13 @@ func (src *Date) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Date) DecodeText(r io.Reader) error { func (dst *Date) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Date{Status: Null} *dst = Date{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) sbuf := string(src)
_, err = r.Read(buf)
if err != nil {
return err
}
sbuf := string(buf)
switch sbuf { switch sbuf {
case "infinity": case "infinity":
*dst = Date{Status: Present, InfinityModifier: Infinity} *dst = Date{Status: Present, InfinityModifier: Infinity}
@@ -101,25 +91,17 @@ func (dst *Date) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Date) DecodeBinary(r io.Reader) error { func (dst *Date) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Date{Status: Null} *dst = Date{Status: Null}
return nil return nil
} }
if size != 4 { if len(src) != 4 {
return fmt.Errorf("invalid length for date: %v", size) return fmt.Errorf("invalid length for date: %v", len(src))
} }
dayOffset, err := pgio.ReadInt32(r) dayOffset := int32(binary.BigEndian.Uint32(src))
if err != nil {
return err
}
switch dayOffset { switch dayOffset {
case infinityDayOffset: case infinityDayOffset:
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
"time" "time"
@@ -74,29 +75,17 @@ func (src *DateArray) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *DateArray) DecodeText(r io.Reader) error { func (dst *DateArray) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = DateArray{Status: Null} *dst = DateArray{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Date var elements []Date
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -104,8 +93,11 @@ func (dst *DateArray) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Date var elem Date
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -119,19 +111,14 @@ func (dst *DateArray) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *DateArray) DecodeBinary(r io.Reader) error { func (dst *DateArray) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = DateArray{Status: Null} *dst = DateArray{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -149,7 +136,14 @@ func (dst *DateArray) DecodeBinary(r io.Reader) error {
elements := make([]Date, elementCount) elements := make([]Date, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -237,6 +231,10 @@ func (src *DateArray) EncodeText(w io.Writer) error {
} }
func (src *DateArray) EncodeBinary(w io.Writer) error { func (src *DateArray) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, DateOID)
}
func (src *DateArray) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -257,7 +255,7 @@ func (src *DateArray) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = DateOID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+9 -27
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"math" "math"
@@ -92,24 +93,13 @@ func (src *Float4) AssignTo(dst interface{}) error {
return float64AssignTo(float64(src.Float), src.Status, dst) return float64AssignTo(float64(src.Float), src.Status, dst)
} }
func (dst *Float4) DecodeText(r io.Reader) error { func (dst *Float4) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float4{Status: Null} *dst = Float4{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) n, err := strconv.ParseFloat(string(src), 32)
_, err = r.Read(buf)
if err != nil {
return err
}
n, err := strconv.ParseFloat(string(buf), 32)
if err != nil { if err != nil {
return err return err
} }
@@ -118,25 +108,17 @@ func (dst *Float4) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Float4) DecodeBinary(r io.Reader) error { func (dst *Float4) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float4{Status: Null} *dst = Float4{Status: Null}
return nil return nil
} }
if size != 4 { if len(src) != 4 {
return fmt.Errorf("invalid length for float4: %v", size) return fmt.Errorf("invalid length for float4: %v", len(src))
} }
n, err := pgio.ReadInt32(r) n := int32(binary.BigEndian.Uint32(src))
if err != nil {
return err
}
*dst = Float4{Float: math.Float32frombits(uint32(n)), Status: Present} *dst = Float4{Float: math.Float32frombits(uint32(n)), Status: Present}
return nil return nil
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
@@ -73,29 +74,17 @@ func (src *Float4Array) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Float4Array) DecodeText(r io.Reader) error { func (dst *Float4Array) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float4Array{Status: Null} *dst = Float4Array{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Float4 var elements []Float4
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -103,8 +92,11 @@ func (dst *Float4Array) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Float4 var elem Float4
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -118,19 +110,14 @@ func (dst *Float4Array) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Float4Array) DecodeBinary(r io.Reader) error { func (dst *Float4Array) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float4Array{Status: Null} *dst = Float4Array{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -148,7 +135,14 @@ func (dst *Float4Array) DecodeBinary(r io.Reader) error {
elements := make([]Float4, elementCount) elements := make([]Float4, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -236,6 +230,10 @@ func (src *Float4Array) EncodeText(w io.Writer) error {
} }
func (src *Float4Array) EncodeBinary(w io.Writer) error { func (src *Float4Array) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, Float4OID)
}
func (src *Float4Array) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -256,7 +254,7 @@ func (src *Float4Array) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = Float4OID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+9 -27
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"math" "math"
@@ -82,24 +83,13 @@ func (src *Float8) AssignTo(dst interface{}) error {
return float64AssignTo(src.Float, src.Status, dst) return float64AssignTo(src.Float, src.Status, dst)
} }
func (dst *Float8) DecodeText(r io.Reader) error { func (dst *Float8) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float8{Status: Null} *dst = Float8{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) n, err := strconv.ParseFloat(string(src), 64)
_, err = r.Read(buf)
if err != nil {
return err
}
n, err := strconv.ParseFloat(string(buf), 64)
if err != nil { if err != nil {
return err return err
} }
@@ -108,25 +98,17 @@ func (dst *Float8) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Float8) DecodeBinary(r io.Reader) error { func (dst *Float8) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float8{Status: Null} *dst = Float8{Status: Null}
return nil return nil
} }
if size != 8 { if len(src) != 8 {
return fmt.Errorf("invalid length for float4: %v", size) return fmt.Errorf("invalid length for float4: %v", len(src))
} }
n, err := pgio.ReadInt64(r) n := int64(binary.BigEndian.Uint64(src))
if err != nil {
return err
}
*dst = Float8{Float: math.Float64frombits(uint64(n)), Status: Present} *dst = Float8{Float: math.Float64frombits(uint64(n)), Status: Present}
return nil return nil
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
@@ -73,29 +74,17 @@ func (src *Float8Array) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Float8Array) DecodeText(r io.Reader) error { func (dst *Float8Array) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float8Array{Status: Null} *dst = Float8Array{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Float8 var elements []Float8
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -103,8 +92,11 @@ func (dst *Float8Array) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Float8 var elem Float8
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -118,19 +110,14 @@ func (dst *Float8Array) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Float8Array) DecodeBinary(r io.Reader) error { func (dst *Float8Array) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Float8Array{Status: Null} *dst = Float8Array{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -148,7 +135,14 @@ func (dst *Float8Array) DecodeBinary(r io.Reader) error {
elements := make([]Float8, elementCount) elements := make([]Float8, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -236,6 +230,10 @@ func (src *Float8Array) EncodeText(w io.Writer) error {
} }
func (src *Float8Array) EncodeBinary(w io.Writer) error { func (src *Float8Array) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, Float8OID)
}
func (src *Float8Array) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -256,7 +254,7 @@ func (src *Float8Array) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = Float8OID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+12 -48
View File
@@ -91,26 +91,16 @@ func (src *Inet) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Inet) DecodeText(r io.Reader) error { func (dst *Inet) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Inet{Status: Null} *dst = Inet{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size))
_, err = io.ReadFull(r, buf)
if err != nil {
return err
}
var ipnet *net.IPNet var ipnet *net.IPNet
var err error
if ip := net.ParseIP(string(buf)); ip != nil { if ip := net.ParseIP(string(src)); ip != nil {
ipv4 := ip.To4() ipv4 := ip.To4()
if ipv4 != nil { if ipv4 != nil {
ip = ipv4 ip = ipv4
@@ -119,7 +109,7 @@ func (dst *Inet) DecodeText(r io.Reader) error {
mask := net.CIDRMask(bitCount, bitCount) mask := net.CIDRMask(bitCount, bitCount)
ipnet = &net.IPNet{Mask: mask, IP: ip} ipnet = &net.IPNet{Mask: mask, IP: ip}
} else { } else {
_, ipnet, err = net.ParseCIDR(string(buf)) _, ipnet, err = net.ParseCIDR(string(src))
if err != nil { if err != nil {
return err return err
} }
@@ -129,50 +119,24 @@ func (dst *Inet) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Inet) DecodeBinary(r io.Reader) error { func (dst *Inet) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Inet{Status: Null} *dst = Inet{Status: Null}
return nil return nil
} }
if size != 8 && size != 20 { if len(src) != 8 && len(src) != 20 {
return fmt.Errorf("Received an invalid size for a inet: %d", size) return fmt.Errorf("Received an invalid size for a inet: %d", len(src))
} }
// ignore family // ignore family
_, err = pgio.ReadByte(r) bits := src[1]
if err != nil {
return err
}
bits, err := pgio.ReadByte(r)
if err != nil {
return err
}
// ignore is_cidr // ignore is_cidr
_, err = pgio.ReadByte(r) addressLength := src[3]
if err != nil {
return err
}
addressLength, err := pgio.ReadByte(r)
if err != nil {
return err
}
var ipnet net.IPNet var ipnet net.IPNet
ipnet.IP = make(net.IP, int(addressLength)) ipnet.IP = make(net.IP, int(addressLength))
_, err = r.Read(ipnet.IP) copy(ipnet.IP, src[4:])
if err != nil {
return err
}
ipnet.Mask = net.CIDRMask(int(bits), int(addressLength)*8) ipnet.Mask = net.CIDRMask(int(bits), int(addressLength)*8)
*dst = Inet{IPNet: &ipnet, Status: Present} *dst = Inet{IPNet: &ipnet, Status: Present}
+24 -28
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
"net" "net"
@@ -19,8 +20,7 @@ func (dst *InetArray) ConvertFrom(src interface{}) error {
switch value := src.(type) { switch value := src.(type) {
case InetArray: case InetArray:
*dst = value *dst = value
case CidrArray:
*dst = InetArray(value)
case []*net.IPNet: case []*net.IPNet:
if value == nil { if value == nil {
*dst = InetArray{Status: Null} *dst = InetArray{Status: Null}
@@ -39,6 +39,7 @@ func (dst *InetArray) ConvertFrom(src interface{}) error {
Status: Present, Status: Present,
} }
} }
case []net.IP: case []net.IP:
if value == nil { if value == nil {
*dst = InetArray{Status: Null} *dst = InetArray{Status: Null}
@@ -57,6 +58,7 @@ func (dst *InetArray) ConvertFrom(src interface{}) error {
Status: Present, Status: Present,
} }
} }
default: default:
if originalSrc, ok := underlyingSliceType(src); ok { if originalSrc, ok := underlyingSliceType(src); ok {
return dst.ConvertFrom(originalSrc) return dst.ConvertFrom(originalSrc)
@@ -81,6 +83,7 @@ func (src *InetArray) AssignTo(dst interface{}) error {
} else { } else {
*v = nil *v = nil
} }
case *[]net.IP: case *[]net.IP:
if src.Status == Present { if src.Status == Present {
*v = make([]net.IP, len(src.Elements)) *v = make([]net.IP, len(src.Elements))
@@ -103,29 +106,17 @@ func (src *InetArray) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *InetArray) DecodeText(r io.Reader) error { func (dst *InetArray) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = InetArray{Status: Null} *dst = InetArray{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Inet var elements []Inet
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -133,8 +124,11 @@ func (dst *InetArray) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Inet var elem Inet
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -148,19 +142,14 @@ func (dst *InetArray) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *InetArray) DecodeBinary(r io.Reader) error { func (dst *InetArray) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = InetArray{Status: Null} *dst = InetArray{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -178,7 +167,14 @@ func (dst *InetArray) DecodeBinary(r io.Reader) error {
elements := make([]Inet, elementCount) elements := make([]Inet, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
+10 -29
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"math" "math"
@@ -88,24 +89,13 @@ func (src *Int2) AssignTo(dst interface{}) error {
return int64AssignTo(int64(src.Int), src.Status, dst) return int64AssignTo(int64(src.Int), src.Status, dst)
} }
func (dst *Int2) DecodeText(r io.Reader) error { func (dst *Int2) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int2{Status: Null} *dst = Int2{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) n, err := strconv.ParseInt(string(src), 10, 16)
_, err = r.Read(buf)
if err != nil {
return err
}
n, err := strconv.ParseInt(string(buf), 10, 16)
if err != nil { if err != nil {
return err return err
} }
@@ -114,27 +104,18 @@ func (dst *Int2) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Int2) DecodeBinary(r io.Reader) error { func (dst *Int2) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int2{Status: Null} *dst = Int2{Status: Null}
return nil return nil
} }
if size != 2 { if len(src) != 2 {
return fmt.Errorf("invalid length for int2: %v", size) return fmt.Errorf("invalid length for int2: %v", len(src))
} }
n, err := pgio.ReadInt16(r) n := int16(binary.BigEndian.Uint16(src))
if err != nil { *dst = Int2{Int: n, Status: Present}
return err
}
*dst = Int2{Int: int16(n), Status: Present}
return nil return nil
} }
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
@@ -104,29 +105,17 @@ func (src *Int2Array) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Int2Array) DecodeText(r io.Reader) error { func (dst *Int2Array) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int2Array{Status: Null} *dst = Int2Array{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Int2 var elements []Int2
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -134,8 +123,11 @@ func (dst *Int2Array) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Int2 var elem Int2
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -149,19 +141,14 @@ func (dst *Int2Array) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Int2Array) DecodeBinary(r io.Reader) error { func (dst *Int2Array) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int2Array{Status: Null} *dst = Int2Array{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -179,7 +166,14 @@ func (dst *Int2Array) DecodeBinary(r io.Reader) error {
elements := make([]Int2, elementCount) elements := make([]Int2, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -267,6 +261,10 @@ func (src *Int2Array) EncodeText(w io.Writer) error {
} }
func (src *Int2Array) EncodeBinary(w io.Writer) error { func (src *Int2Array) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, Int2OID)
}
func (src *Int2Array) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -287,7 +285,7 @@ func (src *Int2Array) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = Int2OID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+9 -28
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"math" "math"
@@ -79,24 +80,13 @@ func (src *Int4) AssignTo(dst interface{}) error {
return int64AssignTo(int64(src.Int), src.Status, dst) return int64AssignTo(int64(src.Int), src.Status, dst)
} }
func (dst *Int4) DecodeText(r io.Reader) error { func (dst *Int4) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int4{Status: Null} *dst = Int4{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) n, err := strconv.ParseInt(string(src), 10, 32)
_, err = r.Read(buf)
if err != nil {
return err
}
n, err := strconv.ParseInt(string(buf), 10, 32)
if err != nil { if err != nil {
return err return err
} }
@@ -105,26 +95,17 @@ func (dst *Int4) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Int4) DecodeBinary(r io.Reader) error { func (dst *Int4) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int4{Status: Null} *dst = Int4{Status: Null}
return nil return nil
} }
if size != 4 { if len(src) != 4 {
return fmt.Errorf("invalid length for int4: %v", size) return fmt.Errorf("invalid length for int4: %v", len(src))
}
n, err := pgio.ReadInt32(r)
if err != nil {
return err
} }
n := int32(binary.BigEndian.Uint32(src))
*dst = Int4{Int: n, Status: Present} *dst = Int4{Int: n, Status: Present}
return nil return nil
} }
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
@@ -104,29 +105,17 @@ func (src *Int4Array) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Int4Array) DecodeText(r io.Reader) error { func (dst *Int4Array) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int4Array{Status: Null} *dst = Int4Array{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Int4 var elements []Int4
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -134,8 +123,11 @@ func (dst *Int4Array) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Int4 var elem Int4
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -149,19 +141,14 @@ func (dst *Int4Array) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Int4Array) DecodeBinary(r io.Reader) error { func (dst *Int4Array) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int4Array{Status: Null} *dst = Int4Array{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -179,7 +166,14 @@ func (dst *Int4Array) DecodeBinary(r io.Reader) error {
elements := make([]Int4, elementCount) elements := make([]Int4, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -267,6 +261,10 @@ func (src *Int4Array) EncodeText(w io.Writer) error {
} }
func (src *Int4Array) EncodeBinary(w io.Writer) error { func (src *Int4Array) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, Int4OID)
}
func (src *Int4Array) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -287,7 +285,7 @@ func (src *Int4Array) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = Int4OID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+9 -27
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"math" "math"
@@ -70,24 +71,13 @@ func (src *Int8) AssignTo(dst interface{}) error {
return int64AssignTo(int64(src.Int), src.Status, dst) return int64AssignTo(int64(src.Int), src.Status, dst)
} }
func (dst *Int8) DecodeText(r io.Reader) error { func (dst *Int8) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int8{Status: Null} *dst = Int8{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) n, err := strconv.ParseInt(string(src), 10, 64)
_, err = r.Read(buf)
if err != nil {
return err
}
n, err := strconv.ParseInt(string(buf), 10, 64)
if err != nil { if err != nil {
return err return err
} }
@@ -96,25 +86,17 @@ func (dst *Int8) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Int8) DecodeBinary(r io.Reader) error { func (dst *Int8) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int8{Status: Null} *dst = Int8{Status: Null}
return nil return nil
} }
if size != 8 { if len(src) != 8 {
return fmt.Errorf("invalid length for int8: %v", size) return fmt.Errorf("invalid length for int8: %v", len(src))
} }
n, err := pgio.ReadInt64(r) n := int64(binary.BigEndian.Uint64(src))
if err != nil {
return err
}
*dst = Int8{Int: n, Status: Present} *dst = Int8{Int: n, Status: Present}
return nil return nil
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
@@ -104,29 +105,17 @@ func (src *Int8Array) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Int8Array) DecodeText(r io.Reader) error { func (dst *Int8Array) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int8Array{Status: Null} *dst = Int8Array{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Int8 var elements []Int8
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -134,8 +123,11 @@ func (dst *Int8Array) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Int8 var elem Int8
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -149,19 +141,14 @@ func (dst *Int8Array) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Int8Array) DecodeBinary(r io.Reader) error { func (dst *Int8Array) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Int8Array{Status: Null} *dst = Int8Array{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -179,7 +166,14 @@ func (dst *Int8Array) DecodeBinary(r io.Reader) error {
elements := make([]Int8, elementCount) elements := make([]Int8, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -267,6 +261,10 @@ func (src *Int8Array) EncodeText(w io.Writer) error {
} }
func (src *Int8Array) EncodeBinary(w io.Writer) error { func (src *Int8Array) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, Int8OID)
}
func (src *Int8Array) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -287,7 +285,7 @@ func (src *Int8Array) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = Int8OID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+4 -4
View File
@@ -27,12 +27,12 @@ func (src *Name) AssignTo(dst interface{}) error {
return (*Text)(src).AssignTo(dst) return (*Text)(src).AssignTo(dst)
} }
func (dst *Name) DecodeText(r io.Reader) error { func (dst *Name) DecodeText(src []byte) error {
return (*Text)(dst).DecodeText(r) return (*Text)(dst).DecodeText(src)
} }
func (dst *Name) DecodeBinary(r io.Reader) error { func (dst *Name) DecodeBinary(src []byte) error {
return (*Text)(dst).DecodeBinary(r) return (*Text)(dst).DecodeBinary(src)
} }
func (src Name) EncodeText(w io.Writer) error { func (src Name) EncodeText(w io.Writer) error {
+4 -4
View File
@@ -24,12 +24,12 @@ func (src *OID) AssignTo(dst interface{}) error {
return (*pguint32)(src).AssignTo(dst) return (*pguint32)(src).AssignTo(dst)
} }
func (dst *OID) DecodeText(r io.Reader) error { func (dst *OID) DecodeText(src []byte) error {
return (*pguint32)(dst).DecodeText(r) return (*pguint32)(dst).DecodeText(src)
} }
func (dst *OID) DecodeBinary(r io.Reader) error { func (dst *OID) DecodeBinary(src []byte) error {
return (*pguint32)(dst).DecodeBinary(r) return (*pguint32)(dst).DecodeBinary(src)
} }
func (src OID) EncodeText(w io.Writer) error { func (src OID) EncodeText(w io.Writer) error {
+2 -2
View File
@@ -74,11 +74,11 @@ type Value interface {
} }
type BinaryDecoder interface { type BinaryDecoder interface {
DecodeBinary(r io.Reader) error DecodeBinary(src []byte) error
} }
type TextDecoder interface { type TextDecoder interface {
DecodeText(r io.Reader) error DecodeText(src []byte) error
} }
type BinaryEncoder interface { type BinaryEncoder interface {
+9 -28
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"strconv" "strconv"
@@ -51,24 +52,13 @@ func (src *pguint32) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *pguint32) DecodeText(r io.Reader) error { func (dst *pguint32) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = pguint32{Status: Null} *dst = pguint32{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) n, err := strconv.ParseUint(string(src), 10, 32)
_, err = r.Read(buf)
if err != nil {
return err
}
n, err := strconv.ParseUint(string(buf), 10, 32)
if err != nil { if err != nil {
return err return err
} }
@@ -77,26 +67,17 @@ func (dst *pguint32) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *pguint32) DecodeBinary(r io.Reader) error { func (dst *pguint32) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = pguint32{Status: Null} *dst = pguint32{Status: Null}
return nil return nil
} }
if size != 4 { if len(src) != 4 {
return fmt.Errorf("invalid length: %v", size) return fmt.Errorf("invalid length: %v", len(src))
}
n, err := pgio.ReadUint32(r)
if err != nil {
return err
} }
n := binary.BigEndian.Uint32(src)
*dst = pguint32{Uint: n, Status: Present} *dst = pguint32{Uint: n, Status: Present}
return nil return nil
} }
+5 -15
View File
@@ -106,27 +106,17 @@ func (src *QChar) AssignTo(dst interface{}) error {
return int64AssignTo(int64(src.Int), src.Status, dst) return int64AssignTo(int64(src.Int), src.Status, dst)
} }
func (dst *QChar) DecodeBinary(r io.Reader) error { func (dst *QChar) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = QChar{Status: Null} *dst = QChar{Status: Null}
return nil return nil
} }
if size != 1 { if len(src) != 1 {
return fmt.Errorf(`invalid length for "char": %v`, size) return fmt.Errorf(`invalid length for "char": %v`, len(src))
} }
byt, err := pgio.ReadByte(r) *dst = QChar{Int: int8(src[0]), Status: Present}
if err != nil {
return err
}
*dst = QChar{Int: int8(byt), Status: Present}
return nil return nil
} }
+5 -16
View File
@@ -71,29 +71,18 @@ func (src *Text) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Text) DecodeText(r io.Reader) error { func (dst *Text) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Text{Status: Null} *dst = Text{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) *dst = Text{String: string(src), Status: Present}
_, err = r.Read(buf)
if err != nil {
return err
}
*dst = Text{String: string(buf), Status: Present}
return nil return nil
} }
func (dst *Text) DecodeBinary(r io.Reader) error { func (dst *Text) DecodeBinary(src []byte) error {
return dst.DecodeText(r) return dst.DecodeText(src)
} }
func (src Text) EncodeText(w io.Writer) error { func (src Text) EncodeText(w io.Writer) error {
+26 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
@@ -73,29 +74,17 @@ func (src *TextArray) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *TextArray) DecodeText(r io.Reader) error { func (dst *TextArray) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = TextArray{Status: Null} *dst = TextArray{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Text var elements []Text
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -103,8 +92,11 @@ func (dst *TextArray) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Text var elem Text
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -118,19 +110,14 @@ func (dst *TextArray) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *TextArray) DecodeBinary(r io.Reader) error { func (dst *TextArray) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = TextArray{Status: Null} *dst = TextArray{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -148,7 +135,14 @@ func (dst *TextArray) DecodeBinary(r io.Reader) error {
elements := make([]Text, elementCount) elements := make([]Text, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -211,7 +205,12 @@ func (src *TextArray) EncodeText(w io.Writer) error {
} }
textElementWriter.Reset() textElementWriter.Reset()
if elem.String == "" && elem.Status == Present { if elem.Status == Null {
_, err := io.WriteString(buf, `"NULL"`)
if err != nil {
return err
}
} else if elem.String == "" {
_, err := io.WriteString(buf, `""`) _, err := io.WriteString(buf, `""`)
if err != nil { if err != nil {
return err return err
+9 -27
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
@@ -72,24 +73,13 @@ func (src *Timestamp) AssignTo(dst interface{}) error {
// DecodeText decodes from src into dst. The decoded time is considered to // DecodeText decodes from src into dst. The decoded time is considered to
// be in UTC. // be in UTC.
func (dst *Timestamp) DecodeText(r io.Reader) error { func (dst *Timestamp) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Timestamp{Status: Null} *dst = Timestamp{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) sbuf := string(src)
_, err = r.Read(buf)
if err != nil {
return err
}
sbuf := string(buf)
switch sbuf { switch sbuf {
case "infinity": case "infinity":
*dst = Timestamp{Status: Present, InfinityModifier: Infinity} *dst = Timestamp{Status: Present, InfinityModifier: Infinity}
@@ -109,25 +99,17 @@ func (dst *Timestamp) DecodeText(r io.Reader) error {
// DecodeBinary decodes from src into dst. The decoded time is considered to // DecodeBinary decodes from src into dst. The decoded time is considered to
// be in UTC. // be in UTC.
func (dst *Timestamp) DecodeBinary(r io.Reader) error { func (dst *Timestamp) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Timestamp{Status: Null} *dst = Timestamp{Status: Null}
return nil return nil
} }
if size != 8 { if len(src) != 8 {
return fmt.Errorf("invalid length for timestamp: %v", size) return fmt.Errorf("invalid length for timestamp: %v", len(src))
} }
microsecSinceY2K, err := pgio.ReadInt64(r) microsecSinceY2K := int64(binary.BigEndian.Uint64(src))
if err != nil {
return err
}
switch microsecSinceY2K { switch microsecSinceY2K {
case infinityMicrosecondOffset: case infinityMicrosecondOffset:
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
"time" "time"
@@ -74,29 +75,17 @@ func (src *TimestampArray) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *TimestampArray) DecodeText(r io.Reader) error { func (dst *TimestampArray) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = TimestampArray{Status: Null} *dst = TimestampArray{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Timestamp var elements []Timestamp
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -104,8 +93,11 @@ func (dst *TimestampArray) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Timestamp var elem Timestamp
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -119,19 +111,14 @@ func (dst *TimestampArray) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *TimestampArray) DecodeBinary(r io.Reader) error { func (dst *TimestampArray) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = TimestampArray{Status: Null} *dst = TimestampArray{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -149,7 +136,14 @@ func (dst *TimestampArray) DecodeBinary(r io.Reader) error {
elements := make([]Timestamp, elementCount) elements := make([]Timestamp, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -237,6 +231,10 @@ func (src *TimestampArray) EncodeText(w io.Writer) error {
} }
func (src *TimestampArray) EncodeBinary(w io.Writer) error { func (src *TimestampArray) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, TimestampOID)
}
func (src *TimestampArray) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -257,7 +255,7 @@ func (src *TimestampArray) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = TimestampOID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+9 -27
View File
@@ -1,6 +1,7 @@
package pgtype package pgtype
import ( import (
"encoding/binary"
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
@@ -71,24 +72,13 @@ func (src *Timestamptz) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *Timestamptz) DecodeText(r io.Reader) error { func (dst *Timestamptz) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Timestamptz{Status: Null} *dst = Timestamptz{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) sbuf := string(src)
_, err = r.Read(buf)
if err != nil {
return err
}
sbuf := string(buf)
switch sbuf { switch sbuf {
case "infinity": case "infinity":
*dst = Timestamptz{Status: Present, InfinityModifier: Infinity} *dst = Timestamptz{Status: Present, InfinityModifier: Infinity}
@@ -115,25 +105,17 @@ func (dst *Timestamptz) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *Timestamptz) DecodeBinary(r io.Reader) error { func (dst *Timestamptz) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = Timestamptz{Status: Null} *dst = Timestamptz{Status: Null}
return nil return nil
} }
if size != 8 { if len(src) != 8 {
return fmt.Errorf("invalid length for timestamptz: %v", size) return fmt.Errorf("invalid length for timestamptz: %v", len(src))
} }
microsecSinceY2K, err := pgio.ReadInt64(r) microsecSinceY2K := int64(binary.BigEndian.Uint64(src))
if err != nil {
return err
}
switch microsecSinceY2K { switch microsecSinceY2K {
case infinityMicrosecondOffset: case infinityMicrosecondOffset:
+25 -27
View File
@@ -2,6 +2,7 @@ package pgtype
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
"time" "time"
@@ -74,29 +75,17 @@ func (src *TimestamptzArray) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *TimestamptzArray) DecodeText(r io.Reader) error { func (dst *TimestamptzArray) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = TimestamptzArray{Status: Null} *dst = TimestamptzArray{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []Timestamptz var elements []Timestamptz
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -104,8 +93,11 @@ func (dst *TimestamptzArray) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem Timestamptz var elem Timestamptz
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -119,19 +111,14 @@ func (dst *TimestamptzArray) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *TimestamptzArray) DecodeBinary(r io.Reader) error { func (dst *TimestamptzArray) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = TimestamptzArray{Status: Null} *dst = TimestamptzArray{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -149,7 +136,14 @@ func (dst *TimestamptzArray) DecodeBinary(r io.Reader) error {
elements := make([]Timestamptz, elementCount) elements := make([]Timestamptz, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp : rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -237,6 +231,10 @@ func (src *TimestamptzArray) EncodeText(w io.Writer) error {
} }
func (src *TimestamptzArray) EncodeBinary(w io.Writer) error { func (src *TimestamptzArray) EncodeBinary(w io.Writer) error {
return src.encodeBinary(w, TimestamptzOID)
}
func (src *TimestamptzArray) encodeBinary(w io.Writer, elementOID int32) error {
if done, err := encodeNotPresent(w, src.Status); done { if done, err := encodeNotPresent(w, src.Status); done {
return err return err
} }
@@ -257,7 +255,7 @@ func (src *TimestamptzArray) EncodeBinary(w io.Writer) error {
} }
} }
arrayHeader.ElementOID = TimestamptzOID arrayHeader.ElementOID = elementOID
arrayHeader.Dimensions = src.Dimensions arrayHeader.Dimensions = src.Dimensions
// TODO - consider how to avoid having to buffer array before writing length - // TODO - consider how to avoid having to buffer array before writing length -
+9
View File
@@ -0,0 +1,9 @@
DecodeText and DecodeBinary take []byte instead of io.Reader
EncodeText and EncodeBinary do not write size
Add Nullable interface with IsNull() and SetNull()
The above would keep types from needing to worry about writing their own size. Could make EncodeText and DecodeText easier to use with sql.Scanner and driver.Valuer. SetNull() could be removed as DecodeText and DecodeBinary could interpret a nil slice as null.
EncodeText and EncodeBinary could return (null bool, err error). That would finish removing Nullable interface.
Also, consider whether arrays and ranges could be represented as generic data types or more common code could be extracted instead of using code generation.
+22 -36
View File
@@ -73,29 +73,17 @@ func (src *<%= pgtype_array_type %>) AssignTo(dst interface{}) error {
return nil return nil
} }
func (dst *<%= pgtype_array_type %>) DecodeText(r io.Reader) error { func (dst *<%= pgtype_array_type %>) DecodeText(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = <%= pgtype_array_type %>{Status: Null} *dst = <%= pgtype_array_type %>{Status: Null}
return nil return nil
} }
buf := make([]byte, int(size)) uta, err := ParseUntypedTextArray(string(src))
_, err = io.ReadFull(r, buf)
if err != nil { if err != nil {
return err return err
} }
uta, err := ParseUntypedTextArray(string(buf))
if err != nil {
return err
}
textElementReader := NewTextElementReader(r)
var elements []<%= pgtype_element_type %> var elements []<%= pgtype_element_type %>
if len(uta.Elements) > 0 { if len(uta.Elements) > 0 {
@@ -103,8 +91,11 @@ func (dst *<%= pgtype_array_type %>) DecodeText(r io.Reader) error {
for i, s := range uta.Elements { for i, s := range uta.Elements {
var elem <%= pgtype_element_type %> var elem <%= pgtype_element_type %>
textElementReader.Reset(s) var elemSrc []byte
err = elem.DecodeText(textElementReader) if s != "NULL" {
elemSrc = []byte(s)
}
err = elem.DecodeText(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -118,19 +109,14 @@ func (dst *<%= pgtype_array_type %>) DecodeText(r io.Reader) error {
return nil return nil
} }
func (dst *<%= pgtype_array_type %>) DecodeBinary(r io.Reader) error { func (dst *<%= pgtype_array_type %>) DecodeBinary(src []byte) error {
size, err := pgio.ReadInt32(r) if src == nil {
if err != nil {
return err
}
if size == -1 {
*dst = <%= pgtype_array_type %>{Status: Null} *dst = <%= pgtype_array_type %>{Status: Null}
return nil return nil
} }
var arrayHeader ArrayHeader var arrayHeader ArrayHeader
err = arrayHeader.DecodeBinary(r) rp, err := arrayHeader.DecodeBinary(src)
if err != nil { if err != nil {
return err return err
} }
@@ -148,7 +134,14 @@ func (dst *<%= pgtype_array_type %>) DecodeBinary(r io.Reader) error {
elements := make([]<%= pgtype_element_type %>, elementCount) elements := make([]<%= pgtype_element_type %>, elementCount)
for i := range elements { for i := range elements {
err = elements[i].DecodeBinary(r) elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
rp += 4
var elemSrc []byte
if elemLen >= 0 {
elemSrc = src[rp:rp+elemLen]
rp += elemLen
}
err = elements[i].DecodeBinary(elemSrc)
if err != nil { if err != nil {
return err return err
} }
@@ -211,16 +204,9 @@ func (src *<%= pgtype_array_type %>) EncodeText(w io.Writer) error {
} }
textElementWriter.Reset() textElementWriter.Reset()
if elem.String == "" && elem.Status == Present { err = elem.EncodeText(textElementWriter)
_, err := io.WriteString(buf, `""`) if err != nil {
if err != nil { return err
return err
}
} else {
err = elem.EncodeText(textElementWriter)
if err != nil {
return err
}
} }
for _, dec := range dimElemCounts { for _, dec := range dimElemCounts {
+4 -4
View File
@@ -14,12 +14,12 @@ func (src *VarcharArray) AssignTo(dst interface{}) error {
return (*TextArray)(src).AssignTo(dst) return (*TextArray)(src).AssignTo(dst)
} }
func (dst *VarcharArray) DecodeText(r io.Reader) error { func (dst *VarcharArray) DecodeText(src []byte) error {
return (*TextArray)(dst).DecodeText(r) return (*TextArray)(dst).DecodeText(src)
} }
func (dst *VarcharArray) DecodeBinary(r io.Reader) error { func (dst *VarcharArray) DecodeBinary(src []byte) error {
return (*TextArray)(dst).DecodeBinary(r) return (*TextArray)(dst).DecodeBinary(src)
} }
func (src *VarcharArray) EncodeText(w io.Writer) error { func (src *VarcharArray) EncodeText(w io.Writer) error {
+4 -4
View File
@@ -33,12 +33,12 @@ func (src *XID) AssignTo(dst interface{}) error {
return (*pguint32)(src).AssignTo(dst) return (*pguint32)(src).AssignTo(dst)
} }
func (dst *XID) DecodeText(r io.Reader) error { func (dst *XID) DecodeText(src []byte) error {
return (*pguint32)(dst).DecodeText(r) return (*pguint32)(dst).DecodeText(src)
} }
func (dst *XID) DecodeBinary(r io.Reader) error { func (dst *XID) DecodeBinary(src []byte) error {
return (*pguint32)(dst).DecodeBinary(r) return (*pguint32)(dst).DecodeBinary(src)
} }
func (src XID) EncodeText(w io.Writer) error { func (src XID) EncodeText(w io.Writer) error {