pgtype tests pass

query-exec-mode
Jack Christensen 2021-12-31 17:51:18 -06:00
parent 19ae359e9e
commit 1516a0d8db
4 changed files with 126 additions and 0 deletions

View File

@ -12,6 +12,24 @@ type Int2 struct {
Valid bool
}
// ScanInt64 implements the Int64Scanner interface.
func (dst *Int2) ScanInt64(n int64, valid bool) error {
if !valid {
*dst = Int2{}
return nil
}
if n < math.MinInt16 {
return fmt.Errorf("%d is greater than maximum value for Int2", n)
}
if n > math.MaxInt16 {
return fmt.Errorf("%d is greater than maximum value for Int2", n)
}
*dst = Int2{Int: int16(n), Valid: true}
return nil
}
// Scan implements the database/sql Scanner interface.
func (dst *Int2) Scan(src interface{}) error {
if src == nil {

View File

@ -70,6 +70,8 @@ func (Int2Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
return scanPlanBinaryInt2ToUint64{}
case *uint:
return scanPlanBinaryInt2ToUint{}
case Int64Scanner:
return scanPlanBinaryInt2ToInt64Scanner{}
}
case TextFormatCode:
switch target.(type) {
@ -93,6 +95,8 @@ func (Int2Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
return scanPlanTextAnyToUint64{}
case *uint:
return scanPlanTextAnyToUint{}
case Int64Scanner:
return scanPlanTextAnyToInt64Scanner{}
}
}
@ -132,3 +136,7 @@ func (c Int2Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
}
return n, nil
}
type Int64Scanner interface {
ScanInt64(v int64, valid bool) error
}

View File

@ -462,3 +462,49 @@ func (scanPlanBinaryInt2ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16,
return nil
}
type scanPlanBinaryInt2ToInt64Scanner struct{}
func (scanPlanBinaryInt2ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner)
if !ok {
return ErrScanTargetTypeChanged
}
if src == nil {
return s.ScanInt64(0, false)
}
if len(src) != 2 {
return fmt.Errorf("invalid length for int2: %v", len(src))
}
n := int64(binary.BigEndian.Uint16(src))
return s.ScanInt64(n, true)
}
type scanPlanTextAnyToInt64Scanner struct{}
func (scanPlanTextAnyToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner)
if !ok {
return ErrScanTargetTypeChanged
}
if src == nil {
return s.ScanInt64(0, false)
}
n, err := strconv.ParseInt(string(src), 10, 64)
if err != nil {
return err
}
err = s.ScanInt64(n, true)
if err != nil {
return err
}
return nil
}

View File

@ -5,6 +5,7 @@ import (
"strconv"
)
<%# Any text to all integer types %>
<% [
["8", 8],
["16", 16],
@ -55,6 +56,7 @@ func (scanPlanTextAnyToUint<%= type_suffix %>) Scan(ci *ConnInfo, oid uint32, fo
}
<% end %>
<%# PostgreSQL binary integers to fixed size Go integers %>
<% [
[16, 8],
[16, 16],
@ -125,6 +127,7 @@ func (scanPlanBinaryInt<%= src_byte_size %>ToUint<%= dst_bit_size %>) Scan(ci *C
}
<% end %>
<%# PostgreSQL binary integers to Go machine integers %>
<% [16].each do |src_bit_size| %>
<% src_byte_size = src_bit_size / 8 %>
type scanPlanBinaryInt<%= src_byte_size %>ToInt struct{}
@ -189,3 +192,54 @@ func (scanPlanBinaryInt<%= src_byte_size %>ToUint) Scan(ci *ConnInfo, oid uint32
return nil
}
<% end %>
<%# PostgreSQL binary integers to Go Int64Scanner %>
<% [16].each do |src_bit_size| %>
<% src_byte_size = src_bit_size / 8 %>
type scanPlanBinaryInt<%= src_byte_size %>ToInt64Scanner struct{}
func (scanPlanBinaryInt<%= src_byte_size %>ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner)
if !ok {
return ErrScanTargetTypeChanged
}
if src == nil {
return s.ScanInt64(0, false)
}
if len(src) != <%= src_byte_size %> {
return fmt.Errorf("invalid length for int<%= src_byte_size %>: %v", len(src))
}
n := int64(binary.BigEndian.Uint<%= src_bit_size %>(src))
return s.ScanInt64(n, true)
}
<% end %>
type scanPlanTextAnyToInt64Scanner struct{}
func (scanPlanTextAnyToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner)
if !ok {
return ErrScanTargetTypeChanged
}
if src == nil {
return s.ScanInt64(0, false)
}
n, err := strconv.ParseInt(string(src), 10, 64)
if err != nil {
return err
}
err = s.ScanInt64(n, true)
if err != nil {
return err
}
return nil
}