mirror of https://github.com/jackc/pgx.git
Add binary scan plans for int2
parent
77b9b59622
commit
19ae359e9e
|
@ -2,7 +2,6 @@ package pgtype
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -50,6 +49,28 @@ func (Int2Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case BinaryFormatCode:
|
case BinaryFormatCode:
|
||||||
|
switch target.(type) {
|
||||||
|
case *int8:
|
||||||
|
return scanPlanBinaryInt2ToInt8{}
|
||||||
|
case *int16:
|
||||||
|
return scanPlanBinaryInt2ToInt16{}
|
||||||
|
case *int32:
|
||||||
|
return scanPlanBinaryInt2ToInt32{}
|
||||||
|
case *int64:
|
||||||
|
return scanPlanBinaryInt2ToInt64{}
|
||||||
|
case *int:
|
||||||
|
return scanPlanBinaryInt2ToInt{}
|
||||||
|
case *uint8:
|
||||||
|
return scanPlanBinaryInt2ToUint8{}
|
||||||
|
case *uint16:
|
||||||
|
return scanPlanBinaryInt2ToUint16{}
|
||||||
|
case *uint32:
|
||||||
|
return scanPlanBinaryInt2ToUint32{}
|
||||||
|
case *uint64:
|
||||||
|
return scanPlanBinaryInt2ToUint64{}
|
||||||
|
case *uint:
|
||||||
|
return scanPlanBinaryInt2ToUint{}
|
||||||
|
}
|
||||||
case TextFormatCode:
|
case TextFormatCode:
|
||||||
switch target.(type) {
|
switch target.(type) {
|
||||||
case *int8:
|
case *int8:
|
||||||
|
@ -111,23 +132,3 @@ func (c Int2Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
|
||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type scanPlanBinaryInt2ToInt16 struct{}
|
|
||||||
|
|
||||||
func (scanPlanBinaryInt2ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
|
||||||
if src == nil {
|
|
||||||
return fmt.Errorf("cannot scan null into %T", dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(src) != 2 {
|
|
||||||
return fmt.Errorf("invalid length for int2: %v", len(src))
|
|
||||||
}
|
|
||||||
|
|
||||||
p, ok := (dst).(*int16)
|
|
||||||
if !ok {
|
|
||||||
return ErrScanTargetTypeChanged
|
|
||||||
}
|
|
||||||
|
|
||||||
*p = int16(binary.BigEndian.Uint16(src))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package pgtype
|
package pgtype
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -214,3 +216,249 @@ func (scanPlanTextAnyToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, sr
|
||||||
*p = uint(n)
|
*p = uint(n)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToInt8 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for int2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*int8)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int16(binary.BigEndian.Uint16(src))
|
||||||
|
if n < math.MinInt8 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for int8", n)
|
||||||
|
} else if n > math.MaxInt8 {
|
||||||
|
return fmt.Errorf("%d is greater than maximum value for int8", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = int8(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToUint8 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for uint2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*uint8)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int16(binary.BigEndian.Uint16(src))
|
||||||
|
if n < 0 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for uint8", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n > math.MaxUint8 {
|
||||||
|
return fmt.Errorf("%d is greater than maximum value for uint8", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = uint8(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToInt16 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for int2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*int16)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = int16(binary.BigEndian.Uint16(src))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToUint16 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for uint2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*uint16)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int16(binary.BigEndian.Uint16(src))
|
||||||
|
if n < 0 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for uint16", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = uint16(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToInt32 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for int2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*int32)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = int32(binary.BigEndian.Uint16(src))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToUint32 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for uint2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*uint32)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int16(binary.BigEndian.Uint16(src))
|
||||||
|
if n < 0 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for uint32", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = uint32(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToInt64 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for int2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*int64)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = int64(binary.BigEndian.Uint16(src))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToUint64 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for uint2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*uint64)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int16(binary.BigEndian.Uint16(src))
|
||||||
|
if n < 0 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for uint64", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = uint64(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToInt struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for int2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*int)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = int(binary.BigEndian.Uint16(src))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt2ToUint struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt2ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 2 {
|
||||||
|
return fmt.Errorf("invalid length for uint2: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*uint)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int64(binary.BigEndian.Uint16(src))
|
||||||
|
if n < 0 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for uint", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = uint(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -54,3 +54,138 @@ func (scanPlanTextAnyToUint<%= type_suffix %>) Scan(ci *ConnInfo, oid uint32, fo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<% [
|
||||||
|
[16, 8],
|
||||||
|
[16, 16],
|
||||||
|
[16, 32],
|
||||||
|
[16, 64],
|
||||||
|
].each do |src_bit_size, dst_bit_size| %>
|
||||||
|
<% src_byte_size = src_bit_size / 8 %>
|
||||||
|
type scanPlanBinaryInt<%= src_byte_size %>ToInt<%= dst_bit_size %> struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt<%= src_byte_size %>ToInt<%= dst_bit_size %>) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != <%= src_byte_size %> {
|
||||||
|
return fmt.Errorf("invalid length for int<%= src_byte_size %>: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*int<%= dst_bit_size %>)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
<% if dst_bit_size < src_bit_size %>
|
||||||
|
n := int<%= src_bit_size %>(binary.BigEndian.Uint<%= src_bit_size %>(src))
|
||||||
|
if n < math.MinInt<%= dst_bit_size %> {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for int<%= dst_bit_size %>", n)
|
||||||
|
} else if n > math.MaxInt<%= dst_bit_size %> {
|
||||||
|
return fmt.Errorf("%d is greater than maximum value for int<%= dst_bit_size %>", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = int<%= dst_bit_size %>(n)
|
||||||
|
<% else %>
|
||||||
|
*p = int<%= dst_bit_size %>(binary.BigEndian.Uint<%= src_bit_size %>(src))
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt<%= src_byte_size %>ToUint<%= dst_bit_size %> struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt<%= src_byte_size %>ToUint<%= dst_bit_size %>) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != <%= src_byte_size %> {
|
||||||
|
return fmt.Errorf("invalid length for uint<%= src_byte_size %>: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*uint<%= dst_bit_size %>)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int<%= src_bit_size %>(binary.BigEndian.Uint<%= src_bit_size %>(src))
|
||||||
|
if n < 0 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for uint<%= dst_bit_size %>", n)
|
||||||
|
}
|
||||||
|
<% if dst_bit_size < src_bit_size %>
|
||||||
|
if n > math.MaxUint<%= dst_bit_size %> {
|
||||||
|
return fmt.Errorf("%d is greater than maximum value for uint<%= dst_bit_size %>", n)
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
|
*p = uint<%= dst_bit_size %>(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% [16].each do |src_bit_size| %>
|
||||||
|
<% src_byte_size = src_bit_size / 8 %>
|
||||||
|
type scanPlanBinaryInt<%= src_byte_size %>ToInt struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt<%= src_byte_size %>ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != <%= src_byte_size %> {
|
||||||
|
return fmt.Errorf("invalid length for int<%= src_byte_size %>: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*int)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
<% if 32 < src_bit_size %>
|
||||||
|
n := int64(binary.BigEndian.Uint<%= src_bit_size %>(src))
|
||||||
|
if n < math.MinInt {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for int", n)
|
||||||
|
} else if n > math.MaxInt {
|
||||||
|
return fmt.Errorf("%d is greater than maximum value for int", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = int(n)
|
||||||
|
<% else %>
|
||||||
|
*p = int(binary.BigEndian.Uint<%= src_bit_size %>(src))
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryInt<%= src_byte_size %>ToUint struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryInt<%= src_byte_size %>ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan null into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != <%= src_byte_size %> {
|
||||||
|
return fmt.Errorf("invalid length for uint<%= src_byte_size %>: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := (dst).(*uint)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int64(binary.BigEndian.Uint<%= src_bit_size %>(src))
|
||||||
|
if n < 0 {
|
||||||
|
return fmt.Errorf("%d is less than minimum value for uint", n)
|
||||||
|
}
|
||||||
|
<% if 32 < src_bit_size %>
|
||||||
|
if uint64(n) > math.MaxUint {
|
||||||
|
return fmt.Errorf("%d is greater than maximum value for uint", n)
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
|
*p = uint(n)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
|
|
Loading…
Reference in New Issue