1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-05-04 22:17:59 +08:00
Dušan Borovčanin a48fb944c6
MF-1667 - Postgres lib update (#1680)
* Replace SQL lib in Things and Users

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update Bootstrap DB lib

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Rename pqErr to pgErr

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update Auth db lib

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update DB lib in consumers

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update DB lib for Readers

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update Certs DB lib

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Remove "lib/pq" from dependencies

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update vendor

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update Go version for base image in Dockerfile

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Remove unused Provision Dockerfile

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Move error codes to init.go files

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Add missing comment

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Use Error Codes lib

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update Go version in CI script

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Update mod file

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
2022-12-13 15:34:01 +01:00

96 lines
3.4 KiB
Go

package pgproto3
import (
"encoding/binary"
"github.com/jackc/pgx/v5/internal/pgio"
)
type FunctionCall struct {
Function uint32
ArgFormatCodes []uint16
Arguments [][]byte
ResultFormatCode uint16
}
// Frontend identifies this message as sendable by a PostgreSQL frontend.
func (*FunctionCall) Frontend() {}
// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
// type identifier and 4 byte message length.
func (dst *FunctionCall) Decode(src []byte) error {
*dst = FunctionCall{}
rp := 0
// Specifies the object ID of the function to call.
dst.Function = binary.BigEndian.Uint32(src[rp:])
rp += 4
// The number of argument format codes that follow (denoted C below).
// This can be zero to indicate that there are no arguments or that the arguments all use the default format (text);
// or one, in which case the specified format code is applied to all arguments;
// or it can equal the actual number of arguments.
nArgumentCodes := int(binary.BigEndian.Uint16(src[rp:]))
rp += 2
argumentCodes := make([]uint16, nArgumentCodes)
for i := 0; i < nArgumentCodes; i++ {
// The argument format codes. Each must presently be zero (text) or one (binary).
ac := binary.BigEndian.Uint16(src[rp:])
if ac != 0 && ac != 1 {
return &invalidMessageFormatErr{messageType: "FunctionCall"}
}
argumentCodes[i] = ac
rp += 2
}
dst.ArgFormatCodes = argumentCodes
// Specifies the number of arguments being supplied to the function.
nArguments := int(binary.BigEndian.Uint16(src[rp:]))
rp += 2
arguments := make([][]byte, nArguments)
for i := 0; i < nArguments; i++ {
// The length of the argument value, in bytes (this count does not include itself). Can be zero.
// As a special case, -1 indicates a NULL argument value. No value bytes follow in the NULL case.
argumentLength := int(binary.BigEndian.Uint32(src[rp:]))
rp += 4
if argumentLength == -1 {
arguments[i] = nil
} else {
// The value of the argument, in the format indicated by the associated format code. n is the above length.
argumentValue := src[rp : rp+argumentLength]
rp += argumentLength
arguments[i] = argumentValue
}
}
dst.Arguments = arguments
// The format code for the function result. Must presently be zero (text) or one (binary).
resultFormatCode := binary.BigEndian.Uint16(src[rp:])
if resultFormatCode != 0 && resultFormatCode != 1 {
return &invalidMessageFormatErr{messageType: "FunctionCall"}
}
dst.ResultFormatCode = resultFormatCode
return nil
}
// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
func (src *FunctionCall) Encode(dst []byte) []byte {
dst = append(dst, 'F')
sp := len(dst)
dst = pgio.AppendUint32(dst, 0) // Unknown length, set it at the end
dst = pgio.AppendUint32(dst, src.Function)
dst = pgio.AppendUint16(dst, uint16(len(src.ArgFormatCodes)))
for _, argFormatCode := range src.ArgFormatCodes {
dst = pgio.AppendUint16(dst, argFormatCode)
}
dst = pgio.AppendUint16(dst, uint16(len(src.Arguments)))
for _, argument := range src.Arguments {
if argument == nil {
dst = pgio.AppendInt32(dst, -1)
} else {
dst = pgio.AppendInt32(dst, int32(len(argument)))
dst = append(dst, argument...)
}
}
dst = pgio.AppendUint16(dst, src.ResultFormatCode)
pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
return dst
}