...
1 package pgtype
2
3 import (
4 "fmt"
5 "reflect"
6 )
7
8
9
10
11
12
13 type Record struct {
14 Fields []Value
15 Status Status
16 }
17
18 func (dst *Record) Set(src interface{}) error {
19 if src == nil {
20 *dst = Record{Status: Null}
21 return nil
22 }
23
24 if value, ok := src.(interface{ Get() interface{} }); ok {
25 value2 := value.Get()
26 if value2 != value {
27 return dst.Set(value2)
28 }
29 }
30
31 switch value := src.(type) {
32 case []Value:
33 *dst = Record{Fields: value, Status: Present}
34 default:
35 return fmt.Errorf("cannot convert %v to Record", src)
36 }
37
38 return nil
39 }
40
41 func (dst Record) Get() interface{} {
42 switch dst.Status {
43 case Present:
44 return dst.Fields
45 case Null:
46 return nil
47 default:
48 return dst.Status
49 }
50 }
51
52 func (src *Record) AssignTo(dst interface{}) error {
53 switch src.Status {
54 case Present:
55 switch v := dst.(type) {
56 case *[]Value:
57 *v = make([]Value, len(src.Fields))
58 copy(*v, src.Fields)
59 return nil
60 case *[]interface{}:
61 *v = make([]interface{}, len(src.Fields))
62 for i := range *v {
63 (*v)[i] = src.Fields[i].Get()
64 }
65 return nil
66 default:
67 if nextDst, retry := GetAssignToDstType(dst); retry {
68 return src.AssignTo(nextDst)
69 }
70 return fmt.Errorf("unable to assign to %T", dst)
71 }
72 case Null:
73 return NullAssignTo(dst)
74 }
75
76 return fmt.Errorf("cannot decode %#v into %T", src, dst)
77 }
78
79 func prepareNewBinaryDecoder(ci *ConnInfo, fieldOID uint32, v *Value) (BinaryDecoder, error) {
80 var binaryDecoder BinaryDecoder
81
82 if dt, ok := ci.DataTypeForOID(fieldOID); ok {
83 binaryDecoder, _ = dt.Value.(BinaryDecoder)
84 } else {
85 return nil, fmt.Errorf("unknown oid while decoding record: %v", fieldOID)
86 }
87
88 if binaryDecoder == nil {
89 return nil, fmt.Errorf("no binary decoder registered for: %v", fieldOID)
90 }
91
92
93 binaryDecoder = reflect.New(reflect.ValueOf(binaryDecoder).Elem().Type()).Interface().(BinaryDecoder)
94 *v = binaryDecoder.(Value)
95 return binaryDecoder, nil
96 }
97
98 func (dst *Record) DecodeBinary(ci *ConnInfo, src []byte) error {
99 if src == nil {
100 *dst = Record{Status: Null}
101 return nil
102 }
103
104 scanner := NewCompositeBinaryScanner(ci, src)
105
106 fields := make([]Value, scanner.FieldCount())
107
108 for i := 0; scanner.Next(); i++ {
109 binaryDecoder, err := prepareNewBinaryDecoder(ci, scanner.OID(), &fields[i])
110 if err != nil {
111 return err
112 }
113
114 if err = binaryDecoder.DecodeBinary(ci, scanner.Bytes()); err != nil {
115 return err
116 }
117 }
118
119 if scanner.Err() != nil {
120 return scanner.Err()
121 }
122
123 *dst = Record{Fields: fields, Status: Present}
124
125 return nil
126 }
127
View as plain text