...

Source file src/github.com/jackc/pgx/v5/pgproto3/parse.go

Documentation: github.com/jackc/pgx/v5/pgproto3

     1  package pgproto3
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"encoding/json"
     7  	"errors"
     8  	"math"
     9  
    10  	"github.com/jackc/pgx/v5/internal/pgio"
    11  )
    12  
    13  type Parse struct {
    14  	Name          string
    15  	Query         string
    16  	ParameterOIDs []uint32
    17  }
    18  
    19  // Frontend identifies this message as sendable by a PostgreSQL frontend.
    20  func (*Parse) Frontend() {}
    21  
    22  // Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
    23  // type identifier and 4 byte message length.
    24  func (dst *Parse) Decode(src []byte) error {
    25  	*dst = Parse{}
    26  
    27  	buf := bytes.NewBuffer(src)
    28  
    29  	b, err := buf.ReadBytes(0)
    30  	if err != nil {
    31  		return err
    32  	}
    33  	dst.Name = string(b[:len(b)-1])
    34  
    35  	b, err = buf.ReadBytes(0)
    36  	if err != nil {
    37  		return err
    38  	}
    39  	dst.Query = string(b[:len(b)-1])
    40  
    41  	if buf.Len() < 2 {
    42  		return &invalidMessageFormatErr{messageType: "Parse"}
    43  	}
    44  	parameterOIDCount := int(binary.BigEndian.Uint16(buf.Next(2)))
    45  
    46  	for i := 0; i < parameterOIDCount; i++ {
    47  		if buf.Len() < 4 {
    48  			return &invalidMessageFormatErr{messageType: "Parse"}
    49  		}
    50  		dst.ParameterOIDs = append(dst.ParameterOIDs, binary.BigEndian.Uint32(buf.Next(4)))
    51  	}
    52  
    53  	return nil
    54  }
    55  
    56  // Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
    57  func (src *Parse) Encode(dst []byte) ([]byte, error) {
    58  	dst, sp := beginMessage(dst, 'P')
    59  
    60  	dst = append(dst, src.Name...)
    61  	dst = append(dst, 0)
    62  	dst = append(dst, src.Query...)
    63  	dst = append(dst, 0)
    64  
    65  	if len(src.ParameterOIDs) > math.MaxUint16 {
    66  		return nil, errors.New("too many parameter oids")
    67  	}
    68  	dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs)))
    69  	for _, oid := range src.ParameterOIDs {
    70  		dst = pgio.AppendUint32(dst, oid)
    71  	}
    72  
    73  	return finishMessage(dst, sp)
    74  }
    75  
    76  // MarshalJSON implements encoding/json.Marshaler.
    77  func (src Parse) MarshalJSON() ([]byte, error) {
    78  	return json.Marshal(struct {
    79  		Type          string
    80  		Name          string
    81  		Query         string
    82  		ParameterOIDs []uint32
    83  	}{
    84  		Type:          "Parse",
    85  		Name:          src.Name,
    86  		Query:         src.Query,
    87  		ParameterOIDs: src.ParameterOIDs,
    88  	})
    89  }
    90  

View as plain text