1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "encoding/binary"
6 "fmt"
7
8 "github.com/jackc/pgio"
9 )
10
11 type Int4multirange struct {
12 Ranges []Int4range
13 Status Status
14 }
15
16 func (dst *Int4multirange) Set(src interface{}) error {
17
18 if src == nil {
19 *dst = Int4multirange{Status: Null}
20 return nil
21 }
22
23 switch value := src.(type) {
24 case Int4multirange:
25 *dst = value
26 case *Int4multirange:
27 *dst = *value
28 case string:
29 return dst.DecodeText(nil, []byte(value))
30 case []Int4range:
31 if value == nil {
32 *dst = Int4multirange{Status: Null}
33 } else if len(value) == 0 {
34 *dst = Int4multirange{Status: Present}
35 } else {
36 elements := make([]Int4range, len(value))
37 for i := range value {
38 if err := elements[i].Set(value[i]); err != nil {
39 return err
40 }
41 }
42 *dst = Int4multirange{
43 Ranges: elements,
44 Status: Present,
45 }
46 }
47 case []*Int4range:
48 if value == nil {
49 *dst = Int4multirange{Status: Null}
50 } else if len(value) == 0 {
51 *dst = Int4multirange{Status: Present}
52 } else {
53 elements := make([]Int4range, len(value))
54 for i := range value {
55 if err := elements[i].Set(value[i]); err != nil {
56 return err
57 }
58 }
59 *dst = Int4multirange{
60 Ranges: elements,
61 Status: Present,
62 }
63 }
64 default:
65 return fmt.Errorf("cannot convert %v to Int4multirange", src)
66 }
67
68 return nil
69
70 }
71
72 func (dst Int4multirange) 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
83 func (src *Int4multirange) AssignTo(dst interface{}) error {
84 return fmt.Errorf("cannot assign %v to %T", src, dst)
85 }
86
87 func (dst *Int4multirange) DecodeText(ci *ConnInfo, src []byte) error {
88 if src == nil {
89 *dst = Int4multirange{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 []Int4range
99
100 if len(utmr.Elements) > 0 {
101 elements = make([]Int4range, len(utmr.Elements))
102
103 for i, s := range utmr.Elements {
104 var elem Int4range
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 = Int4multirange{Ranges: elements, Status: Present}
118
119 return nil
120 }
121
122 func (dst *Int4multirange) DecodeBinary(ci *ConnInfo, src []byte) error {
123 if src == nil {
124 *dst = Int4multirange{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 = Int4multirange{Status: Present}
135 return nil
136 }
137
138 elements := make([]Int4range, 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 = Int4multirange{Ranges: elements, Status: Present}
155 return nil
156 }
157
158 func (src Int4multirange) 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
191 func (src Int4multirange) 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
219 func (dst *Int4multirange) 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
237 func (src Int4multirange) Value() (driver.Value, error) {
238 return EncodeValueText(src)
239 }
240
View as plain text