sequel 3.37.0 → 3.38.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/CHANGELOG +56 -0
  2. data/README.rdoc +82 -58
  3. data/Rakefile +6 -5
  4. data/bin/sequel +1 -1
  5. data/doc/active_record.rdoc +67 -52
  6. data/doc/advanced_associations.rdoc +33 -48
  7. data/doc/association_basics.rdoc +41 -51
  8. data/doc/cheat_sheet.rdoc +21 -21
  9. data/doc/core_extensions.rdoc +374 -0
  10. data/doc/dataset_basics.rdoc +5 -5
  11. data/doc/dataset_filtering.rdoc +47 -43
  12. data/doc/mass_assignment.rdoc +1 -1
  13. data/doc/migration.rdoc +4 -5
  14. data/doc/model_hooks.rdoc +3 -3
  15. data/doc/object_model.rdoc +31 -25
  16. data/doc/opening_databases.rdoc +19 -5
  17. data/doc/prepared_statements.rdoc +2 -2
  18. data/doc/querying.rdoc +109 -52
  19. data/doc/reflection.rdoc +6 -6
  20. data/doc/release_notes/3.38.0.txt +234 -0
  21. data/doc/schema_modification.rdoc +22 -13
  22. data/doc/sharding.rdoc +8 -9
  23. data/doc/sql.rdoc +154 -112
  24. data/doc/testing.rdoc +47 -7
  25. data/doc/thread_safety.rdoc +1 -1
  26. data/doc/transactions.rdoc +1 -1
  27. data/doc/validations.rdoc +1 -1
  28. data/doc/virtual_rows.rdoc +29 -43
  29. data/lib/sequel/adapters/do/postgres.rb +1 -4
  30. data/lib/sequel/adapters/jdbc.rb +14 -3
  31. data/lib/sequel/adapters/jdbc/db2.rb +9 -0
  32. data/lib/sequel/adapters/jdbc/derby.rb +41 -4
  33. data/lib/sequel/adapters/jdbc/jtds.rb +11 -0
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -6
  35. data/lib/sequel/adapters/mock.rb +10 -4
  36. data/lib/sequel/adapters/postgres.rb +1 -28
  37. data/lib/sequel/adapters/shared/mssql.rb +23 -13
  38. data/lib/sequel/adapters/shared/postgres.rb +46 -0
  39. data/lib/sequel/adapters/swift.rb +21 -13
  40. data/lib/sequel/adapters/swift/mysql.rb +1 -0
  41. data/lib/sequel/adapters/swift/postgres.rb +4 -5
  42. data/lib/sequel/adapters/swift/sqlite.rb +2 -1
  43. data/lib/sequel/adapters/tinytds.rb +14 -2
  44. data/lib/sequel/adapters/utils/pg_types.rb +5 -0
  45. data/lib/sequel/core.rb +29 -17
  46. data/lib/sequel/database/query.rb +1 -1
  47. data/lib/sequel/database/schema_generator.rb +3 -0
  48. data/lib/sequel/dataset/actions.rb +5 -6
  49. data/lib/sequel/dataset/query.rb +7 -7
  50. data/lib/sequel/dataset/sql.rb +5 -18
  51. data/lib/sequel/extensions/core_extensions.rb +8 -12
  52. data/lib/sequel/extensions/pg_array.rb +59 -33
  53. data/lib/sequel/extensions/pg_array_ops.rb +32 -4
  54. data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -1
  55. data/lib/sequel/extensions/pg_hstore.rb +32 -17
  56. data/lib/sequel/extensions/pg_hstore_ops.rb +32 -3
  57. data/lib/sequel/extensions/pg_inet.rb +1 -2
  58. data/lib/sequel/extensions/pg_interval.rb +0 -1
  59. data/lib/sequel/extensions/pg_json.rb +41 -23
  60. data/lib/sequel/extensions/pg_range.rb +36 -11
  61. data/lib/sequel/extensions/pg_range_ops.rb +32 -4
  62. data/lib/sequel/extensions/pg_row.rb +572 -0
  63. data/lib/sequel/extensions/pg_row_ops.rb +164 -0
  64. data/lib/sequel/extensions/query.rb +3 -3
  65. data/lib/sequel/extensions/schema_dumper.rb +7 -8
  66. data/lib/sequel/extensions/select_remove.rb +1 -1
  67. data/lib/sequel/model/base.rb +1 -0
  68. data/lib/sequel/no_core_ext.rb +1 -1
  69. data/lib/sequel/plugins/pg_row.rb +121 -0
  70. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  71. data/lib/sequel/plugins/validation_helpers.rb +31 -0
  72. data/lib/sequel/sql.rb +64 -44
  73. data/lib/sequel/version.rb +1 -1
  74. data/spec/adapters/mssql_spec.rb +37 -12
  75. data/spec/adapters/mysql_spec.rb +39 -75
  76. data/spec/adapters/oracle_spec.rb +11 -11
  77. data/spec/adapters/postgres_spec.rb +414 -237
  78. data/spec/adapters/spec_helper.rb +1 -1
  79. data/spec/adapters/sqlite_spec.rb +14 -14
  80. data/spec/core/database_spec.rb +6 -6
  81. data/spec/core/dataset_spec.rb +169 -205
  82. data/spec/core/expression_filters_spec.rb +182 -295
  83. data/spec/core/object_graph_spec.rb +6 -6
  84. data/spec/core/schema_spec.rb +14 -14
  85. data/spec/core/spec_helper.rb +1 -0
  86. data/spec/{extensions/core_extensions_spec.rb → core_extensions_spec.rb} +208 -14
  87. data/spec/extensions/columns_introspection_spec.rb +5 -5
  88. data/spec/extensions/hook_class_methods_spec.rb +28 -36
  89. data/spec/extensions/many_through_many_spec.rb +4 -4
  90. data/spec/extensions/pg_array_ops_spec.rb +15 -7
  91. data/spec/extensions/pg_array_spec.rb +81 -48
  92. data/spec/extensions/pg_auto_parameterize_spec.rb +2 -2
  93. data/spec/extensions/pg_hstore_ops_spec.rb +13 -9
  94. data/spec/extensions/pg_hstore_spec.rb +66 -65
  95. data/spec/extensions/pg_inet_spec.rb +2 -4
  96. data/spec/extensions/pg_interval_spec.rb +2 -3
  97. data/spec/extensions/pg_json_spec.rb +20 -18
  98. data/spec/extensions/pg_range_ops_spec.rb +11 -4
  99. data/spec/extensions/pg_range_spec.rb +30 -7
  100. data/spec/extensions/pg_row_ops_spec.rb +48 -0
  101. data/spec/extensions/pg_row_plugin_spec.rb +45 -0
  102. data/spec/extensions/pg_row_spec.rb +323 -0
  103. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  104. data/spec/extensions/query_literals_spec.rb +11 -11
  105. data/spec/extensions/query_spec.rb +3 -3
  106. data/spec/extensions/schema_dumper_spec.rb +20 -4
  107. data/spec/extensions/schema_spec.rb +18 -41
  108. data/spec/extensions/select_remove_spec.rb +4 -4
  109. data/spec/extensions/spec_helper.rb +4 -8
  110. data/spec/extensions/to_dot_spec.rb +5 -5
  111. data/spec/extensions/validation_class_methods_spec.rb +28 -16
  112. data/spec/integration/associations_test.rb +20 -20
  113. data/spec/integration/dataset_test.rb +98 -98
  114. data/spec/integration/eager_loader_test.rb +13 -27
  115. data/spec/integration/plugin_test.rb +5 -5
  116. data/spec/integration/prepared_statement_test.rb +22 -13
  117. data/spec/integration/schema_test.rb +28 -18
  118. data/spec/integration/spec_helper.rb +1 -1
  119. data/spec/integration/timezone_test.rb +2 -2
  120. data/spec/integration/type_test.rb +15 -6
  121. data/spec/model/association_reflection_spec.rb +1 -1
  122. data/spec/model/associations_spec.rb +4 -4
  123. data/spec/model/base_spec.rb +5 -5
  124. data/spec/model/eager_loading_spec.rb +15 -15
  125. data/spec/model/model_spec.rb +32 -32
  126. data/spec/model/record_spec.rb +16 -0
  127. data/spec/model/spec_helper.rb +2 -6
  128. data/spec/model/validations_spec.rb +1 -1
  129. metadata +16 -4
