rdo-postgres 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Postgres::Array::TimestampTZ do
4
+ it "is a kind of ::Array" do
5
+ RDO::Postgres::Array::TimestampTZ.new.should be_a_kind_of(::Array)
6
+ end
7
+
8
+ describe "#to_s" do
9
+ context "with an empty array" do
10
+ let(:arr) { RDO::Postgres::Array::TimestampTZ[] }
11
+
12
+ it "returns {}" do
13
+ arr.to_s.should == '{}'
14
+ end
15
+ end
16
+
17
+ context "with an array of DateTimes" do
18
+ let(:arr) { RDO::Postgres::Array::TimestampTZ[
19
+ DateTime.new(2012, 9, 22, 5, 43, 2, "-07:00"),
20
+ DateTime.new(1983, 5, 3, 15, 0, 1, "+10:00")
21
+ ] }
22
+
23
+ it "formats the times in quotes" do
24
+ arr.to_s.should == %Q[{"#{DateTime.new(2012, 9, 22, 5, 43, 2, "-07:00")}","#{DateTime.new(1983, 5, 3, 15, 0, 1, "+10:00")}"}]
25
+ end
26
+ end
27
+
28
+ context "with an array containing nil" do
29
+ let(:arr) { RDO::Postgres::Array::TimestampTZ[nil, DateTime.new(1983, 5, 3, 0, 0, 1, "-07:00")] }
30
+
31
+ it "uses NULL" do
32
+ arr.to_s.should == %Q[{NULL,"#{DateTime.new(1983, 5, 3, 0, 0, 1, "-07:00")}"}]
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#to_a" do
38
+ let(:arr) { RDO::Postgres::Array::TimestampTZ[DateTime.new(2012, 9, 22, 0, 0, 0, "-07:00")] }
39
+
40
+ it "returns a core ruby Array" do
41
+ arr.to_a.class.should == ::Array
42
+ end
43
+ end
44
+
45
+ describe ".parse" do
46
+ let(:str) { '{}' }
47
+ let(:arr) { RDO::Postgres::Array::TimestampTZ.parse(str) }
48
+
49
+ it "returns a RDO::Postgres::Array::TimestampTZ" do
50
+ arr.should be_a_kind_of(RDO::Postgres::Array::TimestampTZ)
51
+ end
52
+
53
+ context "with an empty array string" do
54
+ let(:str) { '{}' }
55
+
56
+ it "returns an empty Array" do
57
+ arr.should be_empty
58
+ end
59
+ end
60
+
61
+ context "with an array of timestamps" do
62
+ let(:str) { '{"2012-09-22 05:34:01 -07:00","1983-05-03 13:59:09 +10:00"}' }
63
+
64
+ it "returns an Array of DateTimes" do
65
+ arr.to_a.should == [
66
+ DateTime.new(2012, 9, 22, 5, 34, 1, "-07:00"),
67
+ DateTime.new(1983, 5, 3, 13, 59, 9, "+10:00")
68
+ ]
69
+ end
70
+ end
71
+
72
+ context "with an array containing NULL" do
73
+ let(:str) { '{NULL,"1983-05-03 00:04:05 -07:00"}' }
74
+
75
+ it "uses nil as the value" do
76
+ arr.to_a.should == [nil, DateTime.new(1983, 5, 3, 0, 4, 5, "-07:00")]
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,122 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Postgres::Array do
4
+ it "is a kind of ::Array" do
5
+ RDO::Postgres::Array.new.should be_a_kind_of(::Array)
6
+ end
7
+
8
+ describe "#to_s" do
9
+ context "with an empty array" do
10
+ let(:arr) { RDO::Postgres::Array[] }
11
+
12
+ it "returns {}" do
13
+ arr.to_s.should == '{}'
14
+ end
15
+ end
16
+
17
+ context "with an array of Strings" do
18
+ let(:arr) { RDO::Postgres::Array["a", "b", "c"] }
19
+
20
+ it "wraps double quotes around the elements" do
21
+ arr.to_s.should == '{"a","b","c"}'
22
+ end
23
+
24
+ context "containing double quotes" do
25
+ let(:arr) { RDO::Postgres::Array["a", "b and \"c\""] }
26
+
27
+ it "escapes the quotes" do
28
+ arr.to_s.should == '{"a","b and \\"c\\""}'
29
+ end
30
+ end
31
+
32
+ context "containing backslashes" do
33
+ let(:arr) { RDO::Postgres::Array["a", "b and \\c"] }
34
+
35
+ it "escapes the backslashes" do
36
+ arr.to_s.should == '{"a","b and \\\\c"}'
37
+ end
38
+ end
39
+ end
40
+
41
+ context "with an array containing nil" do
42
+ let(:arr) { RDO::Postgres::Array[nil, nil, "c"] }
43
+
44
+ it "uses NULL" do
45
+ arr.to_s.should == '{NULL,NULL,"c"}'
46
+ end
47
+ end
48
+
49
+ context "with an array containing non-Strings" do
50
+ let(:arr) { RDO::Postgres::Array[42, 7] }
51
+
52
+ it "converts the objects to Strings" do
53
+ arr.to_s.should == '{"42","7"}'
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#to_a" do
59
+ let(:arr) { RDO::Postgres::Array[1, 2, 3] }
60
+
61
+ it "returns a core ruby Array" do
62
+ arr.to_a.class.should == ::Array
63
+ end
64
+ end
65
+
66
+ describe ".parse" do
67
+ let(:str) { '{}' }
68
+ let(:arr) { RDO::Postgres::Array.parse(str) }
69
+
70
+ it "returns a RDO::Postgres::Array" do
71
+ arr.should be_a_kind_of(RDO::Postgres::Array)
72
+ end
73
+
74
+ context "with an empty array string" do
75
+ let(:str) { '{}' }
76
+
77
+ it "returns an empty Array" do
78
+ arr.should be_empty
79
+ end
80
+ end
81
+
82
+ context "with an array of unquoted strings" do
83
+ let(:str) { '{a,b,c}' }
84
+
85
+ it "returns an Array of Strings" do
86
+ arr.to_a.should == ["a", "b", "c"]
87
+ end
88
+ end
89
+
90
+ context "with an array of quoted strings" do
91
+ let(:str) { '{"a b","c d","e f"}' }
92
+
93
+ it "returns an Array of Strings" do
94
+ arr.to_a.should == ["a b", "c d", "e f"]
95
+ end
96
+
97
+ context "containing double quotes" do
98
+ let(:str) { '{"a \\"b\\"","\\"c\\" d"}' }
99
+
100
+ it "returns an Array of Strings" do
101
+ arr.to_a.should == ['a "b"', '"c" d']
102
+ end
103
+ end
104
+
105
+ context "containing backslashes" do
106
+ let(:str) { '{"a \\\\b","\\\\c d"}' }
107
+
108
+ it "returns an Array of Strings" do
109
+ arr.to_a.should == ["a \\b", "\\c d"]
110
+ end
111
+ end
112
+ end
113
+
114
+ context "with an array containing NULL" do
115
+ let(:str) { '{NULL,NULL,"c"}' }
116
+
117
+ it "uses nil as the value" do
118
+ arr.to_a.should == [nil, nil, "c"]
119
+ end
120
+ end
121
+ end
122
+ end
@@ -688,6 +688,196 @@ describe RDO::Postgres::Driver, "bind parameter support" do
688
688
  end
