package pgproto3
import (
)
const (
TextFormat = 0
BinaryFormat = 1
)
type FieldDescription struct {
Name []byte
TableOID uint32
TableAttributeNumber uint16
DataTypeOID uint32
DataTypeSize int16
TypeModifier int32
Format int16
}
func ( FieldDescription) () ([]byte, error) {
return json.Marshal(struct {
string
uint32
uint16
uint32
int16
int32
int16
}{
: string(.Name),
: .TableOID,
: .TableAttributeNumber,
: .DataTypeOID,
: .DataTypeSize,
: .TypeModifier,
: .Format,
})
}
type RowDescription struct {
Fields []FieldDescription
}
func (*RowDescription) () {}
func ( *RowDescription) ( []byte) error {
if len() < 2 {
return &invalidMessageFormatErr{messageType: "RowDescription"}
}
:= int(binary.BigEndian.Uint16())
:= 2
.Fields = .Fields[0:0]
for range {
var FieldDescription
:= bytes.IndexByte([:], 0)
if < 0 {
return &invalidMessageFormatErr{messageType: "RowDescription"}
}
.Name = [ : +]
+= + 1
if len([:]) < 18 {
return &invalidMessageFormatErr{messageType: "RowDescription"}
}
.TableOID = binary.BigEndian.Uint32([:])
+= 4
.TableAttributeNumber = binary.BigEndian.Uint16([:])
+= 2
.DataTypeOID = binary.BigEndian.Uint32([:])
+= 4
.DataTypeSize = int16(binary.BigEndian.Uint16([:]))
+= 2
.TypeModifier = int32(binary.BigEndian.Uint32([:]))
+= 4
.Format = int16(binary.BigEndian.Uint16([:]))
+= 2
.Fields = append(.Fields, )
}
return nil
}
func ( *RowDescription) ( []byte) ([]byte, error) {
, := beginMessage(, 'T')
if len(.Fields) > math.MaxUint16 {
return nil, errors.New("too many fields")
}
= pgio.AppendUint16(, uint16(len(.Fields)))
for , := range .Fields {
= append(, .Name...)
= append(, 0)
= pgio.AppendUint32(, .TableOID)
= pgio.AppendUint16(, .TableAttributeNumber)
= pgio.AppendUint32(, .DataTypeOID)
= pgio.AppendInt16(, .DataTypeSize)
= pgio.AppendInt32(, .TypeModifier)
= pgio.AppendInt16(, .Format)
}
return finishMessage(, )
}
func ( RowDescription) () ([]byte, error) {
return json.Marshal(struct {
string
[]FieldDescription
}{
: "RowDescription",
: .Fields,
})
}
func ( *RowDescription) ( []byte) error {
var struct {
[]struct {
string
uint32
uint16
uint32
int16
int32
int16
}
}
if := json.Unmarshal(, &); != nil {
return
}
.Fields = make([]FieldDescription, len(.))
for , := range . {
.Fields[] = FieldDescription{
Name: []byte(.),
TableOID: .,
TableAttributeNumber: .,
DataTypeOID: .,
DataTypeSize: .,
TypeModifier: .,
Format: .,
}
}
return nil
}