mirror of https://github.com/jackc/pgx.git
commit
bf182c76bc
60
values.go
60
values.go
|
@ -19,6 +19,7 @@ const (
|
|||
BoolOid = 16
|
||||
ByteaOid = 17
|
||||
CharOid = 18
|
||||
NameOid = 19
|
||||
Int8Oid = 20
|
||||
Int2Oid = 21
|
||||
Int4Oid = 23
|
||||
|
@ -102,6 +103,7 @@ func init() {
|
|||
"int2": BinaryFormatCode,
|
||||
"int4": BinaryFormatCode,
|
||||
"int8": BinaryFormatCode,
|
||||
"name": BinaryFormatCode,
|
||||
"oid": BinaryFormatCode,
|
||||
"record": BinaryFormatCode,
|
||||
"text": BinaryFormatCode,
|
||||
|
@ -261,6 +263,57 @@ func (n NullString) Encode(w *WriteBuf, oid Oid) error {
|
|||
return encodeString(w, oid, n.String)
|
||||
}
|
||||
|
||||
// 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
|
||||
// name data type is used.
|
||||
//
|
||||
// Note that the underlying Go data type of pgx.Name is string,
|
||||
// so there is no way to enforce the 63-byte length. Inputting
|
||||
// a longer name into PostgreSQL will result in silent truncation
|
||||
// to 63 bytes.
|
||||
//
|
||||
// Also, if you have custom-compiled PostgreSQL and set
|
||||
// NAMEDATALEN to a different value, obviously that number of
|
||||
// bytes applies, rather than the default 63.
|
||||
type Name string
|
||||
|
||||
// NullName represents a pgx.Name that may be null. NullName 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 NullName struct {
|
||||
Name Name
|
||||
Valid bool // Valid is true if Name is not NULL
|
||||
}
|
||||
|
||||
func (n *NullName) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != NameOid {
|
||||
return SerializationError(fmt.Sprintf("NullName.Scan cannot decode OID %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Name, n.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
|
||||
n.Valid = true
|
||||
n.Name = Name(decodeText(vr))
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullName) FormatCode() int16 { return TextFormatCode }
|
||||
|
||||
func (n NullName) Encode(w *WriteBuf, oid Oid) error {
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
return encodeString(w, oid, string(n.Name))
|
||||
}
|
||||
|
||||
// The pgx.Char type is for PostgreSQL's special 8-bit-only
|
||||
// "char" type more akin to the C language's char type, or Go's byte type.
|
||||
// (Note that the name in PostgreSQL itself is "char", in double-quotes,
|
||||
|
@ -911,6 +964,10 @@ func Encode(wbuf *WriteBuf, oid Oid, arg interface{}) error {
|
|||
return encodeUInt(wbuf, oid, arg)
|
||||
case Char:
|
||||
return encodeChar(wbuf, oid, 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
|
||||
return encodeString(wbuf, oid, string(arg))
|
||||
case int8:
|
||||
return encodeInt8(wbuf, oid, arg)
|
||||
case uint8:
|
||||
|
@ -1089,6 +1146,9 @@ func Decode(vr *ValueReader, d interface{}) error {
|
|||
*v = uint64(n)
|
||||
case *Char:
|
||||
*v = decodeChar(vr)
|
||||
case *Name:
|
||||
// name goes over the wire just like text
|
||||
*v = Name(decodeText(vr))
|
||||
case *Oid:
|
||||
*v = decodeOid(vr)
|
||||
case *Xid:
|
||||
|
|
|
@ -562,6 +562,7 @@ func TestNullX(t *testing.T) {
|
|||
i16 pgx.NullInt16
|
||||
i32 pgx.NullInt32
|
||||
c pgx.NullChar
|
||||
n pgx.NullName
|
||||
oid pgx.NullOid
|
||||
xid pgx.NullXid
|
||||
cid pgx.NullCid
|
||||
|
@ -596,6 +597,8 @@ func TestNullX(t *testing.T) {
|
|||
{"select $1::\"char\"", []interface{}{pgx.NullChar{Char: 1, Valid: true}}, []interface{}{&actual.c}, allTypes{c: pgx.NullChar{Char: 1, Valid: true}}},
|
||||
{"select $1::\"char\"", []interface{}{pgx.NullChar{Char: 1, Valid: false}}, []interface{}{&actual.c}, allTypes{c: pgx.NullChar{Char: 0, Valid: false}}},
|
||||
{"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.NullString{String: "foo", Valid: true}}, []interface{}{&actual.s}, allTypes{s: pgx.NullString{String: "foo", Valid: true}}},
|
||||
{"select $1::name", []interface{}{pgx.NullString{String: "foo", Valid: false}}, []interface{}{&actual.s}, allTypes{s: pgx.NullString{String: "", 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}}},
|
||||
|
|
Loading…
Reference in New Issue