Allow types to specify preference format result and param formats
This will be useful for array and composite types that may have to support elements that may not support binary encoding. It also is slightly more convenient for text-ish types to have a default format of text.
This commit is contained in:
@@ -33,6 +33,10 @@ func (src *BPChar) AssignTo(dst interface{}) error {
|
|||||||
return (*Text)(src).AssignTo(dst)
|
return (*Text)(src).AssignTo(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (BPChar) PreferredResultFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (dst *BPChar) DecodeText(ci *ConnInfo, src []byte) error {
|
func (dst *BPChar) DecodeText(ci *ConnInfo, src []byte) error {
|
||||||
return (*Text)(dst).DecodeText(ci, src)
|
return (*Text)(dst).DecodeText(ci, src)
|
||||||
}
|
}
|
||||||
@@ -41,6 +45,10 @@ func (dst *BPChar) DecodeBinary(ci *ConnInfo, src []byte) error {
|
|||||||
return (*Text)(dst).DecodeBinary(ci, src)
|
return (*Text)(dst).DecodeBinary(ci, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (BPChar) PreferredParamFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (src BPChar) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
func (src BPChar) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
||||||
return (Text)(src).EncodeText(ci, buf)
|
return (Text)(src).EncodeText(ci, buf)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ func (src *enumType) AssignTo(dst interface{}) error {
|
|||||||
return errors.Errorf("cannot decode %#v into %T", src, dst)
|
return errors.Errorf("cannot decode %#v into %T", src, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (enumType) PreferredResultFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (dst *enumType) DecodeText(ci *ConnInfo, src []byte) error {
|
func (dst *enumType) DecodeText(ci *ConnInfo, src []byte) error {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
dst.status = Null
|
dst.status = Null
|
||||||
@@ -152,6 +156,10 @@ func (dst *enumType) DecodeBinary(ci *ConnInfo, src []byte) error {
|
|||||||
return dst.DecodeText(ci, src)
|
return dst.DecodeText(ci, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (enumType) PreferredParamFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (src enumType) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
func (src enumType) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
||||||
switch src.status {
|
switch src.status {
|
||||||
case Null:
|
case Null:
|
||||||
|
|||||||
@@ -113,6 +113,10 @@ func (src *JSON) AssignTo(dst interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (JSON) PreferredResultFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (dst *JSON) DecodeText(ci *ConnInfo, src []byte) error {
|
func (dst *JSON) DecodeText(ci *ConnInfo, src []byte) error {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
*dst = JSON{Status: Null}
|
*dst = JSON{Status: Null}
|
||||||
@@ -127,6 +131,10 @@ func (dst *JSON) DecodeBinary(ci *ConnInfo, src []byte) error {
|
|||||||
return dst.DecodeText(ci, src)
|
return dst.DecodeText(ci, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (JSON) PreferredParamFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (src JSON) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
func (src JSON) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
||||||
switch src.Status {
|
switch src.Status {
|
||||||
case Null:
|
case Null:
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ func (src *JSONB) AssignTo(dst interface{}) error {
|
|||||||
return (*JSON)(src).AssignTo(dst)
|
return (*JSON)(src).AssignTo(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (JSONB) PreferredResultFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (dst *JSONB) DecodeText(ci *ConnInfo, src []byte) error {
|
func (dst *JSONB) DecodeText(ci *ConnInfo, src []byte) error {
|
||||||
return (*JSON)(dst).DecodeText(ci, src)
|
return (*JSON)(dst).DecodeText(ci, src)
|
||||||
}
|
}
|
||||||
@@ -43,6 +47,10 @@ func (dst *JSONB) DecodeBinary(ci *ConnInfo, src []byte) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (JSONB) PreferredParamFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (src JSONB) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
func (src JSONB) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
||||||
return (JSON)(src).EncodeText(ci, buf)
|
return (JSON)(src).EncodeText(ci, buf)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,6 +142,18 @@ type TypeValue interface {
|
|||||||
TypeName() string
|
TypeName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResultFormatPreferrer allows a type to specify its preferred result format instead of it being inferred from
|
||||||
|
// whether it is also a BinaryDecoder.
|
||||||
|
type ResultFormatPreferrer interface {
|
||||||
|
PreferredResultFormat() int16
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamFormatPreferrer allows a type to specify its preferred param format instead of it being inferred from
|
||||||
|
// whether it is also a BinaryEncoder.
|
||||||
|
type ParamFormatPreferrer interface {
|
||||||
|
PreferredParamFormat() int16
|
||||||
|
}
|
||||||
|
|
||||||
type BinaryDecoder interface {
|
type BinaryDecoder interface {
|
||||||
// DecodeBinary decodes src into BinaryDecoder. If src is nil then the
|
// DecodeBinary decodes src into BinaryDecoder. If src is nil then the
|
||||||
// original SQL value is NULL. BinaryDecoder takes ownership of src. The
|
// original SQL value is NULL. BinaryDecoder takes ownership of src. The
|
||||||
@@ -364,7 +376,9 @@ func (ci *ConnInfo) RegisterDataType(t DataType) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
var formatCode int16
|
var formatCode int16
|
||||||
if _, ok := t.Value.(BinaryEncoder); ok {
|
if pfp, ok := t.Value.(ParamFormatPreferrer); ok {
|
||||||
|
formatCode = pfp.PreferredParamFormat()
|
||||||
|
} else if _, ok := t.Value.(BinaryEncoder); ok {
|
||||||
formatCode = BinaryFormatCode
|
formatCode = BinaryFormatCode
|
||||||
}
|
}
|
||||||
ci.oidToParamFormatCode[t.OID] = formatCode
|
ci.oidToParamFormatCode[t.OID] = formatCode
|
||||||
@@ -372,7 +386,9 @@ func (ci *ConnInfo) RegisterDataType(t DataType) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
var formatCode int16
|
var formatCode int16
|
||||||
if _, ok := t.Value.(BinaryDecoder); ok {
|
if rfp, ok := t.Value.(ResultFormatPreferrer); ok {
|
||||||
|
formatCode = rfp.PreferredResultFormat()
|
||||||
|
} else if _, ok := t.Value.(BinaryDecoder); ok {
|
||||||
formatCode = BinaryFormatCode
|
formatCode = BinaryFormatCode
|
||||||
}
|
}
|
||||||
ci.oidToResultFormatCode[t.OID] = formatCode
|
ci.oidToResultFormatCode[t.OID] = formatCode
|
||||||
|
|||||||
@@ -44,6 +44,26 @@ func mustParseMacaddr(t testing.TB, s string) net.HardwareAddr {
|
|||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConnInfoResultFormatCodeForOID(t *testing.T) {
|
||||||
|
ci := pgtype.NewConnInfo()
|
||||||
|
|
||||||
|
// pgtype.JSONB implements BinaryDecoder but also implements ResultFormatPreferrer to override it to text.
|
||||||
|
assert.Equal(t, int16(pgtype.TextFormatCode), ci.ResultFormatCodeForOID(pgtype.JSONBOID))
|
||||||
|
|
||||||
|
// pgtype.Int4 implements BinaryDecoder but does not implement ResultFormatPreferrer so it should be binary.
|
||||||
|
assert.Equal(t, int16(pgtype.BinaryFormatCode), ci.ResultFormatCodeForOID(pgtype.Int4OID))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConnInfoParamFormatCodeForOID(t *testing.T) {
|
||||||
|
ci := pgtype.NewConnInfo()
|
||||||
|
|
||||||
|
// pgtype.JSONB implements BinaryEncoder but also implements ParamFormatPreferrer to override it to text.
|
||||||
|
assert.Equal(t, int16(pgtype.TextFormatCode), ci.ParamFormatCodeForOID(pgtype.JSONBOID))
|
||||||
|
|
||||||
|
// pgtype.Int4 implements BinaryEncoder but does not implement ParamFormatPreferrer so it should be binary.
|
||||||
|
assert.Equal(t, int16(pgtype.BinaryFormatCode), ci.ParamFormatCodeForOID(pgtype.Int4OID))
|
||||||
|
}
|
||||||
|
|
||||||
func TestConnInfoScanUnknownOIDToStringsAndBytes(t *testing.T) {
|
func TestConnInfoScanUnknownOIDToStringsAndBytes(t *testing.T) {
|
||||||
unknownOID := uint32(999999)
|
unknownOID := uint32(999999)
|
||||||
srcBuf := []byte("foo")
|
srcBuf := []byte("foo")
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ func (src *Text) AssignTo(dst interface{}) error {
|
|||||||
return errors.Errorf("cannot decode %#v into %T", src, dst)
|
return errors.Errorf("cannot decode %#v into %T", src, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Text) PreferredResultFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (dst *Text) DecodeText(ci *ConnInfo, src []byte) error {
|
func (dst *Text) DecodeText(ci *ConnInfo, src []byte) error {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
*dst = Text{Status: Null}
|
*dst = Text{Status: Null}
|
||||||
@@ -99,6 +103,10 @@ func (dst *Text) DecodeBinary(ci *ConnInfo, src []byte) error {
|
|||||||
return dst.DecodeText(ci, src)
|
return dst.DecodeText(ci, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Text) PreferredParamFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (src Text) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
func (src Text) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
||||||
switch src.Status {
|
switch src.Status {
|
||||||
case Null:
|
case Null:
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ func (src *Varchar) AssignTo(dst interface{}) error {
|
|||||||
return (*Text)(src).AssignTo(dst)
|
return (*Text)(src).AssignTo(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Varchar) PreferredResultFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (dst *Varchar) DecodeText(ci *ConnInfo, src []byte) error {
|
func (dst *Varchar) DecodeText(ci *ConnInfo, src []byte) error {
|
||||||
return (*Text)(dst).DecodeText(ci, src)
|
return (*Text)(dst).DecodeText(ci, src)
|
||||||
}
|
}
|
||||||
@@ -31,6 +35,10 @@ func (dst *Varchar) DecodeBinary(ci *ConnInfo, src []byte) error {
|
|||||||
return (*Text)(dst).DecodeBinary(ci, src)
|
return (*Text)(dst).DecodeBinary(ci, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Varchar) PreferredParamFormat() int16 {
|
||||||
|
return TextFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
func (src Varchar) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
func (src Varchar) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
|
||||||
return (Text)(src).EncodeText(ci, buf)
|
return (Text)(src).EncodeText(ci, buf)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user