@@ -244,7 +244,7 @@ describe Sequel::Model, "many_through_many" do
244
244
  end
245
245
 
246
246
  it "should support an array for the select option" do
247
- @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[:tags.*, :albums__name]
247
+ @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), :albums__name]
248
248
  n = @c1.load(:id => 1234)
249
249
  n.tags_dataset.sql.should == 'SELECT tags.*, albums.name FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))'
250
250
  n.tags.should == [@c2.load(:id=>1)]
@@ -914,12 +914,12 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
914
914
  end
915
915
 
916
916
  it "should respect the association's :graph_block option" do
917
- @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_block=>proc{|ja,lja,js| {:active.qualify(ja)=>true}}
917
+ @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}
918
918
  @c1.eager_graph(:tags).sql.should == 'SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON ((tags.id = albums_tags.tag_id) AND (tags.active IS TRUE))'
919
919
  end
920
920
 
921
921
  it "should respect the association's :block option on through" do
922
- @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :block=>proc{|ja,lja,js| {:active.qualify(ja)=>true}}}, [:albums_tags, :album_id, :tag_id]]
922
+ @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}}, [:albums_tags, :album_id, :tag_id]]
923
923
  @c1.eager_graph(:tags).sql.should == 'SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON ((albums.id = albums_artists.album_id) AND (albums.active IS TRUE)) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)'
924
924
  end
925
925
 
@@ -943,7 +943,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
943
943
  end
944
944
 
945
945
  it "should only qualify unqualified symbols, identifiers, or ordered versions in association's :order" do
946
- @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[:blah__id.identifier, :blah__id.identifier.desc, :blah__id.desc, :blah__id, :album_id, :album_id.desc, 1, 'RANDOM()'.lit, :a.qualify(:b)]
946
+ @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(:blah__id), :blah__id, :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
947
947
  @c1.order(:artists__blah2, :artists__blah3).eager_graph(:tags).sql.should == 'SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tags.blah__id, tags.blah__id DESC, blah.id DESC, blah.id, tags.album_id, tags.album_id DESC, 1, RANDOM(), b.a'
948
948
  end
949
949
 
@@ -3,7 +3,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe "Sequel::Postgres::ArrayOp" do
4
4
  before do
5
5
  @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
6
- @a = :a.pg_array
6
+ @a = Sequel.pg_array_op(:a)
7
7
  end
8
8
 
9
9
  it "should support the standard mathematical operators" do
@@ -76,20 +76,28 @@ describe "Sequel::Postgres::ArrayOp" do
76
76
  @a.pg_array.should equal(@a)
77
77
  end
78
78
 
79
+ it "Sequel.pg_array_op should return arg for ArrayOp" do
80
+ Sequel.pg_array_op(@a).should equal(@a)
81
+ end
82
+
79
83
  it "should be able to turn expressions into array ops using pg_array" do
80
- @db.literal(:a.qualify(:b).pg_array.push(3)).should == "(b.a || 3)"
81
- @db.literal(:a.sql_function(:b).pg_array.push(3)).should == "(a(b) || 3)"
84
+ @db.literal(Sequel.qualify(:b, :a).pg_array.push(3)).should == "(b.a || 3)"
85
+ @db.literal(Sequel.function(:a, :b).pg_array.push(3)).should == "(a(b) || 3)"
82
86
  end
83
87
 
84
88
  it "should be able to turn literal strings into array ops using pg_array" do
85
- @db.literal('a'.lit.pg_array.unnest).should == "unnest(a)"
89
+ @db.literal(Sequel.lit('a').pg_array.unnest).should == "unnest(a)"
90
+ end
91
+
92
+ it "should be able to turn symbols into array ops using Sequel.pg_array_op" do
93
+ @db.literal(Sequel.pg_array_op(:a).unnest).should == "unnest(a)"
86
94
  end
87
95
 
88
- it "should be able to turn symbols into array ops using pg_array" do
89
- @db.literal(:a.pg_array.unnest).should == "unnest(a)"
96
+ it "should be able to turn symbols into array ops using Sequel.pg_array" do
97
+ @db.literal(Sequel.pg_array(:a).unnest).should == "unnest(a)"
90
98
  end
91
99
 
92
100
  it "should allow transforming PGArray instances into ArrayOp instances" do
93
- @db.literal([1,2].pg_array.op.push(3)).should == "(ARRAY[1,2] || 3)"
101
+ @db.literal(Sequel.pg_array([1,2]).op.push(3)).should == "(ARRAY[1,2] || 3)"
94
102
  end
95
103
  end
