rdo-postgres 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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