package pgtype
import (
)
type TIDScanner interface {
ScanTID(v TID) error
}
type TIDValuer interface {
TIDValue() (TID, error)
}
type TID struct {
BlockNumber uint32
OffsetNumber uint16
Valid bool
}
func ( *TID) ( TID) error {
* =
return nil
}
func ( TID) () (TID, error) {
return , nil
}
func ( *TID) ( any) error {
if == nil {
* = TID{}
return nil
}
switch src := .(type) {
case string:
return scanPlanTextAnyToTIDScanner{}.Scan([]byte(), )
}
return fmt.Errorf("cannot scan %T", )
}
func ( TID) () (driver.Value, error) {
if !.Valid {
return nil, nil
}
, := TIDCodec{}.PlanEncode(nil, 0, TextFormatCode, ).Encode(, nil)
if != nil {
return nil,
}
return string(),
}
type TIDCodec struct{}
func (TIDCodec) ( int16) bool {
return == TextFormatCode || == BinaryFormatCode
}
func (TIDCodec) () int16 {
return BinaryFormatCode
}
func (TIDCodec) ( *Map, uint32, int16, any) EncodePlan {
if , := .(TIDValuer); ! {
return nil
}
switch {
case BinaryFormatCode:
return encodePlanTIDCodecBinary{}
case TextFormatCode:
return encodePlanTIDCodecText{}
}
return nil
}
type encodePlanTIDCodecBinary struct{}
func (encodePlanTIDCodecBinary) ( any, []byte) ( []byte, error) {
, := .(TIDValuer).TIDValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
= pgio.AppendUint32(, .BlockNumber)
= pgio.AppendUint16(, .OffsetNumber)
return , nil
}
type encodePlanTIDCodecText struct{}
func (encodePlanTIDCodecText) ( any, []byte) ( []byte, error) {
, := .(TIDValuer).TIDValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
= append(, fmt.Sprintf(`(%d,%d)`, .BlockNumber, .OffsetNumber)...)
return , nil
}
func (TIDCodec) ( *Map, uint32, int16, any) ScanPlan {
switch {
case BinaryFormatCode:
switch .(type) {
case TIDScanner:
return scanPlanBinaryTIDToTIDScanner{}
case TextScanner:
return scanPlanBinaryTIDToTextScanner{}
}
case TextFormatCode:
switch .(type) {
case TIDScanner:
return scanPlanTextAnyToTIDScanner{}
}
}
return nil
}
type scanPlanBinaryTIDToTIDScanner struct{}
func (scanPlanBinaryTIDToTIDScanner) ( []byte, any) error {
:= ().(TIDScanner)
if == nil {
return .ScanTID(TID{})
}
if len() != 6 {
return fmt.Errorf("invalid length for tid: %v", len())
}
return .ScanTID(TID{
BlockNumber: binary.BigEndian.Uint32(),
OffsetNumber: binary.BigEndian.Uint16([4:]),
Valid: true,
})
}
type scanPlanBinaryTIDToTextScanner struct{}
func (scanPlanBinaryTIDToTextScanner) ( []byte, any) error {
:= ().(TextScanner)
if == nil {
return .ScanText(Text{})
}
if len() != 6 {
return fmt.Errorf("invalid length for tid: %v", len())
}
:= binary.BigEndian.Uint32()
:= binary.BigEndian.Uint16([4:])
return .ScanText(Text{
String: fmt.Sprintf(`(%d,%d)`, , ),
Valid: true,
})
}
type scanPlanTextAnyToTIDScanner struct{}
func (scanPlanTextAnyToTIDScanner) ( []byte, any) error {
:= ().(TIDScanner)
if == nil {
return .ScanTID(TID{})
}
if len() < 5 {
return fmt.Errorf("invalid length for tid: %v", len())
}
, , := strings.Cut(string([1:len()-1]), ",")
if ! {
return fmt.Errorf("invalid format for tid")
}
, := strconv.ParseUint(, 10, 32)
if != nil {
return
}
, := strconv.ParseUint(, 10, 16)
if != nil {
return
}
return .ScanTID(TID{BlockNumber: uint32(), OffsetNumber: uint16(), Valid: true})
}
func ( TIDCodec) ( *Map, uint32, int16, []byte) (driver.Value, error) {
return codecDecodeToTextFormat(, , , , )
}
func ( TIDCodec) ( *Map, uint32, int16, []byte) (any, error) {
if == nil {
return nil, nil
}
var TID
:= codecScan(, , , , , &)
if != nil {
return nil,
}
return , nil
}