1package pgtype
2
3import (
4 "database/sql/driver"
5 "encoding/binary"
6 "fmt"
7
8 "github.com/jackc/pgio"
9)
10
11type <%= multirange_type %> struct {
12 Ranges []<%= range_type %>
13 Status Status
14}
15
16func (dst *<%= multirange_type %>) Set(src interface{}) error {
17 //untyped nil and typed nil interfaces are different
18 if src == nil {
19 *dst = <%= multirange_type %>{Status: Null}
20 return nil
21 }
22
23 switch value := src.(type) {
24 case <%= multirange_type %>:
25 *dst = value
26 case *<%= multirange_type %>:
27 *dst = *value
28 case string:
29 return dst.DecodeText(nil, []byte(value))
30 case []<%= range_type %>:
31 if value == nil {
32 *dst = <%= multirange_type %>{Status: Null}
33 } else if len(value) == 0 {
34 *dst = <%= multirange_type %>{Status: Present}
35 } else {
36 elements := make([]<%= range_type %>, len(value))
37 for i := range value {
38 if err := elements[i].Set(value[i]); err != nil {
39 return err
40 }
41 }
42 *dst = <%= multirange_type %>{
43 Ranges: elements,
44 Status: Present,
45 }
46 }
47 case []*<%= range_type %>:
48 if value == nil {
49 *dst = <%= multirange_type %>{Status: Null}
50 } else if len(value) == 0 {
51 *dst = <%= multirange_type %>{Status: Present}
52 } else {
53 elements := make([]<%= range_type %>, len(value))
54 for i := range value {
55 if err := elements[i].Set(value[i]); err != nil {
56 return err
57 }
58 }
59 *dst = <%= multirange_type %>{
60 Ranges: elements,
61 Status: Present,
62 }
63 }
64 default:
65 return fmt.Errorf("cannot convert %v to <%= multirange_type %>", src)
66 }
67
68 return nil
69
70}
71
72func (dst <%= multirange_type %>) Get() interface{} {
73 switch dst.Status {
74 case Present:
75 return dst
76 case Null:
77 return nil
78 default:
79 return dst.Status
80 }
81}
82
83func (src *<%= multirange_type %>) AssignTo(dst interface{}) error {
84 return fmt.Errorf("cannot assign %v to %T", src, dst)
85}
86
87func (dst *<%= multirange_type %>) DecodeText(ci *ConnInfo, src []byte) error {
88 if src == nil {
89 *dst = <%= multirange_type %>{Status: Null}
90 return nil
91 }
92
93 utmr, err := ParseUntypedTextMultirange(string(src))
94 if err != nil {
95 return err
96 }
97
98 var elements []<%= range_type %>
99
100 if len(utmr.Elements) > 0 {
101 elements = make([]<%= range_type %>, len(utmr.Elements))
102
103 for i, s := range utmr.Elements {
104 var elem <%= range_type %>
105
106 elemSrc := []byte(s)
107
108 err = elem.DecodeText(ci, elemSrc)
109 if err != nil {
110 return err
111 }
112
113 elements[i] = elem
114 }
115 }
116
117 *dst = <%= multirange_type %>{Ranges: elements, Status: Present}
118
119 return nil
120}
121
122func (dst *<%= multirange_type %>) DecodeBinary(ci *ConnInfo, src []byte) error {
123 if src == nil {
124 *dst = <%= multirange_type %>{Status: Null}
125 return nil
126 }
127
128 rp := 0
129
130 numElems := int(binary.BigEndian.Uint32(src[rp:]))
131 rp += 4
132
133 if numElems == 0 {
134 *dst = <%= multirange_type %>{Status: Present}
135 return nil
136 }
137
138 elements := make([]<%= range_type %>, numElems)
139
140 for i := range elements {
141 elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
142 rp += 4
143 var elemSrc []byte
144 if elemLen >= 0 {
145 elemSrc = src[rp : rp+elemLen]
146 rp += elemLen
147 }
148 err := elements[i].DecodeBinary(ci, elemSrc)
149 if err != nil {
150 return err
151 }
152 }
153
154 *dst = <%= multirange_type %>{Ranges: elements, Status: Present}
155 return nil
156}
157
158func (src <%= multirange_type %>) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
159 switch src.Status {
160 case Null:
161 return nil, nil
162 case Undefined:
163 return nil, errUndefined
164 }
165
166 buf = append(buf, '{')
167
168 inElemBuf := make([]byte, 0, 32)
169 for i, elem := range src.Ranges {
170 if i > 0 {
171 buf = append(buf, ',')
172 }
173
174 elemBuf, err := elem.EncodeText(ci, inElemBuf)
175 if err != nil {
176 return nil, err
177 }
178 if elemBuf == nil {
179 return nil, fmt.Errorf("multi-range does not allow null range")
180 } else {
181 buf = append(buf, string(elemBuf)...)
182 }
183
184 }
185
186 buf = append(buf, '}')
187
188 return buf, nil
189}
190
191func (src <%= multirange_type %>) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
192 switch src.Status {
193 case Null:
194 return nil, nil
195 case Undefined:
196 return nil, errUndefined
197 }
198
199 buf = pgio.AppendInt32(buf, int32(len(src.Ranges)))
200
201 for i := range src.Ranges {
202 sp := len(buf)
203 buf = pgio.AppendInt32(buf, -1)
204
205 elemBuf, err := src.Ranges[i].EncodeBinary(ci, buf)
206 if err != nil {
207 return nil, err
208 }
209 if elemBuf != nil {
210 buf = elemBuf
211 pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
212 }
213 }
214
215 return buf, nil
216}
217
218// Scan implements the database/sql Scanner interface.
219func (dst *<%= multirange_type %>) Scan(src interface{}) error {
220 if src == nil {
221 return dst.DecodeText(nil, nil)
222 }
223
224 switch src := src.(type) {
225 case string:
226 return dst.DecodeText(nil, []byte(src))
227 case []byte:
228 srcCopy := make([]byte, len(src))
229 copy(srcCopy, src)
230 return dst.DecodeText(nil, srcCopy)
231 }
232
233 return fmt.Errorf("cannot scan %T", src)
234}
235
236// Value implements the database/sql/driver Valuer interface.
237func (src <%= multirange_type %>) Value() (driver.Value, error) {
238 return EncodeValueText(src)
239}
View as plain text