Adds NullAclItem

This commit is contained in:
Manni Wood 2016-10-27 21:33:56 -04:00
parent 3734a92a71
commit f73791c6c9
2 changed files with 53 additions and 0 deletions

View File

@ -44,6 +44,7 @@ const (
Int8ArrayOid = 1016
Float4ArrayOid = 1021
Float8ArrayOid = 1022
AclItemOid = 1033
InetArrayOid = 1041
VarcharOid = 1043
DateOid = 1082
@ -89,6 +90,7 @@ func init() {
"_timestamp": BinaryFormatCode,
"_timestamptz": BinaryFormatCode,
"_varchar": BinaryFormatCode,
"aclitem": TextFormatCode, // Pg's src/backend/utils/adt/acl.c has only in/out (text) not send/recv (bin)
"bool": BinaryFormatCode,
"bytea": BinaryFormatCode,
"char": BinaryFormatCode,
@ -263,6 +265,47 @@ func (n NullString) Encode(w *WriteBuf, oid Oid) error {
return encodeString(w, oid, n.String)
}
// AclItem is used for PostgreSQL's aclitem data type.
type AclItem string
// NullAclItem represents a pgx.AclItem that may be null. NullAclItem implements the
// Scanner and Encoder interfaces so it may be used both as an argument to
// Query[Row] and a destination for Scan for prepared and unprepared queries.
//
// If Valid is false then the value is NULL.
type NullAclItem struct {
AclItem AclItem
Valid bool // Valid is true if AclItem is not NULL
}
func (n *NullAclItem) Scan(vr *ValueReader) error {
if vr.Type().DataType != AclItemOid {
return SerializationError(fmt.Sprintf("NullAclItem.Scan cannot decode OID %d", vr.Type().DataType))
}
if vr.Len() == -1 {
n.AclItem, n.Valid = "", false
return nil
}
n.Valid = true
n.AclItem = AclItem(decodeText(vr))
return vr.Err()
}
// Particularly important to return TextFormatCode, seeing as Postgres
// only ever sends aclitem as text, not binary.
func (n NullAclItem) FormatCode() int16 { return TextFormatCode }
func (n NullAclItem) Encode(w *WriteBuf, oid Oid) error {
if !n.Valid {
w.WriteInt32(-1)
return nil
}
return encodeString(w, oid, string(n.AclItem))
}
// Name is a type used for PostgreSQL's special 63-byte
// name data type, used for identifiers like table names.
// The pg_class.relname column is a good example of where the
@ -964,6 +1007,10 @@ func Encode(wbuf *WriteBuf, oid Oid, arg interface{}) error {
return encodeUInt(wbuf, oid, arg)
case Char:
return encodeChar(wbuf, oid, arg)
case AclItem:
// The aclitem data type goes over the wire using the same format as string,
// so just cast to string and use encodeString
return encodeString(wbuf, oid, string(arg))
case Name:
// The name data type goes over the wire using the same format as string,
// so just cast to string and use encodeString
@ -1146,6 +1193,9 @@ func Decode(vr *ValueReader, d interface{}) error {
*v = uint64(n)
case *Char:
*v = decodeChar(vr)
case *AclItem:
// aclitem goes over the wire just like text
*v = AclItem(decodeText(vr))
case *Name:
// name goes over the wire just like text
*v = Name(decodeText(vr))

View File

@ -562,6 +562,7 @@ func TestNullX(t *testing.T) {
i16 pgx.NullInt16
i32 pgx.NullInt32
c pgx.NullChar
a pgx.NullAclItem
n pgx.NullName
oid pgx.NullOid
xid pgx.NullXid
@ -599,6 +600,8 @@ func TestNullX(t *testing.T) {
{"select $1::\"char\"", []interface{}{pgx.NullChar{Char: 255, Valid: true}}, []interface{}{&actual.c}, allTypes{c: pgx.NullChar{Char: 255, Valid: true}}},
{"select $1::name", []interface{}{pgx.NullName{Name: "foo", Valid: true}}, []interface{}{&actual.n}, allTypes{n: pgx.NullName{Name: "foo", Valid: true}}},
{"select $1::name", []interface{}{pgx.NullName{Name: "foo", Valid: false}}, []interface{}{&actual.n}, allTypes{n: pgx.NullName{Name: "", Valid: false}}},
{"select $1::aclitem", []interface{}{pgx.NullAclItem{AclItem: "postgres=arwdDxt/postgres", Valid: true}}, []interface{}{&actual.a}, allTypes{a: pgx.NullAclItem{AclItem: "postgres=arwdDxt/postgres", Valid: true}}},
{"select $1::aclitem", []interface{}{pgx.NullAclItem{AclItem: "postgres=arwdDxt/postgres", Valid: false}}, []interface{}{&actual.a}, allTypes{a: pgx.NullAclItem{AclItem: "", Valid: false}}},
{"select $1::cid", []interface{}{pgx.NullCid{Cid: 1, Valid: true}}, []interface{}{&actual.cid}, allTypes{cid: pgx.NullCid{Cid: 1, Valid: true}}},
{"select $1::cid", []interface{}{pgx.NullCid{Cid: 1, Valid: false}}, []interface{}{&actual.cid}, allTypes{cid: pgx.NullCid{Cid: 0, Valid: false}}},
{"select $1::cid", []interface{}{pgx.NullCid{Cid: 4294967295, Valid: true}}, []interface{}{&actual.cid}, allTypes{cid: pgx.NullCid{Cid: 4294967295, Valid: true}}},