689
689
  end
690
690
 
691
+ describe "Array param" do
692
+ context "against a text[] field" do
693
+ let(:table) { "CREATE TABLE test (id serial primary key, words text[])" }
694
+ let(:tuple) do
695
+ connection.execute("INSERT INTO test (words) VALUES (?) RETURNING *", ["apple", "orange"]).first
696
+ end
697
+
698
+ it "is inferred correctly" do
699
+ tuple.should == {id: 1, words: ["apple", "orange"]}
700
+ end
701
+
702
+ context "with embeddded quotes" do
703
+ let(:tuple) do
704
+ connection.execute("INSERT INTO test (words) VALUES (?) RETURNING *", ['"apple"']).first
705
+ end
706
+
707
+ it "is inferred correctly" do
708
+ tuple.should == {id: 1, words: ['"apple"']}
709
+ end
710
+ end
711
+
712
+ context "with embeddded backslashes" do
713
+ let(:tuple) do
714
+ connection.execute("INSERT INTO test (words) VALUES (?) RETURNING *", ['\\apple']).first
715
+ end
716
+
717
+ it "is inferred correctly" do
718
+ tuple.should == {id: 1, words: ['\\apple']}
719
+ end
720
+ end
721
+
722
+ context "with embedded nils" do
723
+ let(:tuple) do
724
+ connection.execute("INSERT INTO test (words) VALUES (?) RETURNING *", ["apple", nil]).first
725
+ end
726
+
727
+ it "is inferred correctly" do
728
+ tuple.should == {id: 1, words: ["apple", nil]}
729
+ end
730
+ end
731
+
732
+ context "with embedded new lines" do
733
+ let(:tuple) do
734
+ connection.execute("INSERT INTO test (words) VALUES (?) RETURNING *", ["apple\norange"]).first
735
+ end
736
+
737
+ it "is inferred correctly" do
738
+ tuple.should == {id: 1, words: ["apple\norange"]}
739
+ end
740
+ end
741
+ end
742
+
743
+ context "against an integer[] field" do
744
+ let(:table) { "CREATE TABLE test (id serial primary key, days integer[])" }
745
+ let(:tuple) do
746
+ connection.execute("INSERT INTO test (days) VALUES (?) RETURNING *", [4, 11]).first
747
+ end
748
+
749
+ it "is inferred correctly" do
750
+ tuple.should == {id: 1, days: [4, 11]}
751
+ end
752
+
753
+ context "with embedded nils" do
754
+ let(:tuple) do
755
+ connection.execute("INSERT INTO test (days) VALUES (?) RETURNING *", [4, nil]).first
756
+ end
757
+
758
+ it "is inferred correctly" do
759
+ tuple.should == {id: 1, days: [4, nil]}
760
+ end
761
+ end
762
+ end
763
+
764
+ context "against an numeric[] field" do
765
+ let(:table) { "CREATE TABLE test (id serial primary key, prices numeric[])" }
766
+ let(:tuple) do
767
+ connection.execute(
768
+ "INSERT INTO test (prices) VALUES (?) RETURNING *",
769
+ [BigDecimal("17.45"), BigDecimal("23.72")]).first
770
+ end
771
+
772
+ it "is inferred correctly" do
773
+ tuple.should == {id: 1, prices: [BigDecimal("17.45"), BigDecimal("23.72")]}
774
+ end
775
+ end
776
+
777
+ context "against an boolean[] field" do
778
+ let(:table) { "CREATE TABLE test (id serial primary key, truths boolean[])" }
779
+ let(:tuple) do
780
+ connection.execute(
781
+ "INSERT INTO test (truths) VALUES (?) RETURNING *",
782
+ [false, true]
783
+ ).first
784
+ end
785
+
786
+ it "is inferred correctly" do
787
+ tuple.should == {id: 1, truths: [false, true]}
788
+ end
789
+
790
+ context "with embedded nils" do
791
+ let(:tuple) do
792
+ connection.execute(
793
+ "INSERT INTO test (truths) VALUES (?) RETURNING *",
794
+ [false, nil]
795
+ ).first
796
+ end
797
+
798
+ it "is inferred correctly" do
799
+ tuple.should == {id: 1, truths: [false, nil]}
800
+ end
801
+ end
802
+ end
803
+
804
+ context "against an bytea[] field" do
805
+ let(:table) { "CREATE TABLE test (id serial primary key, salts bytea[])" }
806
+ let(:tuple) do
807
+ connection.execute(
808
+ "INSERT INTO test (salts) VALUES (?) RETURNING *",
809
+ ["\x00\x11", "\x22\x33"]
810
+ ).first
811
+ end
812
+
813
+ it "is inferred correctly" do
814
+ tuple.should == {id: 1, salts: ["\x00\x11", "\x22\x33"]}
815
+ end
816
+
817
+ context "with embedded nils" do
818
+ let(:tuple) do
819
+ connection.execute(
820
+ "INSERT INTO test (salts) VALUES (?) RETURNING *",
821
+ ["\x00\x11", nil]
822
+ ).first
823
+ end
824
+
825
+ it "is inferred correctly" do
826
+ tuple.should == {id: 1, salts: ["\x00\x11", nil]}
827
+ end
828
+ end
829
+ end
830
+
831
+ context "against an date[] field" do
832
+ let(:table) { "CREATE TABLE test (id serial primary key, days date[])" }
833
+ let(:tuple) do
834
+ connection.execute(
835
+ "INSERT INTO test (days) VALUES (?) RETURNING *",
836
+ [Date.new(2012, 9, 22), Date.new(1983, 5, 3)]).first
837
+ end
838
+
839
+ it "is inferred correctly" do
840
+ tuple.should == {id: 1, days: [Date.new(2012, 9, 22), Date.new(1983, 5, 3)]}
841
+ end
842
+ end
843
+
844
+ context "against a timestamp[] field" do
845
+ let(:table) { "CREATE TABLE test (id serial primary key, times timestamp[])" }
846
+ let(:tuple) do
847
+ connection.execute(
848
+ "INSERT INTO test (times) VALUES (?) RETURNING *",
849
+ [Time.new(2012, 9, 22, 6, 15, 34), Time.new(1983, 5, 3, 14, 56, 0)]).first
850
+ end
851
+
852
+ it "is inferred correctly" do
853
+ tuple.should == {id: 1, times: [
854
+ DateTime.new(2012, 9, 22, 6, 15, 34, DateTime.now.zone),
855
+ DateTime.new(1983, 5, 3, 14, 56, 0, DateTime.now.zone)
856
+ ]}
857
+ end
858
+ end
859
+
860
+ context "against a timestamptz[] field" do
861
+ let(:table) { "CREATE TABLE test (id serial primary key, times timestamptz[])" }
862
+ let(:tuple) do
863
+ connection.execute(
864
+ "INSERT INTO test (times) VALUES (?) RETURNING *",
865
+ [
866
+ DateTime.new(2012, 9, 22, 6, 15, 34, "-07:00"),
867
+ DateTime.new(1983, 5, 3, 14, 56, 0, "+10:00")
868
+ ]
869
+ ).first
870
+ end
871
+
872
+ it "is inferred correctly" do
873
+ tuple.should == {id: 1, times: [
874
+ DateTime.new(2012, 9, 22, 6, 15, 34, "-07:00"),
875
+ DateTime.new(1983, 5, 3, 14, 56, 0, "+10:00")
876
+ ]}
877
+ end
878
+ end
879
+ end
880
+
691
881
  describe "arbitrary Object param" do
