...

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

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

     1  package pgtype
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"math"
     8  	"strconv"
     9  
    10  	"github.com/jackc/pgx/v5/internal/pgio"
    11  )
    12  
    13  type Uint32Scanner interface {
    14  	ScanUint32(v Uint32) error
    15  }
    16  
    17  type Uint32Valuer interface {
    18  	Uint32Value() (Uint32, error)
    19  }
    20  
    21  // Uint32 is the core type that is used to represent PostgreSQL types such as OID, CID, and XID.
    22  type Uint32 struct {
    23  	Uint32 uint32
    24  	Valid  bool
    25  }
    26  
    27  func (n *Uint32) ScanUint32(v Uint32) error {
    28  	*n = v
    29  	return nil
    30  }
    31  
    32  func (n Uint32) Uint32Value() (Uint32, error) {
    33  	return n, nil
    34  }
    35  
    36  // Scan implements the database/sql Scanner interface.
    37  func (dst *Uint32) Scan(src any) error {
    38  	if src == nil {
    39  		*dst = Uint32{}
    40  		return nil
    41  	}
    42  
    43  	var n int64
    44  
    45  	switch src := src.(type) {
    46  	case int64:
    47  		n = src
    48  	case string:
    49  		un, err := strconv.ParseUint(src, 10, 32)
    50  		if err != nil {
    51  			return err
    52  		}
    53  		n = int64(un)
    54  	default:
    55  		return fmt.Errorf("cannot scan %T", src)
    56  	}
    57  
    58  	if n < 0 {
    59  		return fmt.Errorf("%d is less than the minimum value for Uint32", n)
    60  	}
    61  	if n > math.MaxUint32 {
    62  		return fmt.Errorf("%d is greater than maximum value for Uint32", n)
    63  	}
    64  
    65  	*dst = Uint32{Uint32: uint32(n), Valid: true}
    66  
    67  	return nil
    68  }
    69  
    70  // Value implements the database/sql/driver Valuer interface.
    71  func (src Uint32) Value() (driver.Value, error) {
    72  	if !src.Valid {
    73  		return nil, nil
    74  	}
    75  	return int64(src.Uint32), nil
    76  }
    77  
    78  type Uint32Codec struct{}
    79  
    80  func (Uint32Codec) FormatSupported(format int16) bool {
    81  	return format == TextFormatCode || format == BinaryFormatCode
    82  }
    83  
    84  func (Uint32Codec) PreferredFormat() int16 {
    85  	return BinaryFormatCode
    86  }
    87  
    88  func (Uint32Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
    89  	switch format {
    90  	case BinaryFormatCode:
    91  		switch value.(type) {
    92  		case uint32:
    93  			return encodePlanUint32CodecBinaryUint32{}
    94  		case Uint32Valuer:
    95  			return encodePlanUint32CodecBinaryUint32Valuer{}
    96  		case Int64Valuer:
    97  			return encodePlanUint32CodecBinaryInt64Valuer{}
    98  		}
    99  	case TextFormatCode:
   100  		switch value.(type) {
   101  		case uint32:
   102  			return encodePlanUint32CodecTextUint32{}
   103  		case Int64Valuer:
   104  			return encodePlanUint32CodecTextInt64Valuer{}
   105  		}
   106  	}
   107  
   108  	return nil
   109  }
   110  
   111  type encodePlanUint32CodecBinaryUint32 struct{}
   112  
   113  func (encodePlanUint32CodecBinaryUint32) Encode(value any, buf []byte) (newBuf []byte, err error) {
   114  	v := value.(uint32)
   115  	return pgio.AppendUint32(buf, v), nil
   116  }
   117  
   118  type encodePlanUint32CodecBinaryUint32Valuer struct{}
   119  
   120  func (encodePlanUint32CodecBinaryUint32Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   121  	v, err := value.(Uint32Valuer).Uint32Value()
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  
   126  	if !v.Valid {
   127  		return nil, nil
   128  	}
   129  
   130  	return pgio.AppendUint32(buf, v.Uint32), nil
   131  }
   132  
   133  type encodePlanUint32CodecBinaryInt64Valuer struct{}
   134  
   135  func (encodePlanUint32CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   136  	v, err := value.(Int64Valuer).Int64Value()
   137  	if err != nil {
   138  		return nil, err
   139  	}
   140  
   141  	if !v.Valid {
   142  		return nil, nil
   143  	}
   144  
   145  	if v.Int64 < 0 {
   146  		return nil, fmt.Errorf("%d is less than minimum value for uint32", v.Int64)
   147  	}
   148  	if v.Int64 > math.MaxUint32 {
   149  		return nil, fmt.Errorf("%d is greater than maximum value for uint32", v.Int64)
   150  	}
   151  
   152  	return pgio.AppendUint32(buf, uint32(v.Int64)), nil
   153  }
   154  
   155  type encodePlanUint32CodecTextUint32 struct{}
   156  
   157  func (encodePlanUint32CodecTextUint32) Encode(value any, buf []byte) (newBuf []byte, err error) {
   158  	v := value.(uint32)
   159  	return append(buf, strconv.FormatUint(uint64(v), 10)...), nil
   160  }
   161  
   162  type encodePlanUint32CodecTextUint32Valuer struct{}
   163  
   164  func (encodePlanUint32CodecTextUint32Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   165  	v, err := value.(Uint32Valuer).Uint32Value()
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  
   170  	if !v.Valid {
   171  		return nil, nil
   172  	}
   173  
   174  	return append(buf, strconv.FormatUint(uint64(v.Uint32), 10)...), nil
   175  }
   176  
   177  type encodePlanUint32CodecTextInt64Valuer struct{}
   178  
   179  func (encodePlanUint32CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   180  	v, err := value.(Int64Valuer).Int64Value()
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  
   185  	if !v.Valid {
   186  		return nil, nil
   187  	}
   188  
   189  	if v.Int64 < 0 {
   190  		return nil, fmt.Errorf("%d is less than minimum value for uint32", v.Int64)
   191  	}
   192  	if v.Int64 > math.MaxUint32 {
   193  		return nil, fmt.Errorf("%d is greater than maximum value for uint32", v.Int64)
   194  	}
   195  
   196  	return append(buf, strconv.FormatInt(v.Int64, 10)...), nil
   197  }
   198  
   199  func (Uint32Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
   200  
   201  	switch format {
   202  	case BinaryFormatCode:
   203  		switch target.(type) {
   204  		case *uint32:
   205  			return scanPlanBinaryUint32ToUint32{}
   206  		case Uint32Scanner:
   207  			return scanPlanBinaryUint32ToUint32Scanner{}
   208  		}
   209  	case TextFormatCode:
   210  		switch target.(type) {
   211  		case *uint32:
   212  			return scanPlanTextAnyToUint32{}
   213  		case Uint32Scanner:
   214  			return scanPlanTextAnyToUint32Scanner{}
   215  		}
   216  	}
   217  
   218  	return nil
   219  }
   220  
   221  func (c Uint32Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
   222  	if src == nil {
   223  		return nil, nil
   224  	}
   225  
   226  	var n uint32
   227  	err := codecScan(c, m, oid, format, src, &n)
   228  	if err != nil {
   229  		return nil, err
   230  	}
   231  	return int64(n), nil
   232  }
   233  
   234  func (c Uint32Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
   235  	if src == nil {
   236  		return nil, nil
   237  	}
   238  
   239  	var n uint32
   240  	err := codecScan(c, m, oid, format, src, &n)
   241  	if err != nil {
   242  		return nil, err
   243  	}
   244  	return n, nil
   245  }
   246  
   247  type scanPlanBinaryUint32ToUint32 struct{}
   248  
   249  func (scanPlanBinaryUint32ToUint32) Scan(src []byte, dst any) error {
   250  	if src == nil {
   251  		return fmt.Errorf("cannot scan NULL into %T", dst)
   252  	}
   253  
   254  	if len(src) != 4 {
   255  		return fmt.Errorf("invalid length for uint32: %v", len(src))
   256  	}
   257  
   258  	p := (dst).(*uint32)
   259  	*p = binary.BigEndian.Uint32(src)
   260  
   261  	return nil
   262  }
   263  
   264  type scanPlanBinaryUint32ToUint32Scanner struct{}
   265  
   266  func (scanPlanBinaryUint32ToUint32Scanner) Scan(src []byte, dst any) error {
   267  	s, ok := (dst).(Uint32Scanner)
   268  	if !ok {
   269  		return ErrScanTargetTypeChanged
   270  	}
   271  
   272  	if src == nil {
   273  		return s.ScanUint32(Uint32{})
   274  	}
   275  
   276  	if len(src) != 4 {
   277  		return fmt.Errorf("invalid length for uint32: %v", len(src))
   278  	}
   279  
   280  	n := binary.BigEndian.Uint32(src)
   281  
   282  	return s.ScanUint32(Uint32{Uint32: n, Valid: true})
   283  }
   284  
   285  type scanPlanTextAnyToUint32Scanner struct{}
   286  
   287  func (scanPlanTextAnyToUint32Scanner) Scan(src []byte, dst any) error {
   288  	s, ok := (dst).(Uint32Scanner)
   289  	if !ok {
   290  		return ErrScanTargetTypeChanged
   291  	}
   292  
   293  	if src == nil {
   294  		return s.ScanUint32(Uint32{})
   295  	}
   296  
   297  	n, err := strconv.ParseUint(string(src), 10, 32)
   298  	if err != nil {
   299  		return err
   300  	}
   301  
   302  	return s.ScanUint32(Uint32{Uint32: uint32(n), Valid: true})
   303  }
   304  

View as plain text