...

Source file src/github.com/jackc/pgx/v5/pgtype/text.go

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

     1  package pgtype
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/json"
     6  	"fmt"
     7  )
     8  
     9  type TextScanner interface {
    10  	ScanText(v Text) error
    11  }
    12  
    13  type TextValuer interface {
    14  	TextValue() (Text, error)
    15  }
    16  
    17  type Text struct {
    18  	String string
    19  	Valid  bool
    20  }
    21  
    22  func (t *Text) ScanText(v Text) error {
    23  	*t = v
    24  	return nil
    25  }
    26  
    27  func (t Text) TextValue() (Text, error) {
    28  	return t, nil
    29  }
    30  
    31  // Scan implements the database/sql Scanner interface.
    32  func (dst *Text) Scan(src any) error {
    33  	if src == nil {
    34  		*dst = Text{}
    35  		return nil
    36  	}
    37  
    38  	switch src := src.(type) {
    39  	case string:
    40  		*dst = Text{String: src, Valid: true}
    41  		return nil
    42  	case []byte:
    43  		*dst = Text{String: string(src), Valid: true}
    44  		return nil
    45  	}
    46  
    47  	return fmt.Errorf("cannot scan %T", src)
    48  }
    49  
    50  // Value implements the database/sql/driver Valuer interface.
    51  func (src Text) Value() (driver.Value, error) {
    52  	if !src.Valid {
    53  		return nil, nil
    54  	}
    55  	return src.String, nil
    56  }
    57  
    58  func (src Text) MarshalJSON() ([]byte, error) {
    59  	if !src.Valid {
    60  		return []byte("null"), nil
    61  	}
    62  
    63  	return json.Marshal(src.String)
    64  }
    65  
    66  func (dst *Text) UnmarshalJSON(b []byte) error {
    67  	var s *string
    68  	err := json.Unmarshal(b, &s)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	if s == nil {
    74  		*dst = Text{}
    75  	} else {
    76  		*dst = Text{String: *s, Valid: true}
    77  	}
    78  
    79  	return nil
    80  }
    81  
    82  type TextCodec struct{}
    83  
    84  func (TextCodec) FormatSupported(format int16) bool {
    85  	return format == TextFormatCode || format == BinaryFormatCode
    86  }
    87  
    88  func (TextCodec) PreferredFormat() int16 {
    89  	return TextFormatCode
    90  }
    91  
    92  func (TextCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
    93  	switch format {
    94  	case TextFormatCode, BinaryFormatCode:
    95  		switch value.(type) {
    96  		case string:
    97  			return encodePlanTextCodecString{}
    98  		case []byte:
    99  			return encodePlanTextCodecByteSlice{}
   100  		case TextValuer:
   101  			return encodePlanTextCodecTextValuer{}
   102  		}
   103  	}
   104  
   105  	return nil
   106  }
   107  
   108  type encodePlanTextCodecString struct{}
   109  
   110  func (encodePlanTextCodecString) Encode(value any, buf []byte) (newBuf []byte, err error) {
   111  	s := value.(string)
   112  	buf = append(buf, s...)
   113  	return buf, nil
   114  }
   115  
   116  type encodePlanTextCodecByteSlice struct{}
   117  
   118  func (encodePlanTextCodecByteSlice) Encode(value any, buf []byte) (newBuf []byte, err error) {
   119  	s := value.([]byte)
   120  	buf = append(buf, s...)
   121  	return buf, nil
   122  }
   123  
   124  type encodePlanTextCodecStringer struct{}
   125  
   126  func (encodePlanTextCodecStringer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   127  	s := value.(fmt.Stringer)
   128  	buf = append(buf, s.String()...)
   129  	return buf, nil
   130  }
   131  
   132  type encodePlanTextCodecTextValuer struct{}
   133  
   134  func (encodePlanTextCodecTextValuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   135  	text, err := value.(TextValuer).TextValue()
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  
   140  	if !text.Valid {
   141  		return nil, nil
   142  	}
   143  
   144  	buf = append(buf, text.String...)
   145  	return buf, nil
   146  }
   147  
   148  func (TextCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
   149  
   150  	switch format {
   151  	case TextFormatCode, BinaryFormatCode:
   152  		switch target.(type) {
   153  		case *string:
   154  			return scanPlanTextAnyToString{}
   155  		case *[]byte:
   156  			return scanPlanAnyToNewByteSlice{}
   157  		case BytesScanner:
   158  			return scanPlanAnyToByteScanner{}
   159  		case TextScanner:
   160  			return scanPlanTextAnyToTextScanner{}
   161  		}
   162  	}
   163  
   164  	return nil
   165  }
   166  
   167  func (c TextCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
   168  	return c.DecodeValue(m, oid, format, src)
   169  }
   170  
   171  func (c TextCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
   172  	if src == nil {
   173  		return nil, nil
   174  	}
   175  
   176  	return string(src), nil
   177  }
   178  
   179  type scanPlanTextAnyToString struct{}
   180  
   181  func (scanPlanTextAnyToString) Scan(src []byte, dst any) error {
   182  	if src == nil {
   183  		return fmt.Errorf("cannot scan NULL into %T", dst)
   184  	}
   185  
   186  	p := (dst).(*string)
   187  	*p = string(src)
   188  
   189  	return nil
   190  }
   191  
   192  type scanPlanAnyToNewByteSlice struct{}
   193  
   194  func (scanPlanAnyToNewByteSlice) Scan(src []byte, dst any) error {
   195  	p := (dst).(*[]byte)
   196  	if src == nil {
   197  		*p = nil
   198  	} else {
   199  		*p = make([]byte, len(src))
   200  		copy(*p, src)
   201  	}
   202  
   203  	return nil
   204  }
   205  
   206  type scanPlanAnyToByteScanner struct{}
   207  
   208  func (scanPlanAnyToByteScanner) Scan(src []byte, dst any) error {
   209  	p := (dst).(BytesScanner)
   210  	return p.ScanBytes(src)
   211  }
   212  
   213  type scanPlanTextAnyToTextScanner struct{}
   214  
   215  func (scanPlanTextAnyToTextScanner) Scan(src []byte, dst any) error {
   216  	scanner := (dst).(TextScanner)
   217  
   218  	if src == nil {
   219  		return scanner.ScanText(Text{})
   220  	}
   221  
   222  	return scanner.ScanText(Text{String: string(src), Valid: true})
   223  }
   224  

View as plain text