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.
- 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
|