@@ -1,17 +1,23 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "pg_array extension" do
4
+ before(:all) do
5
+ @pg_types = Sequel::Postgres::PG_TYPES.dup
6
+ end
7
+ after(:all) do
8
+ Sequel::Postgres::PG_TYPES.replace(@pg_types)
9
+ end
10
+
4
11
  before do
5
12
  @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
6
- @db.extend(Module.new{def bound_variable_arg(arg, conn) arg end; def get_conversion_procs(conn) {} end})
7
13
  @db.extend_datasets(Module.new{def supports_timestamp_timezones?; false; end; def supports_timestamp_usecs?; false; end})
8
14
  @db.extension(:pg_array)
9
15
  @m = Sequel::Postgres
10
- @convertor = @m::PG_TYPES
16
+ @converter = @m::PG_TYPES
11
17
  end
12
18
 
13
19
  it "should parse single dimensional text arrays" do
14
- c = @convertor[1009]
20
+ c = @converter[1009]
15
21
  c.call("{a}").to_a.first.should be_a_kind_of(String)
16
22
  c.call("{}").to_a.should == []
17
23
  c.call("{a}").to_a.should == ['a']
@@ -20,7 +26,7 @@ describe "pg_array extension" do
20
26
  end
21
27
 
22
28
  it "should parse multi-dimensional text arrays" do
23
- c = @convertor[1009]
29
+ c = @converter[1009]
24
30
  c.call("{{}}").to_a.should == [[]]
25
31
  c.call("{{a},{b}}").to_a.should == [['a'], ['b']]
26
32
  c.call('{{"a b"},{c}}').to_a.should == [['a b'], ['c']]
@@ -29,12 +35,12 @@ describe "pg_array extension" do
29
35
  end
30
36
 
31
37
  it "should parse text arrays with embedded deliminaters" do
32
- c = @convertor[1009]
38
+ c = @converter[1009]
33
39
  c.call('{{"{},","\\",\\,\\\\\\"\\""}}').to_a.should == [['{},', '",,\\""']]
34
40
  end
35
41
 
36
42
  it "should parse single dimensional integer arrays" do
37
- c = @convertor[1007]
43
+ c = @converter[1007]
38
44
  c.call("{1}").to_a.first.should be_a_kind_of(Integer)
39
45
  c.call("{}").to_a.should == []
40
46
  c.call("{1}").to_a.should == [1]
@@ -43,7 +49,7 @@ describe "pg_array extension" do
43
49
  end
44
50
 
45
51
  it "should parse multiple dimensional integer arrays" do
46
- c = @convertor[1007]
52
+ c = @converter[1007]
47
53
  c.call("{{}}").to_a.should == [[]]
48
54
  c.call("{{1}}").to_a.should == [[1]]
49
55
  c.call('{{2},{3}}').to_a.should == [[2], [3]]
@@ -51,7 +57,7 @@ describe "pg_array extension" do
51
57
  end
52
58
 
53
59
  it "should parse single dimensional float arrays" do
54
- c = @convertor[1022]
60
+ c = @converter[1022]
55
61
  c.call("{}").to_a.should == []
56
62
  c.call("{1.5}").to_a.should == [1.5]
57
63
  c.call('{2.5,3.5}').to_a.should == [2.5, 3.5]
@@ -59,7 +65,7 @@ describe "pg_array extension" do
59
65
  end
60
66
 
61
67
  it "should parse multiple dimensional float arrays" do
62
- c = @convertor[1022]
68
+ c = @converter[1022]
63
69
  c.call("{{}}").to_a.should == [[]]
64
70
  c.call("{{1.5}}").to_a.should == [[1.5]]
65
71
  c.call('{{2.5},{3.5}}').to_a.should == [[2.5], [3.5]]
@@ -67,14 +73,14 @@ describe "pg_array extension" do
67
73
  end
68
74
 
69
75
  it "should parse integers in float arrays as floats" do
70
- c = @convertor[1022]
76
+ c = @converter[1022]
71
77
  c.call("{1}").to_a.first.should be_a_kind_of(Float)
72
78
  c.call("{1}").to_a.should == [1.0]
