...

Text file src/github.com/jackc/pgx/v5/pgtype/int.go.erb

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

     1package pgtype
     2
     3import (
     4	"database/sql/driver"
     5	"encoding/binary"
     6	"encoding/json"
     7	"fmt"
     8	"math"
     9	"strconv"
    10
    11	"github.com/jackc/pgx/v5/internal/pgio"
    12)
    13
    14type Int64Scanner interface {
    15	ScanInt64(Int8) error
    16}
    17
    18type Int64Valuer interface {
    19	Int64Value() (Int8, error)
    20}
    21
    22
    23<% [2, 4, 8].each do |pg_byte_size| %>
    24<% pg_bit_size = pg_byte_size * 8 %>
    25type Int<%= pg_byte_size %> struct {
    26	Int<%= pg_bit_size %>   int<%= pg_bit_size %>
    27	Valid bool
    28}
    29
    30// ScanInt64 implements the Int64Scanner interface.
    31func (dst *Int<%= pg_byte_size %>) ScanInt64(n Int8) error {
    32	if !n.Valid {
    33		*dst = Int<%= pg_byte_size %>{}
    34		return nil
    35	}
    36
    37	if n.Int64 < math.MinInt<%= pg_bit_size %> {
    38		return fmt.Errorf("%d is less than minimum value for Int<%= pg_byte_size %>", n.Int64)
    39	}
    40	if n.Int64 > math.MaxInt<%= pg_bit_size %> {
    41		return fmt.Errorf("%d is greater than maximum value for Int<%= pg_byte_size %>", n.Int64)
    42	}
    43	*dst = Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: int<%= pg_bit_size %>(n.Int64), Valid: true}
    44
    45	return nil
    46}
    47
    48func (n Int<%= pg_byte_size %>) Int64Value() (Int8, error) {
    49	return Int8{Int64: int64(n.Int<%= pg_bit_size %>), Valid: n.Valid}, nil
    50}
    51
    52// Scan implements the database/sql Scanner interface.
    53func (dst *Int<%= pg_byte_size %>) Scan(src any) error {
    54	if src == nil {
    55		*dst = Int<%= pg_byte_size %>{}
    56		return nil
    57	}
    58
    59	var n int64
    60
    61	switch src := src.(type) {
    62	case int64:
    63		n = src
    64	case string:
    65		var err error
    66		n, err = strconv.ParseInt(src, 10, <%= pg_bit_size %>)
    67		if err != nil {
    68			return err
    69		}
    70	case []byte:
    71		var err error
    72		n, err = strconv.ParseInt(string(src), 10, <%= pg_bit_size %>)
    73		if err != nil {
    74			return err
    75		}
    76	default:
    77		return fmt.Errorf("cannot scan %T", src)
    78	}
    79
    80	if n < math.MinInt<%= pg_bit_size %> {
    81		return fmt.Errorf("%d is greater than maximum value for Int<%= pg_byte_size %>", n)
    82	}
    83	if n > math.MaxInt<%= pg_bit_size %> {
    84		return fmt.Errorf("%d is greater than maximum value for Int<%= pg_byte_size %>", n)
    85	}
    86	*dst = Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: int<%= pg_bit_size %>(n), Valid: true}
    87
    88	return nil
    89}
    90
    91// Value implements the database/sql/driver Valuer interface.
    92func (src Int<%= pg_byte_size %>) Value() (driver.Value, error) {
    93	if !src.Valid {
    94		return nil, nil
    95	}
    96	return int64(src.Int<%= pg_bit_size %>), nil
    97}
    98
    99func (src Int<%= pg_byte_size %>) MarshalJSON() ([]byte, error) {
   100	if !src.Valid {
   101		return []byte("null"), nil
   102	}
   103	return []byte(strconv.FormatInt(int64(src.Int<%= pg_bit_size %>), 10)), nil
   104}
   105
   106func (dst *Int<%= pg_byte_size %>) UnmarshalJSON(b []byte) error {
   107	var n *int<%= pg_bit_size %>
   108	err := json.Unmarshal(b, &n)
   109	if err != nil {
   110		return err
   111	}
   112
   113	if n == nil {
   114		*dst = Int<%= pg_byte_size %>{}
   115	} else {
   116		*dst = Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: *n, Valid: true}
   117	}
   118
   119	return nil
   120}
   121
   122type Int<%= pg_byte_size %>Codec struct{}
   123
   124func (Int<%= pg_byte_size %>Codec) FormatSupported(format int16) bool {
   125	return format == TextFormatCode || format == BinaryFormatCode
   126}
   127
   128func (Int<%= pg_byte_size %>Codec) PreferredFormat() int16 {
   129	return BinaryFormatCode
   130}
   131
   132func (Int<%= pg_byte_size %>Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
   133	switch format {
   134	case BinaryFormatCode:
   135		switch value.(type) {
   136		case int<%= pg_bit_size %>:
   137			return encodePlanInt<%= pg_byte_size %>CodecBinaryInt<%= pg_bit_size %>{}
   138		case Int64Valuer:
   139			return encodePlanInt<%= pg_byte_size %>CodecBinaryInt64Valuer{}
   140		}
   141	case TextFormatCode:
   142		switch value.(type) {
   143		case int<%= pg_bit_size %>:
   144			return encodePlanInt<%= pg_byte_size %>CodecTextInt<%= pg_bit_size %>{}
   145		case Int64Valuer:
   146			return encodePlanInt<%= pg_byte_size %>CodecTextInt64Valuer{}
   147		}
   148	}
   149
   150	return nil
   151}
   152
   153type encodePlanInt<%= pg_byte_size %>CodecBinaryInt<%= pg_bit_size %> struct{}
   154
   155func (encodePlanInt<%= pg_byte_size %>CodecBinaryInt<%= pg_bit_size %>) Encode(value any, buf []byte) (newBuf []byte, err error) {
   156  n := value.(int<%= pg_bit_size %>)
   157  return pgio.AppendInt<%= pg_bit_size %>(buf, int<%= pg_bit_size %>(n)), nil
   158}
   159
   160type encodePlanInt<%= pg_byte_size %>CodecTextInt<%= pg_bit_size %> struct{}
   161
   162func (encodePlanInt<%= pg_byte_size %>CodecTextInt<%= pg_bit_size %>) Encode(value any, buf []byte) (newBuf []byte, err error) {
   163  n := value.(int<%= pg_bit_size %>)
   164  return append(buf, strconv.FormatInt(int64(n), 10)...), nil
   165}
   166
   167type encodePlanInt<%= pg_byte_size %>CodecBinaryInt64Valuer struct{}
   168
   169func (encodePlanInt<%= pg_byte_size %>CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   170  n, err := value.(Int64Valuer).Int64Value()
   171	if err != nil {
   172		return nil, err
   173	}
   174
   175	if !n.Valid {
   176		return nil, nil
   177	}
   178
   179	if n.Int64 > math.MaxInt<%= pg_bit_size %> {
   180		return nil, fmt.Errorf("%d is greater than maximum value for int<%= pg_byte_size %>", n.Int64)
   181	}
   182	if n.Int64 < math.MinInt<%= pg_bit_size %> {
   183		return nil, fmt.Errorf("%d is less than minimum value for int<%= pg_byte_size %>", n.Int64)
   184	}
   185
   186  return pgio.AppendInt<%= pg_bit_size %>(buf, int<%= pg_bit_size %>(n.Int64)), nil
   187}
   188
   189type encodePlanInt<%= pg_byte_size %>CodecTextInt64Valuer struct{}
   190
   191func (encodePlanInt<%= pg_byte_size %>CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
   192  n, err := value.(Int64Valuer).Int64Value()
   193	if err != nil {
   194		return nil, err
   195	}
   196
   197	if !n.Valid {
   198		return nil, nil
   199	}
   200
   201	if n.Int64 > math.MaxInt<%= pg_bit_size %> {
   202		return nil, fmt.Errorf("%d is greater than maximum value for int<%= pg_byte_size %>", n.Int64)
   203	}
   204	if n.Int64 < math.MinInt<%= pg_bit_size %> {
   205		return nil, fmt.Errorf("%d is less than minimum value for int<%= pg_byte_size %>", n.Int64)
   206	}
   207
   208  return append(buf, strconv.FormatInt(n.Int64, 10)...), nil
   209}
   210
   211func (Int<%= pg_byte_size %>Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
   212
   213	switch format {
   214	case BinaryFormatCode:
   215		switch target.(type) {
   216		case *int8:
   217			return scanPlanBinaryInt<%= pg_byte_size %>ToInt8{}
   218		case *int16:
   219			return scanPlanBinaryInt<%= pg_byte_size %>ToInt16{}
   220		case *int32:
   221			return scanPlanBinaryInt<%= pg_byte_size %>ToInt32{}
   222		case *int64:
   223			return scanPlanBinaryInt<%= pg_byte_size %>ToInt64{}
   224		case *int:
   225			return scanPlanBinaryInt<%= pg_byte_size %>ToInt{}
   226		case *uint8:
   227			return scanPlanBinaryInt<%= pg_byte_size %>ToUint8{}
   228		case *uint16:
   229			return scanPlanBinaryInt<%= pg_byte_size %>ToUint16{}
   230		case *uint32:
   231			return scanPlanBinaryInt<%= pg_byte_size %>ToUint32{}
   232		case *uint64:
   233			return scanPlanBinaryInt<%= pg_byte_size %>ToUint64{}
   234		case *uint:
   235			return scanPlanBinaryInt<%= pg_byte_size %>ToUint{}
   236		case Int64Scanner:
   237			return scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner{}
   238		case TextScanner:
   239			return scanPlanBinaryInt<%= pg_byte_size %>ToTextScanner{}
   240		}
   241	case TextFormatCode:
   242		switch target.(type) {
   243		case *int8:
   244			return scanPlanTextAnyToInt8{}
   245		case *int16:
   246			return scanPlanTextAnyToInt16{}
   247		case *int32:
   248			return scanPlanTextAnyToInt32{}
   249		case *int64:
   250			return scanPlanTextAnyToInt64{}
   251		case *int:
   252			return scanPlanTextAnyToInt{}
   253		case *uint8:
   254			return scanPlanTextAnyToUint8{}
   255		case *uint16:
   256			return scanPlanTextAnyToUint16{}
   257		case *uint32:
   258			return scanPlanTextAnyToUint32{}
   259		case *uint64:
   260			return scanPlanTextAnyToUint64{}
   261		case *uint:
   262			return scanPlanTextAnyToUint{}
   263		case Int64Scanner:
   264			return scanPlanTextAnyToInt64Scanner{}
   265		}
   266	}
   267
   268	return nil
   269}
   270
   271func (c Int<%= pg_byte_size %>Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
   272	if src == nil {
   273		return nil, nil
   274	}
   275
   276	var n int64
   277	err := codecScan(c, m, oid, format, src, &n)
   278	if err != nil {
   279		return nil, err
   280	}
   281	return n, nil
   282}
   283
   284func (c Int<%= pg_byte_size %>Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
   285	if src == nil {
   286		return nil, nil
   287	}
   288
   289	var n int<%= pg_bit_size %>
   290	err := codecScan(c, m, oid, format, src, &n)
   291	if err != nil {
   292		return nil, err
   293	}
   294	return n, nil
   295}
   296
   297<%# PostgreSQL binary format integer to fixed size Go integers %>
   298<% [8, 16, 32, 64].each do |dst_bit_size| %>
   299type scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %> struct{}
   300
   301func (scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %>) Scan(src []byte, dst any) error {
   302	if src == nil {
   303		return fmt.Errorf("cannot scan NULL into %T", dst)
   304	}
   305
   306	if len(src) != <%= pg_byte_size %> {
   307		return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src))
   308	}
   309
   310	p, ok := (dst).(*int<%= dst_bit_size %>)
   311	if !ok {
   312		return ErrScanTargetTypeChanged
   313	}
   314
   315  <% if dst_bit_size < pg_bit_size %>
   316	n := int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))
   317	if n < math.MinInt<%= dst_bit_size %> {
   318		return fmt.Errorf("%d is less than minimum value for int<%= dst_bit_size %>", n)
   319	} else if n > math.MaxInt<%= dst_bit_size %> {
   320		return fmt.Errorf("%d is greater than maximum value for int<%= dst_bit_size %>", n)
   321	}
   322
   323	*p = int<%= dst_bit_size %>(n)
   324  <% elsif dst_bit_size == pg_bit_size %>
   325	*p = int<%= dst_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))
   326  <% else %>
   327	*p = int<%= dst_bit_size %>(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)))
   328  <% end %>
   329
   330	return nil
   331}
   332
   333type scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %> struct{}
   334
   335func (scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %>) Scan(src []byte, dst any) error {
   336	if src == nil {
   337		return fmt.Errorf("cannot scan NULL into %T", dst)
   338	}
   339
   340	if len(src) != <%= pg_byte_size %> {
   341		return fmt.Errorf("invalid length for uint<%= pg_byte_size %>: %v", len(src))
   342	}
   343
   344	p, ok := (dst).(*uint<%= dst_bit_size %>)
   345	if !ok {
   346		return ErrScanTargetTypeChanged
   347	}
   348
   349	n := int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))
   350	if n < 0 {
   351		return fmt.Errorf("%d is less than minimum value for uint<%= dst_bit_size %>", n)
   352	}
   353  <% if dst_bit_size < pg_bit_size %>
   354	if n > math.MaxUint<%= dst_bit_size %> {
   355		return fmt.Errorf("%d is greater than maximum value for uint<%= dst_bit_size %>", n)
   356	}
   357  <% end %>
   358	*p = uint<%= dst_bit_size %>(n)
   359
   360	return nil
   361}
   362<% end %>
   363
   364<%# PostgreSQL binary format integer to Go machine integers %>
   365type scanPlanBinaryInt<%= pg_byte_size %>ToInt struct{}
   366
   367func (scanPlanBinaryInt<%= pg_byte_size %>ToInt) Scan(src []byte, dst any) error {
   368	if src == nil {
   369		return fmt.Errorf("cannot scan NULL into %T", dst)
   370	}
   371
   372	if len(src) != <%= pg_byte_size %> {
   373		return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src))
   374	}
   375
   376	p, ok := (dst).(*int)
   377	if !ok {
   378		return ErrScanTargetTypeChanged
   379	}
   380
   381  <% if 32 < pg_bit_size %>
   382	n := int64(binary.BigEndian.Uint<%= pg_bit_size %>(src))
   383	if n < math.MinInt {
   384		return fmt.Errorf("%d is less than minimum value for int", n)
   385	} else if n > math.MaxInt {
   386		return fmt.Errorf("%d is greater than maximum value for int", n)
   387	}
   388
   389	*p = int(n)
   390  <% else %>
   391	*p = int(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)))
   392  <% end %>
   393
   394	return nil
   395}
   396
   397type scanPlanBinaryInt<%= pg_byte_size %>ToUint struct{}
   398
   399func (scanPlanBinaryInt<%= pg_byte_size %>ToUint) Scan(src []byte, dst any) error {
   400	if src == nil {
   401		return fmt.Errorf("cannot scan NULL into %T", dst)
   402	}
   403
   404	if len(src) != <%= pg_byte_size %> {
   405		return fmt.Errorf("invalid length for uint<%= pg_byte_size %>: %v", len(src))
   406	}
   407
   408	p, ok := (dst).(*uint)
   409	if !ok {
   410		return ErrScanTargetTypeChanged
   411	}
   412
   413	n := int64(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)))
   414	if n < 0 {
   415		return fmt.Errorf("%d is less than minimum value for uint", n)
   416	}
   417  <% if 32 < pg_bit_size %>
   418	if uint64(n) > math.MaxUint {
   419		return fmt.Errorf("%d is greater than maximum value for uint", n)
   420	}
   421  <% end %>
   422	*p = uint(n)
   423
   424	return nil
   425}
   426
   427<%# PostgreSQL binary format integer to Go Int64Scanner %>
   428type scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner struct{}
   429
   430func (scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner) Scan(src []byte, dst any) error {
   431	s, ok := (dst).(Int64Scanner)
   432	if !ok {
   433		return ErrScanTargetTypeChanged
   434	}
   435
   436	if src == nil {
   437    return s.ScanInt64(Int8{})
   438	}
   439
   440	if len(src) != <%= pg_byte_size %> {
   441		return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src))
   442	}
   443
   444
   445	n := int64(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)))
   446
   447  return s.ScanInt64(Int8{Int64: n, Valid: true})
   448}
   449
   450<%# PostgreSQL binary format integer to Go TextScanner %>
   451type scanPlanBinaryInt<%= pg_byte_size %>ToTextScanner struct{}
   452
   453func (scanPlanBinaryInt<%= pg_byte_size %>ToTextScanner) Scan(src []byte, dst any) error {
   454	s, ok := (dst).(TextScanner)
   455	if !ok {
   456		return ErrScanTargetTypeChanged
   457	}
   458
   459	if src == nil {
   460    return s.ScanText(Text{})
   461	}
   462
   463	if len(src) != <%= pg_byte_size %> {
   464		return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src))
   465	}
   466
   467
   468	n := int64(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)))
   469
   470  return s.ScanText(Text{String: strconv.FormatInt(n, 10), Valid: true})
   471}
   472<% end %>
   473
   474<%# Any text to all integer types %>
   475<% [
   476  ["8", 8],
   477  ["16", 16],
   478  ["32", 32],
   479  ["64", 64],
   480  ["", 0]
   481].each do |type_suffix, bit_size| %>
   482type scanPlanTextAnyToInt<%= type_suffix %> struct{}
   483
   484func (scanPlanTextAnyToInt<%= type_suffix %>) Scan(src []byte, dst any) error {
   485	if src == nil {
   486		return fmt.Errorf("cannot scan NULL into %T", dst)
   487	}
   488
   489	p, ok := (dst).(*int<%= type_suffix %>)
   490	if !ok {
   491		return ErrScanTargetTypeChanged
   492	}
   493
   494	n, err := strconv.ParseInt(string(src), 10, <%= bit_size %>)
   495	if err != nil {
   496		return err
   497	}
   498
   499	*p = int<%= type_suffix %>(n)
   500	return nil
   501}
   502
   503type scanPlanTextAnyToUint<%= type_suffix %> struct{}
   504
   505func (scanPlanTextAnyToUint<%= type_suffix %>) Scan(src []byte, dst any) error {
   506	if src == nil {
   507		return fmt.Errorf("cannot scan NULL into %T", dst)
   508	}
   509
   510	p, ok := (dst).(*uint<%= type_suffix %>)
   511	if !ok {
   512		return ErrScanTargetTypeChanged
   513	}
   514
   515	n, err := strconv.ParseUint(string(src), 10, <%= bit_size %>)
   516	if err != nil {
   517		return err
   518	}
   519
   520	*p = uint<%= type_suffix %>(n)
   521	return nil
   522}
   523<% end %>
   524
   525type scanPlanTextAnyToInt64Scanner struct{}
   526
   527func (scanPlanTextAnyToInt64Scanner) Scan(src []byte, dst any) error {
   528	s, ok := (dst).(Int64Scanner)
   529	if !ok {
   530		return ErrScanTargetTypeChanged
   531	}
   532
   533	if src == nil {
   534    return s.ScanInt64(Int8{})
   535	}
   536
   537	n, err := strconv.ParseInt(string(src), 10, 64)
   538	if err != nil {
   539		return err
   540	}
   541
   542  err = s.ScanInt64(Int8{Int64: n, Valid: true})
   543	if err != nil {
   544		return err
   545	}
   546
   547	return nil
   548}

View as plain text