1 package pgtype_test
2
3 import (
4 "reflect"
5 "testing"
6 "time"
7
8 "github.com/jackc/pgtype"
9 "github.com/jackc/pgtype/testutil"
10 )
11
12 func TestDateArrayTranscode(t *testing.T) {
13 testutil.TestSuccessfulTranscode(t, "date[]", []interface{}{
14 &pgtype.DateArray{
15 Elements: nil,
16 Dimensions: nil,
17 Status: pgtype.Present,
18 },
19 &pgtype.DateArray{
20 Elements: []pgtype.Date{
21 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
22 {Status: pgtype.Null},
23 },
24 Dimensions: []pgtype.ArrayDimension{{Length: 2, LowerBound: 1}},
25 Status: pgtype.Present,
26 },
27 &pgtype.DateArray{Status: pgtype.Null},
28 &pgtype.DateArray{
29 Elements: []pgtype.Date{
30 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
31 {Time: time.Date(2016, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
32 {Time: time.Date(2017, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
33 {Time: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
34 {Status: pgtype.Null},
35 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
36 },
37 Dimensions: []pgtype.ArrayDimension{{Length: 3, LowerBound: 1}, {Length: 2, LowerBound: 1}},
38 Status: pgtype.Present,
39 },
40 &pgtype.DateArray{
41 Elements: []pgtype.Date{
42 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
43 {Time: time.Date(2015, 2, 2, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
44 {Time: time.Date(2015, 2, 3, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
45 {Time: time.Date(2015, 2, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
46 },
47 Dimensions: []pgtype.ArrayDimension{
48 {Length: 2, LowerBound: 4},
49 {Length: 2, LowerBound: 2},
50 },
51 Status: pgtype.Present,
52 },
53 })
54 }
55
56 func TestDateArraySet(t *testing.T) {
57 successfulTests := []struct {
58 source interface{}
59 result pgtype.DateArray
60 }{
61 {
62 source: []time.Time{time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)},
63 result: pgtype.DateArray{
64 Elements: []pgtype.Date{{Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
65 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
66 Status: pgtype.Present},
67 },
68 {
69 source: []customDate{{t: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)}},
70 result: pgtype.DateArray{
71 Elements: []pgtype.Date{{Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
72 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
73 Status: pgtype.Present,
74 },
75 },
76 {
77 source: (([]time.Time)(nil)),
78 result: pgtype.DateArray{Status: pgtype.Null},
79 },
80 {
81 source: [][]time.Time{
82 {time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)},
83 {time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC)}},
84 result: pgtype.DateArray{
85 Elements: []pgtype.Date{
86 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
87 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
88 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
89 Status: pgtype.Present},
90 },
91 {
92 source: [][][][]time.Time{
93 {{{
94 time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC),
95 time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC),
96 time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC)}}},
97 {{{
98 time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC),
99 time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC),
100 time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC)}}}},
101 result: pgtype.DateArray{
102 Elements: []pgtype.Date{
103 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
104 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
105 {Time: time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
106 {Time: time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
107 {Time: time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
108 {Time: time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
109 Dimensions: []pgtype.ArrayDimension{
110 {LowerBound: 1, Length: 2},
111 {LowerBound: 1, Length: 1},
112 {LowerBound: 1, Length: 1},
113 {LowerBound: 1, Length: 3}},
114 Status: pgtype.Present},
115 },
116 {
117 source: [2][1]time.Time{
118 {time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)},
119 {time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC)}},
120 result: pgtype.DateArray{
121 Elements: []pgtype.Date{
122 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
123 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
124 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
125 Status: pgtype.Present},
126 },
127 {
128 source: [2][1][1][3]time.Time{
129 {{{
130 time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC),
131 time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC),
132 time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC)}}},
133 {{{
134 time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC),
135 time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC),
136 time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC)}}}},
137 result: pgtype.DateArray{
138 Elements: []pgtype.Date{
139 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
140 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
141 {Time: time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
142 {Time: time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
143 {Time: time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
144 {Time: time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
145 Dimensions: []pgtype.ArrayDimension{
146 {LowerBound: 1, Length: 2},
147 {LowerBound: 1, Length: 1},
148 {LowerBound: 1, Length: 1},
149 {LowerBound: 1, Length: 3}},
150 Status: pgtype.Present},
151 },
152 }
153
154 for i, tt := range successfulTests {
155 var r pgtype.DateArray
156 err := r.Set(tt.source)
157 if err != nil {
158 t.Errorf("%d: %v", i, err)
159 }
160
161 if !reflect.DeepEqual(r, tt.result) {
162 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
163 }
164 }
165 }
166
167 func TestDateArrayAssignTo(t *testing.T) {
168 var timeSlice []time.Time
169 var timeSliceDim2 [][]time.Time
170 var timeSliceDim4 [][][][]time.Time
171 var timeArrayDim2 [2][1]time.Time
172 var timeArrayDim4 [2][1][1][3]time.Time
173 var customDateSlice []customDate
174
175 simpleTests := []struct {
176 src pgtype.DateArray
177 dst interface{}
178 expected interface{}
179 }{
180 {
181 src: pgtype.DateArray{
182 Elements: []pgtype.Date{{Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
183 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
184 Status: pgtype.Present,
185 },
186 dst: &timeSlice,
187 expected: []time.Time{time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)},
188 },
189 {
190 src: pgtype.DateArray{
191 Elements: []pgtype.Date{{Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
192 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
193 Status: pgtype.Present,
194 },
195 dst: &customDateSlice,
196 expected: []customDate{{t: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)}},
197 },
198 {
199 src: pgtype.DateArray{Status: pgtype.Null},
200 dst: &timeSlice,
201 expected: (([]time.Time)(nil)),
202 },
203 {
204 src: pgtype.DateArray{Status: pgtype.Present},
205 dst: &timeSlice,
206 expected: []time.Time{},
207 },
208 {
209 src: pgtype.DateArray{
210 Elements: []pgtype.Date{
211 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
212 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
213 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
214 Status: pgtype.Present},
215 dst: &timeSliceDim2,
216 expected: [][]time.Time{
217 {time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)},
218 {time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC)}},
219 },
220 {
221 src: pgtype.DateArray{
222 Elements: []pgtype.Date{
223 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
224 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
225 {Time: time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
226 {Time: time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
227 {Time: time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
228 {Time: time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
229 Dimensions: []pgtype.ArrayDimension{
230 {LowerBound: 1, Length: 2},
231 {LowerBound: 1, Length: 1},
232 {LowerBound: 1, Length: 1},
233 {LowerBound: 1, Length: 3}},
234 Status: pgtype.Present},
235 dst: &timeSliceDim4,
236 expected: [][][][]time.Time{
237 {{{
238 time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC),
239 time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC),
240 time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC)}}},
241 {{{
242 time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC),
243 time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC),
244 time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC)}}}},
245 },
246 {
247 src: pgtype.DateArray{
248 Elements: []pgtype.Date{
249 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
250 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
251 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
252 Status: pgtype.Present},
253 dst: &timeArrayDim2,
254 expected: [2][1]time.Time{
255 {time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC)},
256 {time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC)}},
257 },
258 {
259 src: pgtype.DateArray{
260 Elements: []pgtype.Date{
261 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
262 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
263 {Time: time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
264 {Time: time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
265 {Time: time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
266 {Time: time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
267 Dimensions: []pgtype.ArrayDimension{
268 {LowerBound: 1, Length: 2},
269 {LowerBound: 1, Length: 1},
270 {LowerBound: 1, Length: 1},
271 {LowerBound: 1, Length: 3}},
272 Status: pgtype.Present},
273 dst: &timeArrayDim4,
274 expected: [2][1][1][3]time.Time{
275 {{{
276 time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC),
277 time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC),
278 time.Date(2017, 5, 6, 0, 0, 0, 0, time.UTC)}}},
279 {{{
280 time.Date(2018, 7, 8, 0, 0, 0, 0, time.UTC),
281 time.Date(2019, 9, 10, 0, 0, 0, 0, time.UTC),
282 time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC)}}}},
283 },
284 }
285
286 for i, tt := range simpleTests {
287 err := tt.src.AssignTo(tt.dst)
288 if err != nil {
289 t.Errorf("%d: %v", i, err)
290 }
291
292 if dst := reflect.ValueOf(tt.dst).Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) {
293 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
294 }
295 }
296
297 errorTests := []struct {
298 src pgtype.DateArray
299 dst interface{}
300 }{
301 {
302 src: pgtype.DateArray{
303 Elements: []pgtype.Date{{Status: pgtype.Null}},
304 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
305 Status: pgtype.Present,
306 },
307 dst: &timeSlice,
308 },
309 {
310 src: pgtype.DateArray{
311 Elements: []pgtype.Date{
312 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
313 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
314 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}},
315 Status: pgtype.Present},
316 dst: &timeArrayDim2,
317 },
318 {
319 src: pgtype.DateArray{
320 Elements: []pgtype.Date{
321 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
322 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
323 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}},
324 Status: pgtype.Present},
325 dst: &timeSlice,
326 },
327 {
328 src: pgtype.DateArray{
329 Elements: []pgtype.Date{
330 {Time: time.Date(2015, 2, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
331 {Time: time.Date(2016, 3, 4, 0, 0, 0, 0, time.UTC), Status: pgtype.Present}},
332 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
333 Status: pgtype.Present},
334 dst: &timeArrayDim4,
335 },
336 }
337
338 for i, tt := range errorTests {
339 err := tt.src.AssignTo(tt.dst)
340 if err == nil {
341 t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst)
342 }
343 }
344
345 }
346
View as plain text