73
79
  c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.should == [[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]
74
80
  end
75
81
 
76
82
  it "should parse single dimensional decimal arrays" do
77
- c = @convertor[1231]
83
+ c = @converter[1231]
78
84
  c.call("{}").to_a.should == []
79
85
  c.call("{1.5}").to_a.should == [BigDecimal.new('1.5')]
80
86
  c.call('{2.5,3.5}').to_a.should == [BigDecimal.new('2.5'), BigDecimal.new('3.5')]
@@ -82,7 +88,7 @@ describe "pg_array extension" do
82
88
  end
83
89
 
84
90
  it "should parse multiple dimensional decimal arrays" do
85
- c = @convertor[1231]
91
+ c = @converter[1231]
86
92
  c.call("{{}}").to_a.should == [[]]
87
93
  c.call("{{1.5}}").to_a.should == [[BigDecimal.new('1.5')]]
88
94
  c.call('{{2.5},{3.5}}').to_a.should == [[BigDecimal.new('2.5')], [BigDecimal.new('3.5')]]
@@ -90,20 +96,20 @@ describe "pg_array extension" do
90
96
  end
91
97
 
92
98
  it "should parse decimal values with arbitrary precision" do
93
- c = @convertor[1231]
99
+ c = @converter[1231]
94
100
  c.call("{1.000000000000000000005}").to_a.should == [BigDecimal.new('1.000000000000000000005')]
95
101
  c.call("{{1.000000000000000000005,2.000000000000000000005},{3.000000000000000000005,4.000000000000000000005}}").to_a.should == [[BigDecimal.new('1.000000000000000000005'), BigDecimal.new('2.000000000000000000005')], [BigDecimal.new('3.000000000000000000005'), BigDecimal.new('4.000000000000000000005')]]
96
102
  end
97
103
 
98
104
  it "should parse integers in decimal arrays as BigDecimals" do
99
- c = @convertor[1231]
105
+ c = @converter[1231]
100
106
  c.call("{1}").to_a.first.should be_a_kind_of(BigDecimal)
101
107
  c.call("{1}").to_a.should == [BigDecimal.new('1')]
102
108
  c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.should == [[[BigDecimal.new('1'), BigDecimal.new('2')], [BigDecimal.new('3'), BigDecimal.new('4')]], [[BigDecimal.new('5'), BigDecimal.new('6')], [BigDecimal.new('7'), BigDecimal.new('8')]]]
103
109
  end
104
110
 
105
111
  it "should parse arrays with NULL values" do
106
- @convertor.values_at(1007, 1009, 1022, 1231).each do |c|
112
+ @converter.values_at(1007, 1009, 1022, 1231).each do |c|
107
113
  c.call("{NULL}").should == [nil]
108
114
  c.call("{NULL,NULL}").should == [nil,nil]
109
115
  c.call("{{NULL,NULL},{NULL,NULL}}").should == [[nil,nil],[nil,nil]]
@@ -111,7 +117,7 @@ describe "pg_array extension" do
111
117
  end
112
118
 
113
119
  it 'should parse arrays with "NULL" values' do
114
- c = @convertor[1009]
120
+ c = @converter[1009]
115
121
  c.call('{NULL,"NULL",NULL}').to_a.should == [nil, "NULL", nil]
116
122
  c.call('{NULLA,"NULL",NULL}').to_a.should == ["NULLA", "NULL", nil]
117
123
  end
@@ -146,15 +152,29 @@ describe "pg_array extension" do
146
152
  @db.literal(@m::PGArray.new([nil, "{},[]'\""], :"varchar(255)")).should == "ARRAY[NULL,'{},[]''\"']::varchar(255)[]"
147
153
  end
148
154
 
149
- it "should have Array#pg_array method for easy PGArray creation" do
150
- @db.literal([1].pg_array).should == 'ARRAY[1]'
151
- @db.literal([1, 2].pg_array(:int4)).should == 'ARRAY[1,2]::int4[]'
152
- @db.literal([[[1], [2]], [[3], [4]]].pg_array(:real)).should == 'ARRAY[[[1],[2]],[[3],[4]]]::real[]'
155
+ it "should have Sequel.pg_array method for easy PGArray creation" do
156
+ @db.literal(Sequel.pg_array([1])).should == 'ARRAY[1]'
157
+ @db.literal(Sequel.pg_array([1, 2], :int4)).should == 'ARRAY[1,2]::int4[]'
158
+ @db.literal(Sequel.pg_array([[[1], [2]], [[3], [4]]], :real)).should == 'ARRAY[[[1],[2]],[[3],[4]]]::real[]'
159
+ end
160
+
161
+ it "should have Sequel.pg_array return existing PGArrays as-is" do
162
+ a = Sequel.pg_array([1])
163
+ Sequel.pg_array(a).should equal(a)
164
+ end
165
+
166
+ it "should have Sequel.pg_array create a new PGArrays if type of existing does not match" do
167
+ a = Sequel.pg_array([1], :int4)
168
+ b = Sequel.pg_array(a, :int8)
169
+ a.should == b
170
+ a.should_not equal(b)
171
+ a.array_type.should == :int4
172
+ b.array_type.should == :int8
153
173
  end
154
174
 
155
175
  it "should support using arrays as bound variables" do
156
176
  @db.bound_variable_arg(1, nil).should == 1
157
- @db.bound_variable_arg([1,2].pg_array, nil).should == '{1,2}'
177
+ @db.bound_variable_arg(Sequel.pg_array([1,2]), nil).should == '{1,2}'
158
178
  @db.bound_variable_arg([1,2], nil).should == '{1,2}'
159
179
  @db.bound_variable_arg([[1,2]], nil).should == '{{1,2}}'
160
180
  @db.bound_variable_arg([1.0,2.0], nil).should == '{1.0,2.0}'
@@ -169,45 +189,44 @@ describe "pg_array extension" do
169
189
 
170
190
  it "should support typecasting of the various array types" do
171
191
  {
172
- :integer=>{:class=>Integer, :convert=>['1', '1', 1, '1']},
173
- :float=>{:db_type=>'double precision', :class=>Float, :convert=>['1.1', '1.1', 1.1, '1.1']},
174
- :decimal=>{:db_type=>'numeric', :class=>BigDecimal, :convert=>['1.00000000000000000000000001', '1.00000000000000000000000001', BigDecimal.new('1.00000000000000000000000001'), '1.00000000000000000000000001']},
175
- :string=>{:db_type=>'text', :class=>String, :convert=>['1', 1, '1', "'1'"]},
176
- :bigint=>{:class=>Integer, :convert=>['1', '1', 1, '1']},
177
- :boolean=>{:class=>TrueClass, :convert=>['t', 't', true, 'true']},
178
- :blob=>{:db_type=>'bytea', :class=>Sequel::SQL::Blob, :convert=>['1', '1', '1', "'1'"]},
179
- :date=>{:class=>Date, :convert=>['2011-10-12', '2011-10-12', Date.new(2011, 10, 12), "'2011-10-12'"]},
180
- :time=>{:db_type=>'time without time zone', :class=>Sequel::SQLTime, :convert=>['01:02:03', '01:02:03', Sequel::SQLTime.create(1, 2, 3), "'01:02:03'"]},
181
- :datetime=>{:db_type=>'timestamp without time zone', :class=>Time, :convert=>['2011-10-12 01:02:03', '2011-10-12 01:02:03', Time.local(2011, 10, 12, 1, 2, 3), "'2011-10-12 01:02:03'"]},
182
- :time_timezone=>{:db_type=>'time with time zone', :class=>Sequel::SQLTime, :convert=>['01:02:03', '01:02:03', Sequel::SQLTime.create(1, 2, 3), "'01:02:03'"]},
183
- :datetime_timezone=>{:db_type=>'timestamp with time zone', :class=>Time, :convert=>['2011-10-12 01:02:03', '2011-10-12 01:02:03', Time.local(2011, 10, 12, 1, 2, 3), "'2011-10-12 01:02:03'"]},
192
+ :integer=>{:class=>Integer, :convert=>['1', 1, '1']},
193
+ :float=>{:db_type=>'double precision', :class=>Float, :convert=>['1.1', 1.1, '1.1']},
194
+ :decimal=>{:db_type=>'numeric', :class=>BigDecimal, :convert=>['1.00000000000000000000000001', BigDecimal.new('1.00000000000000000000000001'), '1.00000000000000000000000001']},
195
+ :string=>{:db_type=>'text', :class=>String, :convert=>[1, '1', "'1'"]},
196
+ :bigint=>{:class=>Integer, :convert=>['1', 1, '1']},
197
+ :boolean=>{:class=>TrueClass, :convert=>['t', true, 'true']},
198
+ :blob=>{:db_type=>'bytea', :class=>Sequel::SQL::Blob, :convert=>['1', '1', "'1'"]},
199
+ :date=>{:class=>Date, :convert=>['2011-10-12', Date.new(2011, 10, 12), "'2011-10-12'"]},
200
+ :time=>{:db_type=>'time without time zone', :class=>Sequel::SQLTime, :convert=>['01:02:03', Sequel::SQLTime.create(1, 2, 3), "'01:02:03'"]},
201
+ :datetime=>{:db_type=>'timestamp without time zone', :class=>Time, :convert=>['2011-10-12 01:02:03', Time.local(2011, 10, 12, 1, 2, 3), "'2011-10-12 01:02:03'"]},
202
+ :time_timezone=>{:db_type=>'time with time zone', :class=>Sequel::SQLTime, :convert=>['01:02:03', Sequel::SQLTime.create(1, 2, 3), "'01:02:03'"]},
203
+ :datetime_timezone=>{:db_type=>'timestamp with time zone', :class=>Time, :convert=>['2011-10-12 01:02:03', Time.local(2011, 10, 12, 1, 2, 3), "'2011-10-12 01:02:03'"]},
184
204
  }.each do |type, h|
185
205
  meth = :"#{type}_array"
186
206
  db_type = h[:db_type]||type
187
207
  klass = h[:class]
188
- text_in, array_in, value, output = h[:convert]
208
+ array_in, value, output = h[:convert]
189
209
 
190
- ["{#{text_in}}", [array_in]].each do |input|
210
+ [[array_in]].each do |input|
191
211
  v = @db.typecast_value(meth, input)
192
212
  v.should == [value]
193
213
  v.first.should be_a_kind_of(klass)
194
214
  v.array_type.should_not be_nil
195
- @db.typecast_value(meth, [value].pg_array).should == v
215
+ @db.typecast_value(meth, Sequel.pg_array([value])).should == v
196
216
  @db.typecast_value(meth, v).should equal(v)
197
217
  end
198
218
 
199
- ["{{#{text_in}}}", [[array_in]]].each do |input|
219
+ [[[array_in]]].each do |input|
200
220
  v = @db.typecast_value(meth, input)
201
221
  v.should == [[value]]
202
222
  v.first.first.should be_a_kind_of(klass)
203
223
  v.array_type.should_not be_nil
204
- @db.typecast_value(meth, [[value]].pg_array).should == v
224
+ @db.typecast_value(meth, Sequel.pg_array([[value]])).should == v
205
225
  @db.typecast_value(meth, v).should equal(v)
206
226
  end
207
227
 
208
228
  @db.literal(@db.typecast_value(meth, [array_in])).should == "ARRAY[#{output}]::#{db_type}[]"
209
- @db.typecast_value(meth, '{}').should == []
210
- @db.literal(@db.typecast_value(meth, '{}')).should == "ARRAY[]::#{db_type}[]"
229
+ @db.literal(@db.typecast_value(meth, [])).should == "ARRAY[]::#{db_type}[]"
211
230
  end
212
231
  proc{@db.typecast_value(:integer_array, {})}.should raise_error(Sequel::InvalidValue)
213
232
  end
@@ -227,18 +246,32 @@ describe "pg_array extension" do
227
246
  end
228
247
 
229
248
  it "should support using a block as a custom conversion proc given as block" do
230
- Sequel::Postgres::PGArray.register('foo'){|s| (s*2).to_i}
231
- @db.typecast_value(:foo_array, '{1}').should == [11]
249
+ Sequel::Postgres::PGArray.register('foo', :oid=>1234){|s| (s*2).to_i}
250
+ @converter[1234].call('{1}').should == [11]
232
251
  end
233
252
 
234
253
  it "should support using a block as a custom conversion proc given as :converter option" do
235
- Sequel::Postgres::PGArray.register('foo', :converter=>proc{|s| (s*2).to_i})
236
- @db.typecast_value(:foo_array, '{1}').should == [11]
254
+ Sequel::Postgres::PGArray.register('foo', :oid=>1234, :converter=>proc{|s| (s*2).to_i})
255
+ @converter[1234].call('{1}').should == [11]
237
256
  end
238
257
 
239
258
  it "should support using an existing scaler conversion proc via the :scalar_oid option" do
240
- Sequel::Postgres::PGArray.register('foo', :scalar_oid=>16)
241
- @db.typecast_value(:foo_array, '{"t"}').should == [true]
259
+ Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>16)
260
+ @converter[1234].call('{t}').should == [true]
261
+ end
262
+
263
+ it "should support using a given conversion procs hash via the :type_procs option" do
264
+ h = {16=>proc{|s| "!#{s}"}}
265
+ Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>16, :type_procs=>h)
266
+ h[1234].call('{t}').should == ["!t"]
267
+ end
268
+
269
+ it "should support adding methods to the given module via the :typecast_methods_module option" do
270
+ m = Module.new
271
+ Sequel::Postgres::PGArray.register('foo15', :scalar_typecast=>:boolean, :typecast_methods_module=>m)
272
+ @db.typecast_value(:foo15_array, ['t']).should == ['t']
273
+ @db.extend(m)
274
+ @db.typecast_value(:foo15_array, ['t']).should == [true]
242
275
  end
