Create ROW helper for adhoc decoding of records
This commit is contained in:
@@ -71,7 +71,20 @@ create type mytype as (
|
||||
}
|
||||
|
||||
fmt.Printf("Second row: %v\n", result)
|
||||
|
||||
// Adhoc rows can be decoded inplace without boilerplate (works with composite types too)
|
||||
var isNull bool
|
||||
var a int
|
||||
var b *string
|
||||
|
||||
if err = conn.QueryRow(context.Background(), "select (2, 'bar')::mytype", pgx.QueryResultFormats{pgx.BinaryFormatCode}).Scan(pgtype.ROW(&isNull, &a, &b)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Adhoc: isNull=%v a=%d b=%s", isNull, a, *b)
|
||||
|
||||
// Output:
|
||||
// First row: a=1 b=foo
|
||||
// Second row: <nil>
|
||||
// Adhoc: isNull=false a=2 b=bar
|
||||
}
|
||||
|
||||
+28
@@ -471,6 +471,34 @@ func ScanRowValue(ci *ConnInfo, src []byte, dst ...Value) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ROW allows deconstructing row values (records and composite types) into
|
||||
// fields directly without creating your own type and implementing decoder interfaces
|
||||
func ROW(isNull *bool, fields ...interface{}) BinaryDecoderFunc {
|
||||
return func(ci *ConnInfo, src []byte) error {
|
||||
var record Record
|
||||
if err := record.DecodeBinary(ci, src); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if record.Status == Null {
|
||||
*isNull = true
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(record.Fields) != len(fields) {
|
||||
return errors.Errorf("can't scan row value, number of fields don't match: row fields count=%d desired fields count=%d", len(record.Fields), len(fields))
|
||||
}
|
||||
|
||||
for i, f := range record.Fields {
|
||||
if err := f.AssignTo(fields[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
kindTypes = map[reflect.Kind]reflect.Type{
|
||||
reflect.Bool: reflect.TypeOf(false),
|
||||
|
||||
@@ -158,6 +158,15 @@ type TextEncoder interface {
|
||||
EncodeText(ci *ConnInfo, buf []byte) (newBuf []byte, err error)
|
||||
}
|
||||
|
||||
//The BinaryDecoderFunc type is an adapter to allow the use of ordinary functions as BinaryDecoder types.
|
||||
// If f is a function with the appropriate signature, BinaryDecoderFunc(f) is a BinaryDecoder that calls f.
|
||||
type BinaryDecoderFunc func(ci *ConnInfo, src []byte) error
|
||||
|
||||
// DecodeBinary calls f(ci, src)
|
||||
func (f BinaryDecoderFunc) DecodeBinary(ci *ConnInfo, src []byte) error {
|
||||
return f(ci, src)
|
||||
}
|
||||
|
||||
var errUndefined = errors.New("cannot encode status undefined")
|
||||
var errBadStatus = errors.New("invalid status")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user