Replace some old database/sql compatibility

query-exec-mode
Jack Christensen 2022-01-22 11:21:12 -06:00
parent ad785d8134
commit eb0a4c9626
3 changed files with 16 additions and 83 deletions

View File

@ -461,6 +461,8 @@ func (w timeWrapper) TimeValue() (Time, error) {
type durationWrapper time.Duration
func (w durationWrapper) SkipUnderlyingTypePlan() {}
func (w *durationWrapper) ScanInterval(v Interval) error {
if !v.Valid {
return fmt.Errorf("cannot scan NULL into *time.Interval")

View File

@ -1,41 +0,0 @@
package pgtype
import (
"database/sql/driver"
"errors"
)
func DatabaseSQLValue(ci *ConnInfo, src Value) (interface{}, error) {
if valuer, ok := src.(driver.Valuer); ok {
return valuer.Value()
}
if textEncoder, ok := src.(TextEncoder); ok {
buf, err := textEncoder.EncodeText(ci, nil)
if err != nil {
return nil, err
}
return string(buf), nil
}
if binaryEncoder, ok := src.(BinaryEncoder); ok {
buf, err := binaryEncoder.EncodeBinary(ci, nil)
if err != nil {
return nil, err
}
return buf, nil
}
return nil, errors.New("cannot convert to database/sql compatible value")
}
func EncodeValueText(src TextEncoder) (interface{}, error) {
buf, err := src.EncodeText(nil, make([]byte, 0, 32))
if err != nil {
return nil, err
}
if buf == nil {
return nil, nil
}
return string(buf), err
}

View File

@ -520,41 +520,6 @@ func (plan scanPlanDstTextDecoder) Scan(ci *ConnInfo, oid uint32, formatCode int
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
type scanPlanDataTypeSQLScanner DataType
func (plan *scanPlanDataTypeSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
scanner, ok := dst.(sql.Scanner)
if !ok {
newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
dt := (*DataType)(plan)
if dt.Codec != nil {
sqlValue, err := dt.Codec.DecodeDatabaseSQLValue(ci, oid, formatCode, src)
if err != nil {
return err
}
return scanner.Scan(sqlValue)
}
var err error
switch formatCode {
case BinaryFormatCode:
err = dt.binaryDecoder.DecodeBinary(ci, src)
case TextFormatCode:
err = dt.textDecoder.DecodeText(ci, src)
}
if err != nil {
return err
}
sqlSrc, err := DatabaseSQLValue(ci, dt.Value)
if err != nil {
return err
}
return scanner.Scan(sqlSrc)
}
type scanPlanDataTypeAssignTo DataType
func (plan *scanPlanDataTypeAssignTo) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
@ -596,6 +561,18 @@ func (plan *scanPlanDataTypeAssignTo) Scan(ci *ConnInfo, oid uint32, formatCode
return assignToErr
}
type scanPlanCodecSQLScanner struct{ c Codec }
func (plan *scanPlanCodecSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
value, err := plan.c.DecodeDatabaseSQLValue(ci, oid, formatCode, src)
if err != nil {
return err
}
scanner := dst.(sql.Scanner)
return scanner.Scan(value)
}
type scanPlanSQLScanner struct{}
func (scanPlanSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
@ -1176,7 +1153,7 @@ func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, dst interface{}) Scan
for _, f := range tryWrappers {
if wrapperPlan, nextDst, ok := f(dst); ok {
if nextPlan := ci.PlanScan(oid, formatCode, nextDst); nextPlan != nil {
if _, ok := nextPlan.(*scanPlanDataTypeAssignTo); !ok { // avoid fallthrough -- this will go away when old system removed.
if _, ok := nextPlan.(scanPlanReflection); !ok { // avoid fallthrough -- this will go away when old system removed.
wrapperPlan.SetNext(nextPlan)
return wrapperPlan
}
@ -1187,15 +1164,10 @@ func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, dst interface{}) Scan
if _, ok := dst.(*interface{}); ok {
return &pointerEmptyInterfaceScanPlan{codec: dt.Codec}
}
}
if dt != nil {
if _, ok := dst.(sql.Scanner); ok {
if _, found := ci.preferAssignToOverSQLScannerTypes[reflect.TypeOf(dst)]; !found {
return (*scanPlanDataTypeSQLScanner)(dt)
}
return &scanPlanCodecSQLScanner{c: dt.Codec}
}
return (*scanPlanDataTypeAssignTo)(dt)
}
if _, ok := dst.(sql.Scanner); ok {