sequel 3.37.0 → 3.38.0

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.
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
@@ -1,8 +1,5 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
2
 
3
- Regexp.send(:include, Sequel::SQL::StringMethods)
4
- String.send(:include, Sequel::SQL::StringMethods)
5
-
6
3
  describe "Blockless Ruby Filters" do
7
4
  before do
8
5
  db = Sequel::Database.new
@@ -19,27 +16,22 @@ describe "Blockless Ruby Filters" do
19
16
  @d.l(:x).should == 'x'
20
17
  end
21
18
 
22
- it "should support NOT via Symbol#~" do
23
- @d.l(~:x).should == 'NOT x'
24
- end
25
-
26
19
  it "should support qualified columns" do
27
20
  @d.l(:x__y).should == 'x.y'
28
- @d.l(~:x__y).should == 'NOT x.y'
29
21
  end
30
22
 
31
23
  it "should support NOT with SQL functions" do
32
- @d.l(~:is_blah.sql_function).should == 'NOT is_blah()'
33
- @d.l(~:is_blah.sql_function(:x)).should == 'NOT is_blah(x)'
34
- @d.l(~:is_blah.sql_function(:x__y)).should == 'NOT is_blah(x.y)'
35
- @d.l(~:is_blah.sql_function(:x, :x__y)).should == 'NOT is_blah(x, x.y)'
24
+ @d.l(~Sequel.function(:is_blah)).should == 'NOT is_blah()'
25
+ @d.l(~Sequel.function(:is_blah, :x)).should == 'NOT is_blah(x)'
26
+ @d.l(~Sequel.function(:is_blah, :x__y)).should == 'NOT is_blah(x.y)'
27
+ @d.l(~Sequel.function(:is_blah, :x, :x__y)).should == 'NOT is_blah(x, x.y)'
36
28
  end
37
29
 
38
30
  it "should handle multiple ~" do
39
- @d.l(~~:x).should == 'x'
40
- @d.l(~~~:x).should == 'NOT x'
41
- @d.l(~~(:x & :y)).should == '(x AND y)'
42
- @d.l(~~(:x | :y)).should == '(x OR y)'
31
+ @d.l(~Sequel.~(:x)).should == 'x'
32
+ @d.l(~~Sequel.~(:x)).should == 'NOT x'
33
+ @d.l(~~Sequel.&(:x, :y)).should == '(x AND y)'
34
+ @d.l(~~Sequel.|(:x, :y)).should == '(x OR y)'
43
35
  end
44
36
 
45
37
  it "should support = via Hash" do
@@ -54,207 +46,107 @@ describe "Blockless Ruby Filters" do
54
46
  it "should use = 't' and != 't' OR IS NULL if IS TRUE is not supported" do
55
47
  @d.meta_def(:supports_is_true?){false}
56
48
  @d.l(:x => true).should == "(x = 't')"
57
- @d.l(~{:x => true}).should == "((x != 't') OR (x IS NULL))"
49
+ @d.l(~Sequel.expr(:x => true)).should == "((x != 't') OR (x IS NULL))"
58
50
  @d.l(:x => false).should == "(x = 'f')"
59
- @d.l(~{:x => false}).should == "((x != 'f') OR (x IS NULL))"
51
+ @d.l(~Sequel.expr(:x => false)).should == "((x != 'f') OR (x IS NULL))"
60
52
  end
61
53
 
62
- it "should support != via Hash#~" do
63
- @d.l(~{:x => 100}).should == '(x != 100)'
64
- @d.l(~{:x => 'a'}).should == '(x != \'a\')'
65
- @d.l(~{:x => true}).should == '(x IS NOT TRUE)'
66
- @d.l(~{:x => false}).should == '(x IS NOT FALSE)'
67
- @d.l(~{:x => nil}).should == '(x IS NOT NULL)'
54
+ it "should support != via inverted Hash" do
55
+ @d.l(~Sequel.expr(:x => 100)).should == '(x != 100)'
56
+ @d.l(~Sequel.expr(:x => 'a')).should == '(x != \'a\')'
57
+ @d.l(~Sequel.expr(:x => true)).should == '(x IS NOT TRUE)'
58
+ @d.l(~Sequel.expr(:x => false)).should == '(x IS NOT FALSE)'
59
+ @d.l(~Sequel.expr(:x => nil)).should == '(x IS NOT NULL)'
68
60
  end
69
61
 
70
62
  it "should support ~ via Hash and Regexp (if supported by database)" do
71
63
  @d.l(:x => /blah/).should == '(x ~ \'blah\')'
72
64
  end
73
65
 
74
- it "should support !~ via Hash#~ and Regexp" do
75
- @d.l(~{:x => /blah/}).should == '(x !~ \'blah\')'
66
+ it "should support !~ via inverted Hash and Regexp" do
67
+ @d.l(~Sequel.expr(:x => /blah/)).should == '(x !~ \'blah\')'
76
68
  end
77
69
 
