github.com/jackc/pgx/v5@v5.5.5/pgtype/ltree.go (about)

     1  package pgtype
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"fmt"
     6  )
     7  
     8  type LtreeCodec struct{}
     9  
    10  func (l LtreeCodec) FormatSupported(format int16) bool {
    11  	return format == TextFormatCode || format == BinaryFormatCode
    12  }
    13  
    14  // PreferredFormat returns the preferred format.
    15  func (l LtreeCodec) PreferredFormat() int16 {
    16  	return TextFormatCode
    17  }
    18  
    19  // PlanEncode returns an EncodePlan for encoding value into PostgreSQL format for oid and format. If no plan can be
    20  // found then nil is returned.
    21  func (l LtreeCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
    22  	switch format {
    23  	case TextFormatCode:
    24  		return (TextCodec)(l).PlanEncode(m, oid, format, value)
    25  	case BinaryFormatCode:
    26  		switch value.(type) {
    27  		case string:
    28  			return encodeLtreeCodecBinaryString{}
    29  		case []byte:
    30  			return encodeLtreeCodecBinaryByteSlice{}
    31  		case TextValuer:
    32  			return encodeLtreeCodecBinaryTextValuer{}
    33  		}
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  type encodeLtreeCodecBinaryString struct{}
    40  
    41  func (encodeLtreeCodecBinaryString) Encode(value any, buf []byte) (newBuf []byte, err error) {
    42  	ltree := value.(string)
    43  	buf = append(buf, 1)
    44  	return append(buf, ltree...), nil
    45  }
    46  
    47  type encodeLtreeCodecBinaryByteSlice struct{}
    48  
    49  func (encodeLtreeCodecBinaryByteSlice) Encode(value any, buf []byte) (newBuf []byte, err error) {
    50  	ltree := value.([]byte)
    51  	buf = append(buf, 1)
    52  	return append(buf, ltree...), nil
    53  }
    54  
    55  type encodeLtreeCodecBinaryTextValuer struct{}
    56  
    57  func (encodeLtreeCodecBinaryTextValuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
    58  	t, err := value.(TextValuer).TextValue()
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	if !t.Valid {
    63  		return nil, nil
    64  	}
    65  
    66  	buf = append(buf, 1)
    67  	return append(buf, t.String...), nil
    68  }
    69  
    70  // PlanScan returns a ScanPlan for scanning a PostgreSQL value into a destination with the same type as target. If
    71  // no plan can be found then nil is returned.
    72  func (l LtreeCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
    73  	switch format {
    74  	case TextFormatCode:
    75  		return (TextCodec)(l).PlanScan(m, oid, format, target)
    76  	case BinaryFormatCode:
    77  		switch target.(type) {
    78  		case *string:
    79  			return scanPlanBinaryLtreeToString{}
    80  		case TextScanner:
    81  			return scanPlanBinaryLtreeToTextScanner{}
    82  		}
    83  	}
    84  
    85  	return nil
    86  }
    87  
    88  type scanPlanBinaryLtreeToString struct{}
    89  
    90  func (scanPlanBinaryLtreeToString) Scan(src []byte, target any) error {
    91  	version := src[0]
    92  	if version != 1 {
    93  		return fmt.Errorf("unsupported ltree version %d", version)
    94  	}
    95  
    96  	p := (target).(*string)
    97  	*p = string(src[1:])
    98  
    99  	return nil
   100  }
   101  
   102  type scanPlanBinaryLtreeToTextScanner struct{}
   103  
   104  func (scanPlanBinaryLtreeToTextScanner) Scan(src []byte, target any) error {
   105  	version := src[0]
   106  	if version != 1 {
   107  		return fmt.Errorf("unsupported ltree version %d", version)
   108  	}
   109  
   110  	scanner := (target).(TextScanner)
   111  	return scanner.ScanText(Text{String: string(src[1:]), Valid: true})
   112  }
   113  
   114  // DecodeDatabaseSQLValue returns src decoded into a value compatible with the sql.Scanner interface.
   115  func (l LtreeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
   116  	return (TextCodec)(l).DecodeDatabaseSQLValue(m, oid, format, src)
   117  }
   118  
   119  // DecodeValue returns src decoded into its default format.
   120  func (l LtreeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
   121  	return (TextCodec)(l).DecodeValue(m, oid, format, src)
   122  }