243
276
 
244
277
  it "should raise an error if using :scalar_oid option with unexisting scalar conversion proc" do
@@ -263,7 +296,7 @@ describe "pg_array extension" do
263
296
  Sequel::Postgres::PG_TYPES[2].should be_a_kind_of(Sequel::Postgres::PGArray::JSONCreator)
264
297
  end
265
298
 
266
- it "should support registering convertors with :parser=>:json option" do
299
+ it "should support registering converters with :parser=>:json option" do
267
300
  Sequel::Postgres::PGArray.register('foo', :oid=>4, :parser=>:json){|s| s * 2}
268
301
  Sequel::Postgres::PG_TYPES[4].call('{{1, 2}, {3, 4}}').should == [[2, 4], [6, 8]]
269
302
  end
@@ -280,7 +313,7 @@ describe "pg_array extension" do
280
313
  end
281
314
 
282
315
  it "should set appropriate timestamp conversion procs when getting conversion procs" do
283
- procs = @db.send(:get_conversion_procs, nil)
316
+ procs = @db.conversion_procs
284
317
  procs[1185].call('{"2011-10-20 11:12:13"}').should == [Time.local(2011, 10, 20, 11, 12, 13)]
285
318
  procs[1115].call('{"2011-10-20 11:12:13"}').should == [Time.local(2011, 10, 20, 11, 12, 13)]
286
319
  end
@@ -21,8 +21,8 @@ describe "pg_auto_parameterize extension" do
21
21
  pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1::double precision)', 1.1)