78
- it "should support LIKE via Symbol#like" do
79
- @d.l(:x.like('a')).should == '(x LIKE \'a\')'
80
- @d.l(:x.like(/a/)).should == '(x ~ \'a\')'
81
- @d.l(:x.like('a', 'b')).should == '((x LIKE \'a\') OR (x LIKE \'b\'))'
82
- @d.l(:x.like(/a/, /b/i)).should == '((x ~ \'a\') OR (x ~* \'b\'))'
83
- @d.l(:x.like('a', /b/)).should == '((x LIKE \'a\') OR (x ~ \'b\'))'
84
-
85
- @d.l('a'.like(:x)).should == "('a' LIKE x)"
86
- @d.l('a'.like(:x, 'b')).should == "(('a' LIKE x) OR ('a' LIKE 'b'))"
87
- @d.l('a'.like(:x, /b/)).should == "(('a' LIKE x) OR ('a' ~ 'b'))"
88
- @d.l('a'.like(:x, /b/i)).should == "(('a' LIKE x) OR ('a' ~* 'b'))"
89
-
90
- @d.l(/a/.like(:x)).should == "('a' ~ x)"
91
- @d.l(/a/.like(:x, 'b')).should == "(('a' ~ x) OR ('a' ~ 'b'))"
92
- @d.l(/a/.like(:x, /b/)).should == "(('a' ~ x) OR ('a' ~ 'b'))"
93
- @d.l(/a/.like(:x, /b/i)).should == "(('a' ~ x) OR ('a' ~* 'b'))"
94
-
95
- @d.l(/a/i.like(:x)).should == "('a' ~* x)"
96
- @d.l(/a/i.like(:x, 'b')).should == "(('a' ~* x) OR ('a' ~* 'b'))"
97
- @d.l(/a/i.like(:x, /b/)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
98
- @d.l(/a/i.like(:x, /b/i)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
99
- end
100
-
101
- it "should support NOT LIKE via Symbol#like and Symbol#~" do
102
- @d.l(~:x.like('a')).should == '(x NOT LIKE \'a\')'
103
- @d.l(~:x.like(/a/)).should == '(x !~ \'a\')'
104
- @d.l(~:x.like('a', 'b')).should == '((x NOT LIKE \'a\') AND (x NOT LIKE \'b\'))'
105
- @d.l(~:x.like(/a/, /b/i)).should == '((x !~ \'a\') AND (x !~* \'b\'))'
106
- @d.l(~:x.like('a', /b/)).should == '((x NOT LIKE \'a\') AND (x !~ \'b\'))'
107
-
108
- @d.l(~'a'.like(:x)).should == "('a' NOT LIKE x)"
109
- @d.l(~'a'.like(:x, 'b')).should == "(('a' NOT LIKE x) AND ('a' NOT LIKE 'b'))"
110
- @d.l(~'a'.like(:x, /b/)).should == "(('a' NOT LIKE x) AND ('a' !~ 'b'))"
111
- @d.l(~'a'.like(:x, /b/i)).should == "(('a' NOT LIKE x) AND ('a' !~* 'b'))"
112
-
113
- @d.l(~/a/.like(:x)).should == "('a' !~ x)"
114
- @d.l(~/a/.like(:x, 'b')).should == "(('a' !~ x) AND ('a' !~ 'b'))"
115
- @d.l(~/a/.like(:x, /b/)).should == "(('a' !~ x) AND ('a' !~ 'b'))"
116
- @d.l(~/a/.like(:x, /b/i)).should == "(('a' !~ x) AND ('a' !~* 'b'))"
117
-
118
- @d.l(~/a/i.like(:x)).should == "('a' !~* x)"
119
- @d.l(~/a/i.like(:x, 'b')).should == "(('a' !~* x) AND ('a' !~* 'b'))"
120
- @d.l(~/a/i.like(:x, /b/)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
121
- @d.l(~/a/i.like(:x, /b/i)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
122
- end
123
-
124
- it "should support ILIKE via Symbol#ilike" do
125
- @d.l(:x.ilike('a')).should == '(x ILIKE \'a\')'
126
- @d.l(:x.ilike(/a/)).should == '(x ~* \'a\')'
127
- @d.l(:x.ilike('a', 'b')).should == '((x ILIKE \'a\') OR (x ILIKE \'b\'))'
128
- @d.l(:x.ilike(/a/, /b/i)).should == '((x ~* \'a\') OR (x ~* \'b\'))'
129
- @d.l(:x.ilike('a', /b/)).should == '((x ILIKE \'a\') OR (x ~* \'b\'))'
130
-
131
- @d.l('a'.ilike(:x)).should == "('a' ILIKE x)"
132
- @d.l('a'.ilike(:x, 'b')).should == "(('a' ILIKE x) OR ('a' ILIKE 'b'))"
133
- @d.l('a'.ilike(:x, /b/)).should == "(('a' ILIKE x) OR ('a' ~* 'b'))"
134
- @d.l('a'.ilike(:x, /b/i)).should == "(('a' ILIKE x) OR ('a' ~* 'b'))"
135
-
136
- @d.l(/a/.ilike(:x)).should == "('a' ~* x)"
137
- @d.l(/a/.ilike(:x, 'b')).should == "(('a' ~* x) OR ('a' ~* 'b'))"
138
- @d.l(/a/.ilike(:x, /b/)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
139
- @d.l(/a/.ilike(:x, /b/i)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
140
-
141
- @d.l(/a/i.ilike(:x)).should == "('a' ~* x)"
142
- @d.l(/a/i.ilike(:x, 'b')).should == "(('a' ~* x) OR ('a' ~* 'b'))"
143
- @d.l(/a/i.ilike(:x, /b/)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
144
- @d.l(/a/i.ilike(:x, /b/i)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
145
- end
146
-
147
- it "should support NOT ILIKE via Symbol#ilike and Symbol#~" do
148
- @d.l(~:x.ilike('a')).should == '(x NOT ILIKE \'a\')'
149
- @d.l(~:x.ilike(/a/)).should == '(x !~* \'a\')'
150
- @d.l(~:x.ilike('a', 'b')).should == '((x NOT ILIKE \'a\') AND (x NOT ILIKE \'b\'))'
151
- @d.l(~:x.ilike(/a/, /b/i)).should == '((x !~* \'a\') AND (x !~* \'b\'))'
152
- @d.l(~:x.ilike('a', /b/)).should == '((x NOT ILIKE \'a\') AND (x !~* \'b\'))'
153
-
154
- @d.l(~'a'.ilike(:x)).should == "('a' NOT ILIKE x)"
155
- @d.l(~'a'.ilike(:x, 'b')).should == "(('a' NOT ILIKE x) AND ('a' NOT ILIKE 'b'))"
156
- @d.l(~'a'.ilike(:x, /b/)).should == "(('a' NOT ILIKE x) AND ('a' !~* 'b'))"
157
- @d.l(~'a'.ilike(:x, /b/i)).should == "(('a' NOT ILIKE x) AND ('a' !~* 'b'))"
158
-
159
- @d.l(~/a/.ilike(:x)).should == "('a' !~* x)"
160
- @d.l(~/a/.ilike(:x, 'b')).should == "(('a' !~* x) AND ('a' !~* 'b'))"
161
- @d.l(~/a/.ilike(:x, /b/)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
162
- @d.l(~/a/.ilike(:x, /b/i)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
163
-
164
- @d.l(~/a/i.ilike(:x)).should == "('a' !~* x)"
165
- @d.l(~/a/i.ilike(:x, 'b')).should == "(('a' !~* x) AND ('a' !~* 'b'))"
166
- @d.l(~/a/i.ilike(:x, /b/)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
167
- @d.l(~/a/i.ilike(:x, /b/i)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
168
- end
169
-
170
- it "should support negating ranges via Hash#~ and Range" do
171
- @d.l(~{:x => 1..5}).should == '((x < 1) OR (x > 5))'
172
- @d.l(~{:x => 1...5}).should == '((x < 1) OR (x >= 5))'
70
+ it "should support negating ranges" do
71
+ @d.l(~Sequel.expr(:x => 1..5)).should == '((x < 1) OR (x > 5))'
72
+ @d.l(~Sequel.expr(:x => 1...5)).should == '((x < 1) OR (x >= 5))'
173
73
  end
174
74
 
175
- it "should support negating NOT IN via Hash#~ and Dataset or Array" do
176
- @d.l(~{:x => @d.select(:i)}).should == '(x NOT IN (SELECT i FROM items))'
177
- @d.l(~{:x => [1,2,3]}).should == '(x NOT IN (1, 2, 3))'
75
+ it "should support negating IN with Dataset or Array" do
76
+ @d.l(~Sequel.expr(:x => @d.select(:i))).should == '(x NOT IN (SELECT i FROM items))'
77
+ @d.l(~Sequel.expr(:x => [1,2,3])).should == '(x NOT IN (1, 2, 3))'
178
78
  end
179
79
 
180
- it "should support + - * / via Symbol#+,-,*,/" do
181
- @d.l(:x + 1 > 100).should == '((x + 1) > 100)'
182
- @d.l((:x * :y) < 100.01).should == '((x * y) < 100.01)'
183
- @d.l((:x - :y/2) >= 100000000000000000000000000000000000).should == '((x - (y / 2)) >= 100000000000000000000000000000000000)'
184
- @d.l((((:x - :y)/(:x + :y))*:z) <= 100).should == '((((x - y) / (x + y)) * z) <= 100)'
185
- @d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
186
- end
187
-
188
80
  it "should not add ~ method to string expressions" do
189
- proc{~:x.sql_string}.should raise_error(NoMethodError)
81
+ proc{~Sequel.expr(:x).sql_string}.should raise_error(NoMethodError)
190
82
  end
191
83
 
192
84
  it "should allow mathematical or string operations on true, false, or nil" do
193
- @d.lit(:x + 1).should == '(x + 1)'
194
- @d.lit(:x - true).should == "(x - 't')"
195
- @d.lit(:x / false).should == "(x / 'f')"
196
- @d.lit(:x * nil).should == '(x * NULL)'
197
- @d.lit([:x, nil].sql_string_join).should == '(x || NULL)'
85
+ @d.lit(Sequel.expr(:x) + 1).should == '(x + 1)'
86
+ @d.lit(Sequel.expr(:x) - true).should == "(x - 't')"
87
+ @d.lit(Sequel.expr(:x) / false).should == "(x / 'f')"
88
+ @d.lit(Sequel.expr(:x) * nil).should == '(x * NULL)'
89
+ @d.lit(Sequel.join([:x, nil])).should == '(x || NULL)'
198
90
  end
199
91
 
200
92
  it "should allow mathematical or string operations on boolean complex expressions" do
201
- @d.lit(:x + (:y + 1)).should == '(x + y + 1)'
202
- @d.lit(:x - ~:y).should == '(x - NOT y)'
203
- @d.lit(:x / (:y & :z)).should == '(x / (y AND z))'
204
- @d.lit(:x * (:y | :z)).should == '(x * (y OR z))'
205
- @d.lit(:x + :y.like('a')).should == "(x + (y LIKE 'a'))"
206
- @d.lit(:x - ~:y.like('a')).should == "(x - (y NOT LIKE 'a'))"
207
- @d.lit([:x, ~:y.like('a')].sql_string_join).should == "(x || (y NOT LIKE 'a'))"
93
+ @d.lit(Sequel.expr(:x) + (Sequel.expr(:y) + 1)).should == '(x + y + 1)'
94
+ @d.lit(Sequel.expr(:x) - ~Sequel.expr(:y)).should == '(x - NOT y)'
95
+ @d.lit(Sequel.expr(:x) / (Sequel.expr(:y) & :z)).should == '(x / (y AND z))'
96
+ @d.lit(Sequel.expr(:x) * (Sequel.expr(:y) | :z)).should == '(x * (y OR z))'
97
+ @d.lit(Sequel.expr(:x) + Sequel.expr(:y).like('a')).should == "(x + (y LIKE 'a'))"
98
+ @d.lit(Sequel.expr(:x) - ~Sequel.expr(:y).like('a')).should == "(x - (y NOT LIKE 'a'))"
99
+ @d.lit(Sequel.join([:x, ~Sequel.expr(:y).like('a')])).should == "(x || (y NOT LIKE 'a'))"
208
100
  end
209
101
 
210
102
  it "should support AND conditions via &" do
211
- @d.l(:x & :y).should == '(x AND y)'
212
- @d.l(:x.sql_boolean & :y).should == '(x AND y)'
213
- @d.l(:x & :y & :z).should == '(x AND y AND z)'
214
- @d.l(:x & {:y => :z}).should == '(x AND (y = z))'
215
- @d.l((:x + 200 < 0) & (:y - 200 < 0)).should == '(((x + 200) < 0) AND ((y - 200) < 0))'
216
- @d.l(:x & ~:y).should == '(x AND NOT y)'
217
- @d.l(~:x & :y).should == '(NOT x AND y)'
218
- @d.l(~:x & ~:y).should == '(NOT x AND NOT y)'
103
+ @d.l(Sequel.expr(:x) & :y).should == '(x AND y)'
104
+ @d.l(Sequel.expr(:x).sql_boolean & :y).should == '(x AND y)'
105
+ @d.l(Sequel.expr(:x) & :y & :z).should == '(x AND y AND z)'
106
+ @d.l(Sequel.expr(:x) & {:y => :z}).should == '(x AND (y = z))'
107
+ @d.l((Sequel.expr(:x) + 200 < 0) & (Sequel.expr(:y) - 200 < 0)).should == '(((x + 200) < 0) AND ((y - 200) < 0))'
108
+ @d.l(Sequel.expr(:x) & ~Sequel.expr(:y)).should == '(x AND NOT y)'
109
+ @d.l(~Sequel.expr(:x) & :y).should == '(NOT x AND y)'
110
+ @d.l(~Sequel.expr(:x) & ~Sequel.expr(:y)).should == '(NOT x AND NOT y)'
219
111
  end
220
112
 
221
113
  it "should support OR conditions via |" do
222
- @d.l(:x | :y).should == '(x OR y)'
223
- @d.l(:x.sql_boolean | :y).should == '(x OR y)'
224
- @d.l(:x | :y | :z).should == '(x OR y OR z)'
225
- @d.l(:x | {:y => :z}).should == '(x OR (y = z))'
226
- @d.l((:x.sql_number > 200) | (:y.sql_number < 200)).should == '((x > 200) OR (y < 200))'
114
+ @d.l(Sequel.expr(:x) | :y).should == '(x OR y)'
115
+ @d.l(Sequel.expr(:x).sql_boolean | :y).should == '(x OR y)'
116
+ @d.l(Sequel.expr(:x) | :y | :z).should == '(x OR y OR z)'
117
+ @d.l(Sequel.expr(:x) | {:y => :z}).should == '(x OR (y = z))'
118
+ @d.l((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y).sql_number < 200)).should == '((x > 200) OR (y < 200))'
227
119
  end
228
120
 
229
121
  it "should support & | combinations" do
230
- @d.l((:x | :y) & :z).should == '((x OR y) AND z)'
231
- @d.l(:x | (:y & :z)).should == '(x OR (y AND z))'
232
- @d.l((:x & :w) | (:y & :z)).should == '((x AND w) OR (y AND z))'
122
+ @d.l((Sequel.expr(:x) | :y) & :z).should == '((x OR y) AND z)'
123
+ @d.l(Sequel.expr(:x) | (Sequel.expr(:y) & :z)).should == '(x OR (y AND z))'
124
+ @d.l((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z)).should == '((x AND w) OR (y AND z))'
233
125
  end
234
126
 
235
127
  it "should support & | with ~" do
236
- @d.l(~((:x | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
237
- @d.l(~(:x | (:y & :z))).should == '(NOT x AND (NOT y OR NOT z))'
238
- @d.l(~((:x & :w) | (:y & :z))).should == '((NOT x OR NOT w) AND (NOT y OR NOT z))'
239
- @d.l(~((:x.sql_number > 200) | (:y & :z))).should == '((x <= 200) AND (NOT y OR NOT z))'
128
+ @d.l(~((Sequel.expr(:x) | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
129
+ @d.l(~(Sequel.expr(:x) | (Sequel.expr(:y) & :z))).should == '(NOT x AND (NOT y OR NOT z))'
130
+ @d.l(~((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z))).should == '((NOT x OR NOT w) AND (NOT y OR NOT z))'
131
+ @d.l(~((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y) & :z))).should == '((x <= 200) AND (NOT y OR NOT z))'
240
132
  end
241
133
 
242
134
  it "should support LiteralString" do
243
- @d.l('x'.lit).should == '(x)'
244
- @d.l(~'x'.lit).should == 'NOT x'
245
- @d.l(~~'x'.lit).should == 'x'
246
- @d.l(~(('x'.lit | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
247
- @d.l(~(:x | 'y'.lit)).should == '(NOT x AND NOT y)'
248
- @d.l(~('x'.lit & 'y'.lit)).should == '(NOT x OR NOT y)'
249
- @d.l({'y'.lit => 'z'.lit} & 'x'.lit).should == '((y = z) AND x)'
250
- @d.l(('x'.lit > 200) & ('y'.lit < 200)).should == '((x > 200) AND (y < 200))'
251
- @d.l(~('x'.lit + 1 > 100)).should == '((x + 1) <= 100)'
252
- @d.l('x'.lit.like(/a/)).should == '(x ~ \'a\')'
253
- @d.l('x'.lit + 1 > 100).should == '((x + 1) > 100)'
254
- @d.l(('x'.lit * :y) < 100.01).should == '((x * y) < 100.01)'
255
- @d.l(('x'.lit - :y/2) >= 100000000000000000000000000000000000).should == '((x - (y / 2)) >= 100000000000000000000000000000000000)'
256
- @d.l(('z'.lit * (('x'.lit / :y)/(:x + :y))) <= 100).should == '((z * (x / y / (x + y))) <= 100)'
257
- @d.l(~(((('x'.lit - :y)/(:x + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
135
+ @d.l(Sequel.lit('x')).should == '(x)'
136
+ @d.l(~Sequel.lit('x')).should == 'NOT x'
137
+ @d.l(~~Sequel.lit('x')).should == 'x'
138
+ @d.l(~((Sequel.lit('x') | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
139
+ @d.l(~(Sequel.expr(:x) | Sequel.lit('y'))).should == '(NOT x AND NOT y)'
140
+ @d.l(~(Sequel.lit('x') & Sequel.lit('y'))).should == '(NOT x OR NOT y)'
141
+ @d.l(Sequel.expr(Sequel.lit('y') => Sequel.lit('z')) & Sequel.lit('x')).should == '((y = z) AND x)'
142
+ @d.l((Sequel.lit('x') > 200) & (Sequel.lit('y') < 200)).should == '((x > 200) AND (y < 200))'
143
+ @d.l(~(Sequel.lit('x') + 1 > 100)).should == '((x + 1) <= 100)'
144
+ @d.l(Sequel.lit('x').like(/a/)).should == '(x ~ \'a\')'
145
+ @d.l(Sequel.lit('x') + 1 > 100).should == '((x + 1) > 100)'
146
+ @d.l((Sequel.lit('x') * :y) < 100.01).should == '((x * y) < 100.01)'
147
+ @d.l((Sequel.lit('x') - Sequel.expr(:y)/2) >= 100000000000000000000000000000000000).should == '((x - (y / 2)) >= 100000000000000000000000000000000000)'
148
+ @d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).should == '((z * (x / y / (x + y))) <= 100)'
149
+ @d.l(~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
258
150
  end
259
151
 
260
152
  it "should support hashes by ANDing the conditions" do
@@ -270,64 +162,64 @@ describe "Blockless Ruby Filters" do
270
162
  end
271
163
 
272
164
  it "should emulate columns for array values" do
273
- @d.l([:x, :y]=>[[1,2], [3,4]].sql_array).should == '((x, y) IN ((1, 2), (3, 4)))'
165
+ @d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).should == '((x, y) IN ((1, 2), (3, 4)))'
274
166
  @d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).should == '((x, y, z) IN ((1, 2, 5), (3, 4, 6)))'
275
167
  end
276
168
 
277
169
  it "should emulate multiple column in if not supported" do
278
170
  @d.meta_def(:supports_multiple_column_in?){false}
279
- @d.l([:x, :y]=>[[1,2], [3,4]].sql_array).should == '(((x = 1) AND (y = 2)) OR ((x = 3) AND (y = 4)))'
171
+ @d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).should == '(((x = 1) AND (y = 2)) OR ((x = 3) AND (y = 4)))'
280
172
  @d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).should == '(((x = 1) AND (y = 2) AND (z = 5)) OR ((x = 3) AND (y = 4) AND (z = 6)))'
281
173
  end
282
174
 
283
175
  it "should support StringExpression#+ for concatenation of SQL strings" do
284
- @d.lit(:x.sql_string + :y).should == '(x || y)'
285
- @d.lit([:x].sql_string_join + :y).should == '(x || y)'
286
- @d.lit([:x, :z].sql_string_join(' ') + :y).should == "(x || ' ' || z || y)"
176
+ @d.lit(Sequel.expr(:x).sql_string + :y).should == '(x || y)'
177
+ @d.lit(Sequel.join([:x]) + :y).should == '(x || y)'
178
+ @d.lit(Sequel.join([:x, :z], ' ') + :y).should == "(x || ' ' || z || y)"
287
179
  end
288
180
 
289
181
  it "should be supported inside blocks" do
290
- @d.l{[[:x, nil], [:y, [1,2,3]]].sql_or}.should == '((x IS NULL) OR (y IN (1, 2, 3)))'
291
- @d.l{~[[:x, nil], [:y, [1,2,3]]]}.should == '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
292
- @d.l{~(((('x'.lit - :y)/(:x + :y))*:z) <= 100)}.should == '((((x - y) / (x + y)) * z) > 100)'
293
- @d.l{{:x => :a} & {:y => :z}}.should == '((x = a) AND (y = z))'
182
+ @d.l{Sequel.or([[:x, nil], [:y, [1,2,3]]])}.should == '((x IS NULL) OR (y IN (1, 2, 3)))'
183
+ @d.l{Sequel.~([[:x, nil], [:y, [1,2,3]]])}.should == '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
184
+ @d.l{~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)}.should == '((((x - y) / (x + y)) * z) > 100)'
185
+ @d.l{Sequel.&({:x => :a}, {:y => :z})}.should == '((x = a) AND (y = z))'
294
186
  end
295
187
 
296
188
  it "should support &, |, ^, ~, <<, and >> for NumericExpressions" do
297
- @d.l(:x.sql_number & 1 > 100).should == '((x & 1) > 100)'
298
- @d.l(:x.sql_number | 1 > 100).should == '((x | 1) > 100)'
299
- @d.l(:x.sql_number ^ 1 > 100).should == '((x ^ 1) > 100)'
300
- @d.l(~:x.sql_number > 100).should == '(~x > 100)'
301
- @d.l(:x.sql_number << 1 > 100).should == '((x << 1) > 100)'
302
- @d.l(:x.sql_number >> 1 > 100).should == '((x >> 1) > 100)'
303
- @d.l((:x + 1) & 1 > 100).should == '(((x + 1) & 1) > 100)'
304
- @d.l((:x + 1) | 1 > 100).should == '(((x + 1) | 1) > 100)'
305
- @d.l((:x + 1) ^ 1 > 100).should == '(((x + 1) ^ 1) > 100)'
306
- @d.l(~(:x + 1) > 100).should == '(~(x + 1) > 100)'
307
- @d.l((:x + 1) << 1 > 100).should == '(((x + 1) << 1) > 100)'
308
- @d.l((:x + 1) >> 1 > 100).should == '(((x + 1) >> 1) > 100)'
309
- @d.l((:x + 1) & (:x + 2) > 100).should == '(((x + 1) & (x + 2)) > 100)'
189
+ @d.l(Sequel.expr(:x).sql_number & 1 > 100).should == '((x & 1) > 100)'
190
+ @d.l(Sequel.expr(:x).sql_number | 1 > 100).should == '((x | 1) > 100)'
191
+ @d.l(Sequel.expr(:x).sql_number ^ 1 > 100).should == '((x ^ 1) > 100)'
192
+ @d.l(~Sequel.expr(:x).sql_number > 100).should == '(~x > 100)'
193
+ @d.l(Sequel.expr(:x).sql_number << 1 > 100).should == '((x << 1) > 100)'
194
+ @d.l(Sequel.expr(:x).sql_number >> 1 > 100).should == '((x >> 1) > 100)'
195
+ @d.l((Sequel.expr(:x) + 1) & 1 > 100).should == '(((x + 1) & 1) > 100)'
196
+ @d.l((Sequel.expr(:x) + 1) | 1 > 100).should == '(((x + 1) | 1) > 100)'
197
+ @d.l((Sequel.expr(:x) + 1) ^ 1 > 100).should == '(((x + 1) ^ 1) > 100)'
198
+ @d.l(~(Sequel.expr(:x) + 1) > 100).should == '(~(x + 1) > 100)'
199
+ @d.l((Sequel.expr(:x) + 1) << 1 > 100).should == '(((x + 1) << 1) > 100)'
200
+ @d.l((Sequel.expr(:x) + 1) >> 1 > 100).should == '(((x + 1) >> 1) > 100)'
201
+ @d.l((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + 2) > 100).should == '(((x + 1) & (x + 2)) > 100)'
310
202
  end
311
203
 
312
204
  it "should allow using a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
313
- @d.lit((:x + 1) & (:x + '2')).should == "((x + 1) & (x || '2'))"
205
+ @d.lit((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + '2')).should == "((x + 1) & (x || '2'))"
314
206
  end
315
207
 
316
208
  it "should allow using a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
317
- @d.l(:x & (:x + '2')).should == "(x AND (x || '2'))"
209
+ @d.l(Sequel.expr(:x) & (Sequel.expr(:x) + '2')).should == "(x AND (x || '2'))"
318
210
  end
319
211
 
320
212
  it "should raise an error if attempting to invert a ComplexExpression that isn't a BooleanExpression" do
321
- proc{Sequel::SQL::BooleanExpression.invert(:x + 2)}.should raise_error(Sequel::Error)
213
+ proc{Sequel::SQL::BooleanExpression.invert(Sequel.expr(:x) + 2)}.should raise_error(Sequel::Error)
322
214
  end
323
215
 
324
216
  it "should return self on .lit" do
325
- y = :x + 1
217
+ y = Sequel.expr(:x) + 1
326
218
  y.lit.should == y
327
219
  end
328
220
 
329
221
  it "should return have .sql_literal operate like .to_s" do
330
- y = :x + 1
222
+ y = Sequel.expr(:x) + 1
331
223
  y.sql_literal(@d).should == '(x + 1)'
332
224
  y.sql_literal(@d).should == y.to_s(@d)
333
225
  y.sql_literal(@d).should == @d.literal(y)
@@ -343,12 +235,12 @@ describe "Blockless Ruby Filters" do
343
235
  end
344
236
 
345
237
  it "should support negation of SQL::Constants" do
346
- @d.l(~{:x => Sequel::NULL}).should == '(x IS NOT NULL)'
347
- @d.l(~{:x => Sequel::NOTNULL}).should == '(x IS NULL)'
348
- @d.l(~{:x => Sequel::TRUE}).should == '(x IS NOT TRUE)'
349
- @d.l(~{:x => Sequel::FALSE}).should == '(x IS NOT FALSE)'
350
- @d.l(~{:x => Sequel::SQLTRUE}).should == '(x IS NOT TRUE)'
351
- @d.l(~{:x => Sequel::SQLFALSE}).should == '(x IS NOT FALSE)'
238
+ @d.l(Sequel.~(:x => Sequel::NULL)).should == '(x IS NOT NULL)'
239
+ @d.l(Sequel.~(:x => Sequel::NOTNULL)).should == '(x IS NULL)'
240
+ @d.l(Sequel.~(:x => Sequel::TRUE)).should == '(x IS NOT TRUE)'
241
+ @d.l(Sequel.~(:x => Sequel::FALSE)).should == '(x IS NOT FALSE)'
242
+ @d.l(Sequel.~(:x => Sequel::SQLTRUE)).should == '(x IS NOT TRUE)'
243
+ @d.l(Sequel.~(:x => Sequel::SQLFALSE)).should == '(x IS NOT FALSE)'
352
244
  end
353
245
 
354
246
  it "should support direct negation of SQL::Constants" do
@@ -369,85 +261,85 @@ describe "Blockless Ruby Filters" do
369
261
  end
370
262
 
371
263
  it "should use a string concatentation for + if given a string" do
372
- @d.lit(:x + '1').should == "(x || '1')"
373
- @d.lit(:x + '1' + '1').should == "(x || '1' || '1')"
264
+ @d.lit(Sequel.expr(:x) + '1').should == "(x || '1')"
265
+ @d.lit(Sequel.expr(:x) + '1' + '1').should == "(x || '1' || '1')"
374
266
  end
375
267
 
376
268
  it "should use an addition for + if given a literal string" do
377
- @d.lit(:x + '1'.lit).should == "(x + 1)"
378
- @d.lit(:x + '1'.lit + '1'.lit).should == "(x + 1 + 1)"
269
+ @d.lit(Sequel.expr(:x) + Sequel.lit('1')).should == "(x + 1)"
270
+ @d.lit(Sequel.expr(:x) + Sequel.lit('1') + Sequel.lit('1')).should == "(x + 1 + 1)"
379
271
  end
380
272
 
381
273
  it "should use a bitwise operator for & and | if given an integer" do
382
- @d.lit(:x & 1).should == "(x & 1)"
383
- @d.lit(:x | 1).should == "(x | 1)"
384
- @d.lit(:x & 1 & 1).should == "(x & 1 & 1)"
385
- @d.lit(:x | 1 | 1).should == "(x | 1 | 1)"
274
+ @d.lit(Sequel.expr(:x) & 1).should == "(x & 1)"
275
+ @d.lit(Sequel.expr(:x) | 1).should == "(x | 1)"
276
+ @d.lit(Sequel.expr(:x) & 1 & 1).should == "(x & 1 & 1)"
277
+ @d.lit(Sequel.expr(:x) | 1 | 1).should == "(x | 1 | 1)"
386
278
  end
387
279
 
388
280
  it "should allow adding a string to an integer expression" do
389
- @d.lit(:x + 1 + 'a').should == "(x + 1 + 'a')"
281
+ @d.lit(Sequel.expr(:x) + 1 + 'a').should == "(x + 1 + 'a')"
390
282
  end
391
283
 
392
284
  it "should allow adding an integer to an string expression" do
393
- @d.lit(:x + 'a' + 1).should == "(x || 'a' || 1)"
285
+ @d.lit(Sequel.expr(:x) + 'a' + 1).should == "(x || 'a' || 1)"
394
286
  end
395
287
 
396
288
  it "should allow adding a boolean to an integer expression" do
397
- @d.lit(:x + 1 + true).should == "(x + 1 + 't')"
289
+ @d.lit(Sequel.expr(:x) + 1 + true).should == "(x + 1 + 't')"
398
290
  end
399
291
 
400
292
  it "should allow adding a boolean to an string expression" do
401
- @d.lit(:x + 'a' + true).should == "(x || 'a' || 't')"
293
+ @d.lit(Sequel.expr(:x) + 'a' + true).should == "(x || 'a' || 't')"
402
294
  end
403
295
 
404
296
  it "should allow using a boolean operation with an integer on an boolean expression" do
405
- @d.lit(:x & :a & 1).should == "(x AND a AND 1)"
297
+ @d.lit(Sequel.expr(:x) & :a & 1).should == "(x AND a AND 1)"
406
298
  end
407
299
 
408
300
  it "should allow using a boolean operation with a string on an boolean expression" do
409
- @d.lit(:x & :a & 'a').should == "(x AND a AND 'a')"
301
+ @d.lit(Sequel.expr(:x) & :a & 'a').should == "(x AND a AND 'a')"
410
302
  end
411
303
 
412
304
  it "should allowing AND of boolean expression and literal string" do
413
- @d.lit(:x & :a & 'a'.lit).should == "(x AND a AND a)"
305
+ @d.lit(Sequel.expr(:x) & :a & Sequel.lit('a')).should == "(x AND a AND a)"
414
306
  end
415
307
 
416
308
  it "should allowing + of integer expression and literal string" do
417
- @d.lit(:x + :a + 'a'.lit).should == "(x + a + a)"
309
+ @d.lit(Sequel.expr(:x) + :a + Sequel.lit('a')).should == "(x + a + a)"
418
310
  end
419
311
 
420
312
  it "should allowing + of string expression and literal string" do
421
- @d.lit(:x + 'a' + 'a'.lit).should == "(x || 'a' || a)"
313
+ @d.lit(Sequel.expr(:x) + 'a' + Sequel.lit('a')).should == "(x || 'a' || a)"
422
314
  end
423
315
 
424
316
  it "should allow sql_{string,boolean,number} methods on numeric expressions" do
425
- @d.lit((:x + 1).sql_string + 'a').should == "((x + 1) || 'a')"
426
- @d.lit((:x + 1).sql_boolean & 1).should == "((x + 1) AND 1)"
427
- @d.lit((:x + 1).sql_number + 'a').should == "(x + 1 + 'a')"
317
+ @d.lit((Sequel.expr(:x) + 1).sql_string + 'a').should == "((x + 1) || 'a')"
318
+ @d.lit((Sequel.expr(:x) + 1).sql_boolean & 1).should == "((x + 1) AND 1)"
319
+ @d.lit((Sequel.expr(:x) + 1).sql_number + 'a').should == "(x + 1 + 'a')"
428
320
  end
429
321
 
430
322
  it "should allow sql_{string,boolean,number} methods on string expressions" do
431
- @d.lit((:x + 'a').sql_string + 'a').should == "(x || 'a' || 'a')"
432
- @d.lit((:x + 'a').sql_boolean & 1).should == "((x || 'a') AND 1)"
433
- @d.lit((:x + 'a').sql_number + 'a').should == "((x || 'a') + 'a')"
323
+ @d.lit((Sequel.expr(:x) + 'a').sql_string + 'a').should == "(x || 'a' || 'a')"
324
+ @d.lit((Sequel.expr(:x) + 'a').sql_boolean & 1).should == "((x || 'a') AND 1)"
325
+ @d.lit((Sequel.expr(:x) + 'a').sql_number + 'a').should == "((x || 'a') + 'a')"
434
326
  end
435
327
 
436
328
  it "should allow sql_{string,boolean,number} methods on boolean expressions" do
437
- @d.lit((:x & :y).sql_string + 'a').should == "((x AND y) || 'a')"
438
- @d.lit((:x & :y).sql_boolean & 1).should == "(x AND y AND 1)"
439
- @d.lit((:x & :y).sql_number + 'a').should == "((x AND y) + 'a')"
329
+ @d.lit((Sequel.expr(:x) & :y).sql_string + 'a').should == "((x AND y) || 'a')"
330
+ @d.lit((Sequel.expr(:x) & :y).sql_boolean & 1).should == "(x AND y AND 1)"
331
+ @d.lit((Sequel.expr(:x) & :y).sql_number + 'a').should == "((x AND y) + 'a')"
440
332
  end
441
333
 
442
334
  it "should raise an error if trying to literalize an invalid complex expression" do
443
- ce = :x + 1
335
+ ce = Sequel.+(:x, 1)
444
336
  ce.instance_variable_set(:@op, :BANG)
445
337
  proc{@d.lit(ce)}.should raise_error(Sequel::Error)
446
338
  end
447
339
 
448
340
  it "should support equality comparison of two expressions" do
449
- e1 = ~:comment.like('%:hidden:%')
450
- e2 = ~:comment.like('%:hidden:%')
341
+ e1 = ~Sequel.like(:comment, '%:hidden:%')
342
+ e2 = ~Sequel.like(:comment, '%:hidden:%')
451
343
  e1.should == e2
452
344
  end
453
345
 
@@ -460,7 +352,7 @@ describe "Blockless Ruby Filters" do
460
352
  @d.lit(d / 1).should == '((SELECT a FROM items) / 1)'
461
353
 
462
354
  @d.lit(d => 1).should == '((SELECT a FROM items) = 1)'
463
- @d.lit(~{d => 1}).should == '((SELECT a FROM items) != 1)'
355
+ @d.lit(Sequel.~(d => 1)).should == '((SELECT a FROM items) != 1)'
464
356
  @d.lit(d > 1).should == '((SELECT a FROM items) > 1)'
465
357
  @d.lit(d < 1).should == '((SELECT a FROM items) < 1)'
466
358
  @d.lit(d >= 1).should == '((SELECT a FROM items) >= 1)'
@@ -489,46 +381,6 @@ describe "Blockless Ruby Filters" do
489
381
  @d.lit(d.like(:b)).should == '((SELECT a FROM items) LIKE b)'
490
382
  @d.lit(d.ilike(:b)).should == '((SELECT a FROM items) ILIKE b)'
491
383
  end
492
-
493
- if RUBY_VERSION < '1.9.0'
494
- it "should not allow inequality operations on true, false, or nil" do
495
- @d.lit(:x > 1).should == "(x > 1)"
496
- @d.lit(:x < true).should == "(x < 't')"
497
- @d.lit(:x >= false).should == "(x >= 'f')"
498
- @d.lit(:x <= nil).should == "(x <= NULL)"
499
- end
500
-
501
- it "should not allow inequality operations on boolean complex expressions" do
502
- @d.lit(:x > (:y > 5)).should == "(x > (y > 5))"
503
- @d.lit(:x < (:y < 5)).should == "(x < (y < 5))"
504
- @d.lit(:x >= (:y >= 5)).should == "(x >= (y >= 5))"
505
- @d.lit(:x <= (:y <= 5)).should == "(x <= (y <= 5))"
506
- @d.lit(:x > {:y => nil}).should == "(x > (y IS NULL))"
507
- @d.lit(:x < ~{:y => nil}).should == "(x < (y IS NOT NULL))"
508
- @d.lit(:x >= {:y => 5}).should == "(x >= (y = 5))"
509
- @d.lit(:x <= ~{:y => 5}).should == "(x <= (y != 5))"
510
- @d.lit(:x >= {:y => [1,2,3]}).should == "(x >= (y IN (1, 2, 3)))"
511
- @d.lit(:x <= ~{:y => [1,2,3]}).should == "(x <= (y NOT IN (1, 2, 3)))"
512
- end
513
-
514
- it "should support >, <, >=, and <= via Symbol#>,<,>=,<=" do
515
- @d.l(:x > 100).should == '(x > 100)'
516
- @d.l(:x < 100.01).should == '(x < 100.01)'
517
- @d.l(:x >= 100000000000000000000000000000000000).should == '(x >= 100000000000000000000000000000000000)'
518
- @d.l(:x <= 100).should == '(x <= 100)'
519
- end
520
-
521
- it "should support negation of >, <, >=, and <= via Symbol#~" do
522
- @d.l(~(:x > 100)).should == '(x <= 100)'
523
- @d.l(~(:x < 100.01)).should == '(x >= 100.01)'
524
- @d.l(~(:x >= 100000000000000000000000000000000000)).should == '(x < 100000000000000000000000000000000000)'
525
- @d.l(~(:x <= 100)).should == '(x > 100)'
526
- end
527
-
528
- it "should support double negation via ~" do
529
- @d.l(~~(:x > 100)).should == '(x > 100)'
530
- end
531
- end
532
384
  end
533
385
 
534
386
  describe Sequel::SQL::VirtualRow do
@@ -679,6 +531,24 @@ describe "Sequel core extension replacements" do
679
531
  @db.literal(arg).should == should
680
532
  end
681
533
 
534
+ it "Sequel.expr should return items wrapped in Sequel objects" do
535
+ Sequel.expr(1).should be_a_kind_of(Sequel::SQL::NumericExpression)
536
+ Sequel.expr('a').should be_a_kind_of(Sequel::SQL::StringExpression)
537
+ Sequel.expr(true).should be_a_kind_of(Sequel::SQL::BooleanExpression)
538
+ Sequel.expr(nil).should be_a_kind_of(Sequel::SQL::Wrapper)
539
+ Sequel.expr({1=>2}).should be_a_kind_of(Sequel::SQL::BooleanExpression)
540
+ Sequel.expr([[1, 2]]).should be_a_kind_of(Sequel::SQL::BooleanExpression)
541
+ Sequel.expr([1]).should be_a_kind_of(Sequel::SQL::Wrapper)
542
+ Sequel.expr{|o| o.should be_a_kind_of(Sequel::SQL::VirtualRow)}
543
+ Sequel.expr{self.should be_a_kind_of(Sequel::SQL::VirtualRow)}
544
+ Sequel.expr(:a).should be_a_kind_of(Sequel::SQL::Identifier)
545
+ Sequel.expr(:a__b).should be_a_kind_of(Sequel::SQL::QualifiedIdentifier)
546
+ Sequel.expr(:a___c).should be_a_kind_of(Sequel::SQL::AliasedExpression)
547
+ Sequel.expr(:a___c).expression.should be_a_kind_of(Sequel::SQL::Identifier)
548
+ Sequel.expr(:a__b___c).should be_a_kind_of(Sequel::SQL::AliasedExpression)
549
+ Sequel.expr(:a__b___c).expression.should be_a_kind_of(Sequel::SQL::QualifiedIdentifier)
550
+ end
551
+
682
552
  it "Sequel.expr should return an appropriate wrapped object" do
683
553
  l(Sequel.expr(1) + 1, "(1 + 1)")
684
554
  l(Sequel.expr('a') + 'b', "('a' || 'b')")
@@ -922,18 +792,35 @@ describe "Sequel core extension replacements" do
922
792
  it "Sequel.extract should use a date/time extraction" do
923
793
  l(Sequel.extract(:year, :a), 'extract(year FROM a)')
924
794
  end
795
+
796
+ it "#* with no arguments should use a ColumnAll for Identifier and QualifiedIdentifier" do
797
+ l(Sequel.expr(:a).*, 'a.*')
798
+ l(Sequel.expr(:a__b).*, 'a.b.*')
799
+ end
800
+
801
+ it "SQL::Blob should be aliasable and castable by default" do
802
+ b = Sequel.blob('a')
803
+ l(b.as(:a), "'a' AS a")
804
+ l(b.cast(Integer), "CAST('a' AS integer)")
805
+ end
806
+
807
+ it "SQL::Blob should be convertable to a literal string by default" do
808
+ b = Sequel.blob('a ?')
809
+ l(b.lit, "a ?")
810
+ l(b.lit(1), "a 1")
811
+ end
925
812
  end
926
813
 
927
814
  describe "Sequel::SQL::Function#==" do
928
815
  specify "should be true for functions with the same name and arguments, false otherwise" do
929
- a = :date.sql_function(:t)
930
- b = :date.sql_function(:t)
816
+ a = Sequel.function(:date, :t)
817
+ b = Sequel.function(:date, :t)
931
818
  a.should == b
932
819
  (a == b).should == true
933
- c = :date.sql_function(:c)
820
+ c = Sequel.function(:date, :c)
934
821
  a.should_not == c
935
822
  (a == c).should == false
936
- d = :time.sql_function(:c)
823
+ d = Sequel.function(:time, :c)
937
824
  a.should_not == d
938
825
  c.should_not == d
939
826
  (a == d).should == false
@@ -963,20 +850,20 @@ end
963
850
 
964
851
  describe "Expression" do
965
852
  specify "should consider objects == only if they have the same attributes" do
966
- :column.qualify(:table).cast(:type).*(:numeric_column).asc.should == :column.qualify(:table).cast(:type).*(:numeric_column).asc
967
- :other_column.qualify(:table).cast(:type).*(:numeric_column).asc.should_not == :column.qualify(:table).cast(:type).*(:numeric_column).asc
853
+ Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.should == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
854
+ Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.should_not == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
968
855
 
969
- :column.qualify(:table).cast(:type).*(:numeric_column).asc.should eql(:column.qualify(:table).cast(:type).*(:numeric_column).asc)
970
- :other_column.qualify(:table).cast(:type).*(:numeric_column).asc.should_not eql(:column.qualify(:table).cast(:type).*(:numeric_column).asc)
856
+ Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.should eql(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
857
+ Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.should_not eql(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
971
858
  end
972
859
 
973
860
  specify "should use the same hash value for objects that have the same attributes" do
974
- :column.qualify(:table).cast(:type).*(:numeric_column).asc.hash.should == :column.qualify(:table).cast(:type).*(:numeric_column).asc.hash
975
- :other_column.qualify(:table).cast(:type).*(:numeric_column).asc.hash.should_not == :column.qualify(:table).cast(:type).*(:numeric_column).asc.hash
861
+ Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash.should == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
862
+ Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.hash.should_not == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
976
863
 
977
864
  h = {}
978
- a = :column.qualify(:table).cast(:type).*(:numeric_column).asc
979
- b = :column.qualify(:table).cast(:type).*(:numeric_column).asc
865
+ a = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
866
+ b = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
980
867
  h[a] = 1
981
868
  h[b] = 2
982
869
  h[a].should == 2