...

Source file src/github.com/jackc/pgproto3/v2/copy_in_response.go

Documentation: github.com/jackc/pgproto3/v2

     1  package pgproto3
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"encoding/json"
     7  	"errors"
     8  	"math"
     9  
    10  	"github.com/jackc/pgio"
    11  )
    12  
    13  type CopyInResponse struct {
    14  	OverallFormat     byte
    15  	ColumnFormatCodes []uint16
    16  }
    17  
    18  // Backend identifies this message as sendable by the PostgreSQL backend.
    19  func (*CopyInResponse) Backend() {}
    20  
    21  // Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
    22  // type identifier and 4 byte message length.
    23  func (dst *CopyInResponse) Decode(src []byte) error {
    24  	buf := bytes.NewBuffer(src)
    25  
    26  	if buf.Len() < 3 {
    27  		return &invalidMessageFormatErr{messageType: "CopyInResponse"}
    28  	}
    29  
    30  	overallFormat := buf.Next(1)[0]
    31  
    32  	columnCount := int(binary.BigEndian.Uint16(buf.Next(2)))
    33  	if buf.Len() != columnCount*2 {
    34  		return &invalidMessageFormatErr{messageType: "CopyInResponse"}
    35  	}
    36  
    37  	columnFormatCodes := make([]uint16, columnCount)
    38  	for i := 0; i < columnCount; i++ {
    39  		columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2))
    40  	}
    41  
    42  	*dst = CopyInResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes}
    43  
    44  	return nil
    45  }
    46  
    47  // Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
    48  func (src *CopyInResponse) Encode(dst []byte) ([]byte, error) {
    49  	dst, sp := beginMessage(dst, 'G')
    50  
    51  	dst = append(dst, src.OverallFormat)
    52  	if len(src.ColumnFormatCodes) > math.MaxUint16 {
    53  		return nil, errors.New("too many column format codes")
    54  	}
    55  	dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
    56  	for _, fc := range src.ColumnFormatCodes {
    57  		dst = pgio.AppendUint16(dst, fc)
    58  	}
    59  
    60  	return finishMessage(dst, sp)
    61  }
    62  
    63  // MarshalJSON implements encoding/json.Marshaler.
    64  func (src CopyInResponse) MarshalJSON() ([]byte, error) {
    65  	return json.Marshal(struct {
    66  		Type              string
    67  		ColumnFormatCodes []uint16
    68  	}{
    69  		Type:              "CopyInResponse",
    70  		ColumnFormatCodes: src.ColumnFormatCodes,
    71  	})
    72  }
    73  
    74  // UnmarshalJSON implements encoding/json.Unmarshaler.
    75  func (dst *CopyInResponse) UnmarshalJSON(data []byte) error {
    76  	// Ignore null, like in the main JSON package.
    77  	if string(data) == "null" {
    78  		return nil
    79  	}
    80  
    81  	var msg struct {
    82  		OverallFormat     string
    83  		ColumnFormatCodes []uint16
    84  	}
    85  	if err := json.Unmarshal(data, &msg); err != nil {
    86  		return err
    87  	}
    88  
    89  	if len(msg.OverallFormat) != 1 {
    90  		return errors.New("invalid length for CopyInResponse.OverallFormat")
    91  	}
    92  
    93  	dst.OverallFormat = msg.OverallFormat[0]
    94  	dst.ColumnFormatCodes = msg.ColumnFormatCodes
    95  	return nil
    96  }
    97  

View as plain text