From 4faf97cc588126dda160fc360680719572a23105 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Fri, 17 Feb 2017 22:20:18 -0600 Subject: [PATCH] wip --- query.go | 11 ++++++++++- values.go | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/query.go b/query.go index 99b383e0..3bf1a87c 100644 --- a/query.go +++ b/query.go @@ -219,6 +219,15 @@ func (rows *Rows) Scan(dest ...interface{}) (err error) { if err != nil { rows.Fatal(scanArgError{col: i, err: err}) } + } else if s, ok := d.(ScannerV3); ok { + val, err := decodeByOID(vr) + if err != nil { + rows.Fatal(scanArgError{col: i, err: err}) + } + err = s.ScanPgxV3(nil, val) + if err != nil { + rows.Fatal(scanArgError{col: i, err: err}) + } } else if s, ok := d.(sql.Scanner); ok { var val interface{} if 0 <= vr.Len() { @@ -296,7 +305,7 @@ func (rows *Rows) Values() ([]interface{}, error) { values = append(values, nil) continue } - + // TODO - consider what are the implications of returning complex types since database/sql uses this method switch vr.Type().FormatCode { // All intrinsic types (except string) are encoded with binary // encoding so anything else should be treated as a string diff --git a/values.go b/values.go index 45ed914c..4606bcb3 100644 --- a/values.go +++ b/values.go @@ -200,6 +200,10 @@ type Encoder interface { FormatCode() int16 } +type ScannerV3 interface { + ScanPgxV3(fieldDescription interface{}, src interface{}) error +} + // NullFloat32 represents an float4 that may be null. NullFloat32 implements the // Scanner and Encoder interfaces so it may be used both as an argument to // Query[Row] and a destination for Scan. @@ -1166,6 +1170,20 @@ func stripNamedType(val *reflect.Value) (interface{}, bool) { return nil, false } +func decodeByOID(vr *ValueReader) (interface{}, error) { + switch vr.Type().DataType { + case Int2OID, Int4OID, Int8OID: + n := decodeInt(vr) + return n, vr.Err() + case BoolOID: + b := decodeBool(vr) + return b, vr.Err() + default: + buf := vr.ReadBytes(vr.Len()) + return buf, vr.Err() + } +} + // Decode decodes from vr into d. d must be a pointer. This allows // implementations of the Decoder interface to delegate the actual work of // decoding to the built-in functionality.