22
22
  pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1::numeric)', BigDecimal.new('1.01'))
23
23
  pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1)', "a")
24
- pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1::bytea)', "a\0b".to_sequel_blob)
25
- pr.call(@db[:table], 'SELECT * FROM table WHERE (a = 1)', '1'.lit, :nil)
24
+ pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1::bytea)', Sequel.blob("a\0b"))
25
+ pr.call(@db[:table], 'SELECT * FROM table WHERE (a = 1)', Sequel.lit('1'), :nil)
26
26
  pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1::time)', Sequel::SQLTime.create(1, 2, 3, 500000))
27
27
  pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1::date)', Date.today)
28
28
  pr.call(@db[:table], 'SELECT * FROM table WHERE (a = $1::timestamp)', DateTime.new(2012, 1, 2, 3, 4, 5))
@@ -3,7 +3,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe "Sequel::Postgres::HStoreOp" do
4
4
  before do
5
5
  @ds = Sequel.connect('mock://postgres', :quote_identifiers=>false).dataset
6
- @h = :h.hstore
6
+ @h = Sequel.hstore_op(:h)
7
7
  end
8
8
 
9
9
  it "#- should use the - operator" do
@@ -117,20 +117,24 @@ describe "Sequel::Postgres::HStoreOp" do
117
117
  @ds.literal(@h.avals).should == "avals(h)"
118
118
  end
119
119
 
120
- it "should be able to turn expressions into hstore ops using hstore" do
121
- @ds.literal(:a.qualify(:b).hstore['a']).should == "(b.a -> 'a')"
122
- @ds.literal(:a.sql_function(:b).hstore['a']).should == "(a(b) -> 'a')"
120
+ it "should have Sequel.hstore_op return HStoreOp instances as-is" do
121
+ Sequel.hstore_op(@h).should equal(@h)
123
122
  end
124
123
 
125
- it "should be able to turn literal strings into hstore ops using hstore" do
126
- @ds.literal('a'.lit.hstore['a']).should == "(a -> 'a')"
124
+ it "should have Sequel.hstore return HStoreOp instances" do
125
+ Sequel.hstore(:h).should == @h
126
+ end
127
+
128
+ it "should be able to turn expressions into hstore ops using hstore" do
129
+ @ds.literal(Sequel.qualify(:b, :a).hstore['a']).should == "(b.a -> 'a')"
130
+ @ds.literal(Sequel.function(:a, :b).hstore['a']).should == "(a(b) -> 'a')"
127
131
  end
128
132
 
129
- it "should be able to turn symbols into hstore ops using hstore" do
130
- @ds.literal(:a.hstore['a']).should == "(a -> 'a')"
133
+ it "should be able to turn literal strings into hstore ops using hstore" do
134
+ @ds.literal(Sequel.lit('a').hstore['a']).should == "(a -> 'a')"
131
135
  end
132
136
 
133
137
  it "should allow transforming HStore instances into HStoreOp instances" do
134
- @ds.literal({'a'=>'b'}.hstore.op['a']).should == "('\"a\"=>\"b\"'::hstore -> 'a')"
138
+ @ds.literal(Sequel.hstore('a'=>'b').op['a']).should == "('\"a\"=>\"b\"'::hstore -> 'a')"
135
139
  end
136
140
  end
@@ -3,7 +3,6 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe "pg_hstore extension" do
4
4
  before do
5
5
  @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
6
- @db.extend(Module.new{def bound_variable_arg(arg, conn) arg end})
7
6
  @m = Sequel::Postgres
8
7
  @c = @m::HStore
9
8
  @db.extension :pg_hstore
@@ -25,28 +24,33 @@ describe "pg_hstore extension" do
25
24
  end
26
25
 
27
26
  it "should literalize HStores to strings correctly" do
28
- @db.literal({}.hstore).should == '\'\'::hstore'
29
- @db.literal({"a"=>"b"}.hstore).should == '\'"a"=>"b"\'::hstore'
30
- @db.literal({"c"=>nil}.hstore).should == '\'"c"=>NULL\'::hstore'
31
- @db.literal({"c"=>'NULL'}.hstore).should == '\'"c"=>"NULL"\'::hstore'
32
- @db.literal({'c'=>'\ "\'=>'}.hstore).should == '\'"c"=>"\\\\ \\"\'\'=>"\'::hstore'
33
- ['\'"a"=>"b","c"=>"d"\'::hstore', '\'"c"=>"d","a"=>"b"\'::hstore'].should include(@db.literal({"a"=>"b","c"=>"d"}.hstore))
27
+ @db.literal(Sequel.hstore({})).should == '\'\'::hstore'
28
+ @db.literal(Sequel.hstore("a"=>"b")).should == '\'"a"=>"b"\'::hstore'
29
+ @db.literal(Sequel.hstore("c"=>nil)).should == '\'"c"=>NULL\'::hstore'
30
+ @db.literal(Sequel.hstore("c"=>'NULL')).should == '\'"c"=>"NULL"\'::hstore'
31
+ @db.literal(Sequel.hstore('c'=>'\ "\'=>')).should == '\'"c"=>"\\\\ \\"\'\'=>"\'::hstore'
32
+ ['\'"a"=>"b","c"=>"d"\'::hstore', '\'"c"=>"d","a"=>"b"\'::hstore'].should include(@db.literal(Sequel.hstore("a"=>"b","c"=>"d")))
34
33
  end
35
34
 
36
- it "should have Hash#hstore method for creating HStore instances" do
37
- {}.hstore.should be_a_kind_of(@c)
35
+ it "should have Sequel.hstore method for creating HStore instances" do
36
+ Sequel.hstore({}).should be_a_kind_of(@c)
37
+ end
38
+
39
+ it "should have Sequel.hstore return HStores as-is" do
40
+ a = Sequel.hstore({})
41
+ Sequel.hstore(a).should equal(a)
38
42
  end
39
43
 
40
44
  it "should HStore#to_hash method for getting underlying hash" do
41
- {}.hstore.to_hash.should be_a_kind_of(Hash)
45
+ Sequel.hstore({}).to_hash.should be_a_kind_of(Hash)
42
46
  end
43
47
 
44
48
  it "should convert keys and values to strings on creation" do
45
- {1=>2}.hstore.to_hash.should == {"1"=>"2"}
49
+ Sequel.hstore(1=>2).to_hash.should == {"1"=>"2"}
46
50
  end
47
51
 
