1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "fmt"
6
7 "github.com/jackc/pgio"
8 )
9
10 type Tsrange struct {
11 Lower Timestamp
12 Upper Timestamp
13 LowerType BoundType
14 UpperType BoundType
15 Status Status
16 }
17
18 func (dst *Tsrange) Set(src interface{}) error {
19
20 if src == nil {
21 *dst = Tsrange{Status: Null}
22 return nil
23 }
24
25 switch value := src.(type) {
26 case Tsrange:
27 *dst = value
28 case *Tsrange:
29 *dst = *value
30 case string:
31 return dst.DecodeText(nil, []byte(value))
32 default:
33 return fmt.Errorf("cannot convert %v to Tsrange", src)
34 }
35
36 return nil
37 }
38
39 func (dst Tsrange) Get() interface{} {
40 switch dst.Status {
41 case Present:
42 return dst
43 case Null:
44 return nil
45 default:
46 return dst.Status
47 }
48 }
49
50 func (src *Tsrange) AssignTo(dst interface{}) error {
51 return fmt.Errorf("cannot assign %v to %T", src, dst)
52 }
53
54 func (dst *Tsrange) DecodeText(ci *ConnInfo, src []byte) error {
55 if src == nil {
56 *dst = Tsrange{Status: Null}
57 return nil
58 }
59
60 utr, err := ParseUntypedTextRange(string(src))
61 if err != nil {
62 return err
63 }
64
65 *dst = Tsrange{Status: Present}
66
67 dst.LowerType = utr.LowerType
68 dst.UpperType = utr.UpperType
69
70 if dst.LowerType == Empty {
71 return nil
72 }
73
74 if dst.LowerType == Inclusive || dst.LowerType == Exclusive {
75 if err := dst.Lower.DecodeText(ci, []byte(utr.Lower)); err != nil {
76 return err
77 }
78 }
79
80 if dst.UpperType == Inclusive || dst.UpperType == Exclusive {
81 if err := dst.Upper.DecodeText(ci, []byte(utr.Upper)); err != nil {
82 return err
83 }
84 }
85
86 return nil
87 }
88
89 func (dst *Tsrange) DecodeBinary(ci *ConnInfo, src []byte) error {
90 if src == nil {
91 *dst = Tsrange{Status: Null}
92 return nil
93 }
94
95 ubr, err := ParseUntypedBinaryRange(src)
96 if err != nil {
97 return err
98 }
99
100 *dst = Tsrange{Status: Present}
101
102 dst.LowerType = ubr.LowerType
103 dst.UpperType = ubr.UpperType
104
105 if dst.LowerType == Empty {
106 return nil
107 }
108
109 if dst.LowerType == Inclusive || dst.LowerType == Exclusive {
110 if err := dst.Lower.DecodeBinary(ci, ubr.Lower); err != nil {
111 return err
112 }
113 }
114
115 if dst.UpperType == Inclusive || dst.UpperType == Exclusive {
116 if err := dst.Upper.DecodeBinary(ci, ubr.Upper); err != nil {
117 return err
118 }
119 }
120
121 return nil
122 }
123
124 func (src Tsrange) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
125 switch src.Status {
126 case Null:
127 return nil, nil
128 case Undefined:
129 return nil, errUndefined
130 }
131
132 switch src.LowerType {
133 case Exclusive, Unbounded:
134 buf = append(buf, '(')
135 case Inclusive:
136 buf = append(buf, '[')
137 case Empty:
138 return append(buf, "empty"...), nil
139 default:
140 return nil, fmt.Errorf("unknown lower bound type %v", src.LowerType)
141 }
142
143 var err error
144
145 if src.LowerType != Unbounded {
146 buf, err = src.Lower.EncodeText(ci, buf)
147 if err != nil {
148 return nil, err
149 } else if buf == nil {
150 return nil, fmt.Errorf("Lower cannot be null unless LowerType is Unbounded")
151 }
152 }
153
154 buf = append(buf, ',')
155
156 if src.UpperType != Unbounded {
157 buf, err = src.Upper.EncodeText(ci, buf)
158 if err != nil {
159 return nil, err
160 } else if buf == nil {
161 return nil, fmt.Errorf("Upper cannot be null unless UpperType is Unbounded")
162 }
163 }
164
165 switch src.UpperType {
166 case Exclusive, Unbounded:
167 buf = append(buf, ')')
168 case Inclusive:
169 buf = append(buf, ']')
170 default:
171 return nil, fmt.Errorf("unknown upper bound type %v", src.UpperType)
172 }
173
174 return buf, nil
175 }
176
177 func (src Tsrange) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
178 switch src.Status {
179 case Null:
180 return nil, nil
181 case Undefined:
182 return nil, errUndefined
183 }
184
185 var rangeType byte
186 switch src.LowerType {
187 case Inclusive:
188 rangeType |= lowerInclusiveMask
189 case Unbounded:
190 rangeType |= lowerUnboundedMask
191 case Exclusive:
192 case Empty:
193 return append(buf, emptyMask), nil
194 default:
195 return nil, fmt.Errorf("unknown LowerType: %v", src.LowerType)
196 }
197
198 switch src.UpperType {
199 case Inclusive:
200 rangeType |= upperInclusiveMask
201 case Unbounded:
202 rangeType |= upperUnboundedMask
203 case Exclusive:
204 default:
205 return nil, fmt.Errorf("unknown UpperType: %v", src.UpperType)
206 }
207
208 buf = append(buf, rangeType)
209
210 var err error
211
212 if src.LowerType != Unbounded {
213 sp := len(buf)
214 buf = pgio.AppendInt32(buf, -1)
215
216 buf, err = src.Lower.EncodeBinary(ci, buf)
217 if err != nil {
218 return nil, err
219 }
220 if buf == nil {
221 return nil, fmt.Errorf("Lower cannot be null unless LowerType is Unbounded")
222 }
223
224 pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
225 }
226
227 if src.UpperType != Unbounded {
228 sp := len(buf)
229 buf = pgio.AppendInt32(buf, -1)
230
231 buf, err = src.Upper.EncodeBinary(ci, buf)
232 if err != nil {
233 return nil, err
234 }
235 if buf == nil {
236 return nil, fmt.Errorf("Upper cannot be null unless UpperType is Unbounded")
237 }
238
239 pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
240 }
241
242 return buf, nil
243 }
244
245
246 func (dst *Tsrange) Scan(src interface{}) error {
247 if src == nil {
248 *dst = Tsrange{Status: Null}
249 return nil
250 }
251
252 switch src := src.(type) {
253 case string:
254 return dst.DecodeText(nil, []byte(src))
255 case []byte:
256 srcCopy := make([]byte, len(src))
257 copy(srcCopy, src)
258 return dst.DecodeText(nil, srcCopy)
259 }
260
261 return fmt.Errorf("cannot scan %T", src)
262 }
263
264
265 func (src Tsrange) Value() (driver.Value, error) {
266 return EncodeValueText(src)
267 }
268
View as plain text