package pgproto3
import (
)
type Bind struct {
DestinationPortal string
PreparedStatement string
ParameterFormatCodes []int16
Parameters [][]byte
ResultFormatCodes []int16
}
func (*Bind) () {}
func ( *Bind) ( []byte) error {
* = Bind{}
:= bytes.IndexByte(, 0)
if < 0 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
.DestinationPortal = string([:])
:= + 1
= bytes.IndexByte([:], 0)
if < 0 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
.PreparedStatement = string([ : +])
+= + 1
if len([:]) < 2 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
:= int(binary.BigEndian.Uint16([:]))
+= 2
if > 0 {
.ParameterFormatCodes = make([]int16, )
if len([:]) < len(.ParameterFormatCodes)*2 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
for := range {
.ParameterFormatCodes[] = int16(binary.BigEndian.Uint16([:]))
+= 2
}
}
if len([:]) < 2 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
:= int(binary.BigEndian.Uint16([:]))
+= 2
if > 0 {
.Parameters = make([][]byte, )
for := range {
if len([:]) < 4 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
:= int(int32(binary.BigEndian.Uint32([:])))
+= 4
if == -1 {
continue
}
if < 0 || len([:]) < {
return &invalidMessageFormatErr{messageType: "Bind"}
}
.Parameters[] = [ : +]
+=
}
}
if len([:]) < 2 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
:= int(binary.BigEndian.Uint16([:]))
+= 2
.ResultFormatCodes = make([]int16, )
if len([:]) < len(.ResultFormatCodes)*2 {
return &invalidMessageFormatErr{messageType: "Bind"}
}
for := range {
.ResultFormatCodes[] = int16(binary.BigEndian.Uint16([:]))
+= 2
}
return nil
}
func ( *Bind) ( []byte) ([]byte, error) {
, := beginMessage(, 'B')
= append(, .DestinationPortal...)
= append(, 0)
= append(, .PreparedStatement...)
= append(, 0)
if len(.ParameterFormatCodes) > math.MaxUint16 {
return nil, errors.New("too many parameter format codes")
}
= pgio.AppendUint16(, uint16(len(.ParameterFormatCodes)))
for , := range .ParameterFormatCodes {
= pgio.AppendInt16(, )
}
if len(.Parameters) > math.MaxUint16 {
return nil, errors.New("too many parameters")
}
= pgio.AppendUint16(, uint16(len(.Parameters)))
for , := range .Parameters {
if == nil {
= pgio.AppendInt32(, -1)
continue
}
= pgio.AppendInt32(, int32(len()))
= append(, ...)
}
if len(.ResultFormatCodes) > math.MaxUint16 {
return nil, errors.New("too many result format codes")
}
= pgio.AppendUint16(, uint16(len(.ResultFormatCodes)))
for , := range .ResultFormatCodes {
= pgio.AppendInt16(, )
}
return finishMessage(, )
}
func ( Bind) () ([]byte, error) {
:= make([]map[string]string, len(.Parameters))
for , := range .Parameters {
if == nil {
continue
}
:= true
if len(.ParameterFormatCodes) == 1 {
= .ParameterFormatCodes[0] == 0
} else if len(.ParameterFormatCodes) > 1 {
= .ParameterFormatCodes[] == 0
}
if {
[] = map[string]string{"text": string()}
} else {
[] = map[string]string{"binary": hex.EncodeToString()}
}
}
return json.Marshal(struct {
string
string
string
[]int16
[]map[string]string
[]int16
}{
: "Bind",
: .DestinationPortal,
: .PreparedStatement,
: .ParameterFormatCodes,
: ,
: .ResultFormatCodes,
})
}
func ( *Bind) ( []byte) error {
if string() == "null" {
return nil
}
var struct {
string
string
[]int16
[]map[string]string
[]int16
}
:= json.Unmarshal(, &)
if != nil {
return
}
.DestinationPortal = .
.PreparedStatement = .
.ParameterFormatCodes = .
.Parameters = make([][]byte, len(.))
.ResultFormatCodes = .
for , := range . {
.Parameters[], = getValueFromJSON()
if != nil {
return fmt.Errorf("cannot get param %d: %w", , )
}
}
return nil
}