48
52
  it "should convert keys and values to strings on assignment" do
49
- v = {}.hstore
53
+ v = Sequel.hstore({})
50
54
  v[1] = 2
51
55
  v.to_hash.should == {"1"=>"2"}
52
56
  v.store(:'1', 3)
@@ -54,92 +58,92 @@ describe "pg_hstore extension" do
54
58
  end
55
59
 
56
60
  it "should not convert nil values to strings on creation" do
57
- {:foo=>nil}.hstore.to_hash.should == {"foo"=>nil}
61
+ Sequel.hstore(:foo=>nil).to_hash.should == {"foo"=>nil}
58
62
  end
59
63
 
60
64
  it "should not convert nil values to strings on assignment" do
61
- v = {}.hstore
65
+ v = Sequel.hstore({})
62
66
  v[:foo] = nil
63
67
  v.to_hash.should == {"foo"=>nil}
64
68
  end
65
69
 
66
70
  it "should convert lookups by key to string" do
67
- {'foo'=>'bar'}.hstore[:foo].should == 'bar'
68
- {'1'=>'bar'}.hstore[1].should == 'bar'
71
+ Sequel.hstore('foo'=>'bar')[:foo].should == 'bar'
72
+ Sequel.hstore('1'=>'bar')[1].should == 'bar'
69
73
 
70
- {'foo'=>'bar'}.hstore.fetch(:foo).should == 'bar'
71
- {'foo'=>'bar'}.hstore.fetch(:foo2, 2).should == 2
74
+ Sequel.hstore('foo'=>'bar').fetch(:foo).should == 'bar'
75
+ Sequel.hstore('foo'=>'bar').fetch(:foo2, 2).should == 2
72
76
  k = nil
73
- {'foo2'=>'bar'}.hstore.fetch(:foo){|key| k = key }.should == 'foo'
77
+ Sequel.hstore('foo2'=>'bar').fetch(:foo){|key| k = key }.should == 'foo'
74
78
  k.should == 'foo'
75
79
 
76
- {'foo'=>'bar'}.hstore.has_key?(:foo).should be_true
77
- {'foo'=>'bar'}.hstore.has_key?(:bar).should be_false
78
- {'foo'=>'bar'}.hstore.key?(:foo).should be_true
79
- {'foo'=>'bar'}.hstore.key?(:bar).should be_false
80
- {'foo'=>'bar'}.hstore.member?(:foo).should be_true
81
- {'foo'=>'bar'}.hstore.member?(:bar).should be_false
82
- {'foo'=>'bar'}.hstore.include?(:foo).should be_true
83
- {'foo'=>'bar'}.hstore.include?(:bar).should be_false
80
+ Sequel.hstore('foo'=>'bar').has_key?(:foo).should be_true
81
+ Sequel.hstore('foo'=>'bar').has_key?(:bar).should be_false
82
+ Sequel.hstore('foo'=>'bar').key?(:foo).should be_true
83
+ Sequel.hstore('foo'=>'bar').key?(:bar).should be_false
84
+ Sequel.hstore('foo'=>'bar').member?(:foo).should be_true
85
+ Sequel.hstore('foo'=>'bar').member?(:bar).should be_false
86
+ Sequel.hstore('foo'=>'bar').include?(:foo).should be_true
87
+ Sequel.hstore('foo'=>'bar').include?(:bar).should be_false
84
88
 
85
- {'foo'=>'bar', '1'=>'2'}.hstore.values_at(:foo3, :foo, :foo2, 1).should == [nil, 'bar', nil, '2']
89
+ Sequel.hstore('foo'=>'bar', '1'=>'2').values_at(:foo3, :foo, :foo2, 1).should == [nil, 'bar', nil, '2']
86
90
 
87
91
  if RUBY_VERSION >= '1.9.0'
88
- {'foo'=>'bar'}.hstore.assoc(:foo).should == ['foo', 'bar']
89
- {'foo'=>'bar'}.hstore.assoc(:foo2).should == nil
92
+ Sequel.hstore('foo'=>'bar').assoc(:foo).should == ['foo', 'bar']
93
+ Sequel.hstore('foo'=>'bar').assoc(:foo2).should == nil
90
94
  end
91
95
  end
92
96
 
93
97
  it "should convert has_value?/value? lookups to string" do
94
- {'foo'=>'bar'}.hstore.has_value?(:bar).should be_true
95
- {'foo'=>'bar'}.hstore.has_value?(:foo).should be_false
96
- {'foo'=>'bar'}.hstore.value?(:bar).should be_true
97
- {'foo'=>'bar'}.hstore.value?(:foo).should be_false
98
+ Sequel.hstore('foo'=>'bar').has_value?(:bar).should be_true
99
+ Sequel.hstore('foo'=>'bar').has_value?(:foo).should be_false
100
+ Sequel.hstore('foo'=>'bar').value?(:bar).should be_true
101
+ Sequel.hstore('foo'=>'bar').value?(:foo).should be_false
98
102
  end
99
103
 
100
104
  it "should handle nil values in has_value?/value? lookups" do
101
- {'foo'=>''}.hstore.has_value?('').should be_true
102
- {'foo'=>''}.hstore.has_value?(nil).should be_false
103
- {'foo'=>nil}.hstore.has_value?(nil).should be_true
105
+ Sequel.hstore('foo'=>'').has_value?('').should be_true
106
+ Sequel.hstore('foo'=>'').has_value?(nil).should be_false
107
+ Sequel.hstore('foo'=>nil).has_value?(nil).should be_true
104
108
  end
105
109
 
106
110
  it "should have underlying hash convert lookups by key to string" do
107
- {'foo'=>'bar'}.hstore.to_hash[:foo].should == 'bar'
108
- {'1'=>'bar'}.hstore.to_hash[1].should == 'bar'
111
+ Sequel.hstore('foo'=>'bar').to_hash[:foo].should == 'bar'
112
+ Sequel.hstore('1'=>'bar').to_hash[1].should == 'bar'
109
113
  end
110
114
 
111
115
  if RUBY_VERSION >= '1.9.0'
112
116
  it "should convert key lookups to string" do
113
- {'foo'=>'bar'}.hstore.key(:bar).should == 'foo'
114
- {'foo'=>'bar'}.hstore.key(:bar2).should be_nil
117
+ Sequel.hstore('foo'=>'bar').key(:bar).should == 'foo'
118
+ Sequel.hstore('foo'=>'bar').key(:bar2).should be_nil
115
119
  end
116
120
 
117
121
  it "should handle nil values in key lookups" do