692
882
  context "against a text field" do
693
883
  let(:value) { Object.new }
@@ -736,7 +926,7 @@ describe RDO::Postgres::Driver, "bind parameter support" do
736
926
  end
737
927
  end
738
928
 
739
- describe "when a bind marker is contained in a string literal" do
929
+ describe "bind markers in a string literals" do
740
930
  let(:table) do
741
931
  <<-SQL
742
932
  CREATE TABLE test (
@@ -270,4 +270,227 @@ describe RDO::Postgres::Driver, "type casting" do
270
270
  end
271
271
  end
272
272
  end
273
+
274
+ describe "text[] cast" do
275
+ let(:sql) { "SELECT ARRAY['a', 'b']::text[]" }
276
+
277
+ it "returns an Array of Strings" do
278
+ value.should == ["a", "b"]
279
+ end
280
+
281
+ context "including quotes" do
282
+ let(:sql) { %q{SELECT ARRAY['a "b"', '"c" d']::text[]} }
283
+
284
+ it "returns an Array of Strings" do
285
+ value.should == ['a "b"', '"c" d']
286
+ end
287
+ end
288
+
289
+ context "including backslashes" do
290
+ let(:sql) { %q{SELECT ARRAY['a \\b', '\\c d']::text[]} }
291
+
292
+ it "returns an Array of Strings" do
293
+ value.should == ['a \\b', '\\c d']
294
+ end
295
+ end
296
+
297
+ context "including NULLs" do
298
+ let(:sql) { "SELECT ARRAY[NULL, 'b']::text[]" }
299
+
300
+ it "returns an Array including nil" do
301
+ value.should == [nil, "b"]
302
+ end
303
+ end
304
+ end
305
+
306
+ describe "char[] cast" do
307
+ let(:sql) { "SELECT ARRAY['a', 'b']::char(1)[]" }
308
+
309
+ it "returns an Array of Strings" do
310
+ value.should == ["a", "b"]
311
+ end
312
+
313
+ context "including NULLs" do
314
+ let(:sql) { "SELECT ARRAY[NULL, 'b']::char(1)[]" }
315
+
316
+ it "returns an Array including nil" do
317
+ value.should == [nil, "b"]
318
+ end
319
+ end
320
+ end
321
+
322
+ describe "varchar[] cast" do
323
+ let(:sql) { "SELECT ARRAY['a', 'b']::varchar(16)[]" }
324
+
325
+ it "returns an Array of Strings" do
326
+ value.should == ["a", "b"]
327
+ end
328
+
329
+ context "including NULLs" do
330
+ let(:sql) { "SELECT ARRAY[NULL, 'b']::varchar(16)[]" }
331
+
332
+ it "returns an Array including nil" do
333
+ value.should == [nil, "b"]
334
+ end
335
+ end
336
+ end
337
+
338
+ describe "integer[] cast" do
339
+ let(:sql) { "SELECT ARRAY[42, 7]::integer[]" }
340
+
341
+ it "returns an Array of Fixnums" do
342
+ value.should == [42, 7]
343
+ end
344
+
345
+ context "using int2[]" do
346
+ let(:sql) { "SELECT ARRAY[42, 7]::int2[]" }
347
+
348
+ it "returns an Array of Fixnums" do
349
+ value.should == [42, 7]
350
+ end
351
+ end
352
+
353
+ context "using int4[]" do
354
+ let(:sql) { "SELECT ARRAY[42, 7]::int4[]" }
355
+
356
+ it "returns an Array of Fixnums" do
357
+ value.should == [42, 7]
358
+ end
359
+ end
360
+
361
+ context "using int8[]" do
362
+ let(:sql) { "SELECT ARRAY[42, 7]::int8[]" }
363
+
364
+ it "returns an Array of Fixnums" do
365
+ value.should == [42, 7]
366
+ end
367
+ end
368
+
369
+ context "including NULLs" do
370
+ let(:sql) { "SELECT ARRAY[NULL, 7]::integer[]" }
371
+
372
+ it "returns an Array including nil" do
373
+ value.should == [nil, 7]
374
+ end
375
+ end
376
+ end
377
+
378
+ describe "float[] cast" do
379
+ let(:sql) { "SELECT ARRAY[42.6, 7.9]::float[]" }
380
+
381
+ it "returns an Array of Floats" do
382
+ value.should == [42.6, 7.9]
383
+ end
384
+
385
+ context "using float4[]" do
386
+ let(:sql) { "SELECT ARRAY[42.6, 7.9]::float4[]" }
387
+
388
+ it "returns an Array of Floats" do
389
+ value.should == [42.6, 7.9]
390
+ end
391
+ end
392
+
393
+ context "including NULLs" do
394
+ let(:sql) { "SELECT ARRAY[NULL, 7.2]::float[]" }
395
+
396
+ it "returns an Array including nil" do
397
+ value.should == [nil, 7.2]
398
+ end
399
+ end
400
+ end
401
+
402
+ describe "numeric[] cast" do
403
+ let(:sql) { "SELECT ARRAY['123.45', '17.63']::numeric[]" }
404
+
405
+ it "returns an Array of BigDecimals" do
406
+ value.should == [BigDecimal("123.45"), BigDecimal("17.63")]
407
+ end
408
+
409
+ context "including NaN" do
410
+ let(:sql) { "SELECT ARRAY['NaN', '17.63']::numeric[]" }
411
+
412
+ it "returns an Array including NaN" do
413
+ value[0].should be_nan
414
+ value[1].should == BigDecimal("17.63")
415
+ end
416
+ end
417
+
418
+ context "including NULLs" do
419
+ let(:sql) { "SELECT ARRAY[NULL, '17.63']::numeric[]" }
420
+
421
+ it "returns an Array including nil" do
422
+ value.should == [nil, BigDecimal("17.63")]
423
+ end
424
+ end
425
+ end
426
+
427
+ describe "boolean[] cast" do
428
+ let(:sql) { "SELECT ARRAY['t', 'f']::boolean[]" }
429
+
430
+ it "returns an Array of Booleans" do
431
+ value.should == [true, false]
432
+ end
433
+
434
+ context "including NULLs" do
435
+ let(:sql) { "SELECT ARRAY[NULL, 't']::boolean[]" }
436
+
437
+ it "returns an Array including nil" do
438
+ value.should == [nil, true]
439
+ end
440
+ end
441
+ end
442
+
443
+ describe "bytea[] cast" do
444
+ let(:sql) { "SELECT ARRAY[decode('001122', 'hex'), decode('445566', 'hex')]::bytea[]" }
445
+
446
+ it "returns an Array of Strings" do
447
+ value.should == ["\x00\x11\x22", "\x44\x55\x66"]
448
+ end
449
+
450
+ context "including NULLs" do
451
+ let(:sql) { "SELECT ARRAY[NULL, decode('001122', 'hex')]::bytea[]" }
452
+
453
+ it "returns an Array including nil" do
454
+ value.should == [nil, "\x00\x11\x22"]
455
+ end
456
+ end
457
+ end
458
+
459
+ describe "date[] cast" do
460
+ let(:sql) { "SELECT ARRAY['2012-09-22', '1983-05-03']::date[]" }
461
+
462
+ it "returns an Array of Dates" do
463
+ value.should == [Date.new(2012, 9, 22), Date.new(1983, 5, 3)]
464
+ end
465
+
466
+ context "including NULLs" do
467
+ let(:sql) { "SELECT ARRAY[NULL, '1983-05-03']::date[]" }
468
+
469
+ it "returns an Array including nil" do
470
+ value.should == [nil, Date.new(1983, 5, 3)]
471
+ end
472
+ end
473
+ end
474
+
475
+ describe "timestamp[] cast" do
476
+ let(:sql) { "SELECT ARRAY['2012-09-22 06:57:01', '1983-05-03 13:42:03']::timestamp[]" }
477
+
478
+ it "returns an Array of DateTimes" do
479
+ value.should == [
480
+ DateTime.new(2012, 9, 22, 6, 57, 1, DateTime.now.zone),
481
+ DateTime.new(1983, 5, 3, 13, 42, 3, DateTime.now.zone)
482
+ ]
483
+ end
484
+ end
485
+
486
+ describe "timestamptz[] cast" do
487
+ let(:sql) { "SELECT ARRAY['2012-09-22 06:57:01 -07:00', '1983-05-03 13:42:03 +10:00']::timestamptz[]" }
488
+
489
+ it "returns an Array of DateTimes" do
490
+ value.should == [
491
+ DateTime.new(2012, 9, 22, 6, 57, 1, "-07:00"),
492
+ DateTime.new(1983, 5, 3, 13, 42, 3, "+10:00")
493
+ ]
494
+ end
495
+ end
273
496
  end