sequel 3.37.0 → 3.38.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +56 -0
- data/README.rdoc +82 -58
- data/Rakefile +6 -5
- data/bin/sequel +1 -1
- data/doc/active_record.rdoc +67 -52
- data/doc/advanced_associations.rdoc +33 -48
- data/doc/association_basics.rdoc +41 -51
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +47 -43
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +4 -5
- data/doc/model_hooks.rdoc +3 -3
- data/doc/object_model.rdoc +31 -25
- data/doc/opening_databases.rdoc +19 -5
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/querying.rdoc +109 -52
- data/doc/reflection.rdoc +6 -6
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/schema_modification.rdoc +22 -13
- data/doc/sharding.rdoc +8 -9
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +47 -7
- data/doc/thread_safety.rdoc +1 -1
- data/doc/transactions.rdoc +1 -1
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +29 -43
- data/lib/sequel/adapters/do/postgres.rb +1 -4
- data/lib/sequel/adapters/jdbc.rb +14 -3
- data/lib/sequel/adapters/jdbc/db2.rb +9 -0
- data/lib/sequel/adapters/jdbc/derby.rb +41 -4
- data/lib/sequel/adapters/jdbc/jtds.rb +11 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -6
- data/lib/sequel/adapters/mock.rb +10 -4
- data/lib/sequel/adapters/postgres.rb +1 -28
- data/lib/sequel/adapters/shared/mssql.rb +23 -13
- data/lib/sequel/adapters/shared/postgres.rb +46 -0
- data/lib/sequel/adapters/swift.rb +21 -13
- data/lib/sequel/adapters/swift/mysql.rb +1 -0
- data/lib/sequel/adapters/swift/postgres.rb +4 -5
- data/lib/sequel/adapters/swift/sqlite.rb +2 -1
- data/lib/sequel/adapters/tinytds.rb +14 -2
- data/lib/sequel/adapters/utils/pg_types.rb +5 -0
- data/lib/sequel/core.rb +29 -17
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +3 -0
- data/lib/sequel/dataset/actions.rb +5 -6
- data/lib/sequel/dataset/query.rb +7 -7
- data/lib/sequel/dataset/sql.rb +5 -18
- data/lib/sequel/extensions/core_extensions.rb +8 -12
- data/lib/sequel/extensions/pg_array.rb +59 -33
- data/lib/sequel/extensions/pg_array_ops.rb +32 -4
- data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -1
- data/lib/sequel/extensions/pg_hstore.rb +32 -17
- data/lib/sequel/extensions/pg_hstore_ops.rb +32 -3
- data/lib/sequel/extensions/pg_inet.rb +1 -2
- data/lib/sequel/extensions/pg_interval.rb +0 -1
- data/lib/sequel/extensions/pg_json.rb +41 -23
- data/lib/sequel/extensions/pg_range.rb +36 -11
- data/lib/sequel/extensions/pg_range_ops.rb +32 -4
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +164 -0
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/schema_dumper.rb +7 -8
- data/lib/sequel/extensions/select_remove.rb +1 -1
- data/lib/sequel/model/base.rb +1 -0
- data/lib/sequel/no_core_ext.rb +1 -1
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/validation_helpers.rb +31 -0
- data/lib/sequel/sql.rb +64 -44
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +37 -12
- data/spec/adapters/mysql_spec.rb +39 -75
- data/spec/adapters/oracle_spec.rb +11 -11
- data/spec/adapters/postgres_spec.rb +414 -237
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +14 -14
- data/spec/core/database_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +169 -205
- data/spec/core/expression_filters_spec.rb +182 -295
- data/spec/core/object_graph_spec.rb +6 -6
- data/spec/core/schema_spec.rb +14 -14
- data/spec/core/spec_helper.rb +1 -0
- data/spec/{extensions/core_extensions_spec.rb → core_extensions_spec.rb} +208 -14
- data/spec/extensions/columns_introspection_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +28 -36
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/pg_array_ops_spec.rb +15 -7
- data/spec/extensions/pg_array_spec.rb +81 -48
- data/spec/extensions/pg_auto_parameterize_spec.rb +2 -2
- data/spec/extensions/pg_hstore_ops_spec.rb +13 -9
- data/spec/extensions/pg_hstore_spec.rb +66 -65
- data/spec/extensions/pg_inet_spec.rb +2 -4
- data/spec/extensions/pg_interval_spec.rb +2 -3
- data/spec/extensions/pg_json_spec.rb +20 -18
- data/spec/extensions/pg_range_ops_spec.rb +11 -4
- data/spec/extensions/pg_range_spec.rb +30 -7
- data/spec/extensions/pg_row_ops_spec.rb +48 -0
- data/spec/extensions/pg_row_plugin_spec.rb +45 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/query_literals_spec.rb +11 -11
- data/spec/extensions/query_spec.rb +3 -3
- data/spec/extensions/schema_dumper_spec.rb +20 -4
- data/spec/extensions/schema_spec.rb +18 -41
- data/spec/extensions/select_remove_spec.rb +4 -4
- data/spec/extensions/spec_helper.rb +4 -8
- data/spec/extensions/to_dot_spec.rb +5 -5
- data/spec/extensions/validation_class_methods_spec.rb +28 -16
- data/spec/integration/associations_test.rb +20 -20
- data/spec/integration/dataset_test.rb +98 -98
- data/spec/integration/eager_loader_test.rb +13 -27
- data/spec/integration/plugin_test.rb +5 -5
- data/spec/integration/prepared_statement_test.rb +22 -13
- data/spec/integration/schema_test.rb +28 -18
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/integration/timezone_test.rb +2 -2
- data/spec/integration/type_test.rb +15 -6
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +4 -4
- data/spec/model/base_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +15 -15
- data/spec/model/model_spec.rb +32 -32
- data/spec/model/record_spec.rb +16 -0
- data/spec/model/spec_helper.rb +2 -6
- data/spec/model/validations_spec.rb +1 -1
- 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(
|
33
|
-
@d.l(
|
34
|
-
@d.l(
|
35
|
-
@d.l(
|
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(
|
40
|
-
@d.l(
|
41
|
-
@d.l(~~(:x
|
42
|
-
@d.l(~~(:x
|
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(~
|
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(~
|
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
|
63
|
-
@d.l(~
|
64
|
-
@d.l(~
|
65
|
-
@d.l(~
|
66
|
-
@d.l(~
|
67
|
-
@d.l(~
|
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
|
75
|
-
@d.l(~
|
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
|
79
|
-
@d.l(:x
|
80
|
-
@d.l(:x
|
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
|
176
|
-
@d.l(~
|
177
|
-
@d.l(~
|
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{
|
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]
|
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 -
|
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 -
|
207
|
-
@d.lit([:x,
|
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 &
|
217
|
-
@d.l(
|
218
|
-
@d.l(
|
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'
|
244
|
-
@d.l(~'x'
|
245
|
-
@d.l(~~'x'
|
246
|
-
@d.l(~(('x'
|
247
|
-
@d.l(~(:x | 'y'
|
248
|
-
@d.l(~('x'
|
249
|
-
@d.l(
|
250
|
-
@d.l(('x'
|
251
|
-
@d.l(~('x'
|
252
|
-
@d.l('x'.
|
253
|
-
@d.l('x'
|
254
|
-
@d.l(('x'
|
255
|
-
@d.l(('x'
|
256
|
-
@d.l(('z'
|
257
|
-
@d.l(~(((('x'
|
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]]
|
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]]
|
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]
|
286
|
-
@d.lit([:x, :z]
|
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]]]
|
291
|
-
@d.l{
|
292
|
-
@d.l{~(((('x'
|
293
|
-
@d.l{{:x => :a}
|
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(
|
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(
|
347
|
-
@d.l(
|
348
|
-
@d.l(
|
349
|
-
@d.l(
|
350
|
-
@d.l(
|
351
|
-
@d.l(
|
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'
|
378
|
-
@d.lit(:x + '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'
|
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'
|
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'
|
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
|
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 =
|
450
|
-
e2 =
|
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(
|
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 =
|
930
|
-
b =
|
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 =
|
820
|
+
c = Sequel.function(:date, :c)
|
934
821
|
a.should_not == c
|
935
822
|
(a == c).should == false
|
936
|
-
d =
|
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
|
-
|
967
|
-
|
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
|
-
|
970
|
-
|
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
|
-
|
975
|
-
|
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 =
|
979
|
-
b =
|
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
|