118
- {'foo'=>''}.hstore.key('').should == 'foo'
119
- {'foo'=>''}.hstore.key(nil).should == nil
120
- {'foo'=>nil}.hstore.key(nil).should == 'foo'
122
+ Sequel.hstore('foo'=>'').key('').should == 'foo'
123
+ Sequel.hstore('foo'=>'').key(nil).should == nil
124
+ Sequel.hstore('foo'=>nil).key(nil).should == 'foo'
121
125
  end
122
126
 
123
127
  it "should convert rassoc lookups to string" do
124
- {'foo'=>'bar'}.hstore.rassoc(:bar).should == ['foo', 'bar']
125
- {'foo'=>'bar'}.hstore.rassoc(:bar2).should be_nil
128
+ Sequel.hstore('foo'=>'bar').rassoc(:bar).should == ['foo', 'bar']
129
+ Sequel.hstore('foo'=>'bar').rassoc(:bar2).should be_nil
126
130
  end
127
131
 
128
132
  it "should handle nil values in rassoc lookups" do
129
- {'foo'=>''}.hstore.rassoc('').should == ['foo', '']
130
- {'foo'=>''}.hstore.rassoc(nil).should == nil
131
- {'foo'=>nil}.hstore.rassoc(nil).should == ['foo', nil]
133
+ Sequel.hstore('foo'=>'').rassoc('').should == ['foo', '']
134
+ Sequel.hstore('foo'=>'').rassoc(nil).should == nil
135
+ Sequel.hstore('foo'=>nil).rassoc(nil).should == ['foo', nil]
132
136
  end
133
137
  end
134
138
 
135
139
  it "should have delete convert key to string" do
136
- v = {'foo'=>'bar'}.hstore
140
+ v = Sequel.hstore('foo'=>'bar')
137
141
  v.delete(:foo).should == 'bar'
138
142
  v.to_hash.should == {}
139
143
  end
140
144
 
141
145
  it "should handle #replace with hashes that do not use strings" do
142
- v = {'foo'=>'bar'}.hstore
146
+ v = Sequel.hstore('foo'=>'bar')
143
147
  v.replace(:bar=>1)
144
148
  v.should be_a_kind_of(@c)
145
149
  v.should == {'bar'=>'1'}
@@ -147,18 +151,18 @@ describe "pg_hstore extension" do
147
151
  end
148
152
 
149
153
  it "should handle #merge with hashes that do not use strings" do
150
- v = {'foo'=>'bar'}.hstore.merge(:bar=>1)
154
+ v = Sequel.hstore('foo'=>'bar').merge(:bar=>1)
151
155
  v.should be_a_kind_of(@c)
152
156
  v.should == {'foo'=>'bar', 'bar'=>'1'}
153
157
  end
154
158
 
155
159
  it "should handle #merge/#update with hashes that do not use strings" do
156
- v = {'foo'=>'bar'}.hstore
160
+ v = Sequel.hstore('foo'=>'bar')
157
161
  v.merge!(:bar=>1)
158
162
  v.should be_a_kind_of(@c)
159
163
  v.should == {'foo'=>'bar', 'bar'=>'1'}
160
164
 
161
- v = {'foo'=>'bar'}.hstore
165
+ v = Sequel.hstore('foo'=>'bar')
162
166
  v.update(:bar=>1)
163
167
  v.should be_a_kind_of(@c)
164
168
  v.should == {'foo'=>'bar', 'bar'=>'1'}
@@ -167,11 +171,11 @@ describe "pg_hstore extension" do
167
171
  it "should support using hstores as bound variables" do
168
172
  @db.bound_variable_arg(1, nil).should == 1
169
173
  @db.bound_variable_arg({'1'=>'2'}, nil).should == '"1"=>"2"'
170
- @db.bound_variable_arg({'1'=>'2'}.hstore, nil).should == '"1"=>"2"'
171
- @db.bound_variable_arg({'1'=>nil}.hstore, nil).should == '"1"=>NULL'
172
- @db.bound_variable_arg({'1'=>"NULL"}.hstore, nil).should == '"1"=>"NULL"'
173
- @db.bound_variable_arg({'1'=>"'\\ \"=>"}.hstore, nil).should == '"1"=>"\'\\\\ \\"=>"'
174
- ['"a"=>"b","c"=>"d"', '"c"=>"d","a"=>"b"'].should include(@db.bound_variable_arg({"a"=>"b","c"=>"d"}.hstore, nil))
174
+ @db.bound_variable_arg(Sequel.hstore('1'=>'2'), nil).should == '"1"=>"2"'
175
+ @db.bound_variable_arg(Sequel.hstore('1'=>nil), nil).should == '"1"=>NULL'
176
+ @db.bound_variable_arg(Sequel.hstore('1'=>"NULL"), nil).should == '"1"=>"NULL"'
177
+ @db.bound_variable_arg(Sequel.hstore('1'=>"'\\ \"=>"), nil).should == '"1"=>"\'\\\\ \\"=>"'
178
+ ['"a"=>"b","c"=>"d"', '"c"=>"d","a"=>"b"'].should include(@db.bound_variable_arg(Sequel.hstore("a"=>"b","c"=>"d"), nil))
175
179
  end
176
180
 
177
181
  it "should parse hstore type from the schema correctly" do
@@ -180,14 +184,11 @@ describe "pg_hstore extension" do
180
184
  end
181
185
 
182
186
  it "should support typecasting for the hstore type" do
183
- h = {1=>2}.hstore
187
+ h = Sequel.hstore(1=>2)
184
188
  @db.typecast_value(:hstore, h).should equal(h)
185
- @db.typecast_value(:hstore, '').should be_a_kind_of(@c)
186
- @db.typecast_value(:hstore, '').should == {}.hstore
187
- @db.typecast_value(:hstore, '"a"=>"b"').should == {"a"=>"b"}.hstore
188
189
  @db.typecast_value(:hstore, {}).should be_a_kind_of(@c)
189
- @db.typecast_value(:hstore, {}).should == {}.hstore
190
- @db.typecast_value(:hstore, {'a'=>'b'}).should == {"a"=>"b"}.hstore
190
+ @db.typecast_value(:hstore, {}).should == Sequel.hstore({})
191
+ @db.typecast_value(:hstore, {'a'=>'b'}).should == Sequel.hstore("a"=>"b")
191
192
  proc{@db.typecast_value(:hstore, [])}.should raise_error(Sequel::InvalidValue)
192
193
  end
193
194
  end