arel 6.0.0.beta2 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/History.txt +1 -1
  3. data/README.markdown +5 -5
  4. data/lib/arel.rb +1 -1
  5. data/lib/arel/collectors/sql_string.rb +7 -1
  6. data/lib/arel/expressions.rb +5 -4
  7. data/lib/arel/nodes.rb +1 -0
  8. data/lib/arel/nodes/bind_param.rb +6 -0
  9. data/lib/arel/nodes/sql_literal.rb +0 -3
  10. data/lib/arel/predications.rb +2 -2
  11. data/lib/arel/visitors/depth_first.rb +6 -0
  12. data/lib/arel/visitors/oracle.rb +4 -0
  13. data/lib/arel/visitors/postgresql.rb +4 -0
  14. data/lib/arel/visitors/reduce.rb +4 -4
  15. data/lib/arel/visitors/to_sql.rb +3 -2
  16. data/lib/arel/visitors/visitor.rb +15 -15
  17. metadata +26 -69
  18. data/.gitignore +0 -9
  19. data/.travis.yml +0 -18
  20. data/Gemfile +0 -5
  21. data/Rakefile +0 -15
  22. data/arel.gemspec +0 -24
  23. data/test/attributes/test_attribute.rb +0 -910
  24. data/test/collectors/test_bind_collector.rb +0 -70
  25. data/test/collectors/test_sql_string.rb +0 -38
  26. data/test/helper.rb +0 -22
  27. data/test/nodes/test_and.rb +0 -20
  28. data/test/nodes/test_as.rb +0 -34
  29. data/test/nodes/test_ascending.rb +0 -44
  30. data/test/nodes/test_bin.rb +0 -33
  31. data/test/nodes/test_binary.rb +0 -26
  32. data/test/nodes/test_count.rb +0 -33
  33. data/test/nodes/test_delete_statement.rb +0 -34
  34. data/test/nodes/test_descending.rb +0 -44
  35. data/test/nodes/test_distinct.rb +0 -20
  36. data/test/nodes/test_equality.rb +0 -84
  37. data/test/nodes/test_extract.rb +0 -41
  38. data/test/nodes/test_false.rb +0 -20
  39. data/test/nodes/test_grouping.rb +0 -25
  40. data/test/nodes/test_infix_operation.rb +0 -40
  41. data/test/nodes/test_insert_statement.rb +0 -42
  42. data/test/nodes/test_named_function.rb +0 -46
  43. data/test/nodes/test_node.rb +0 -39
  44. data/test/nodes/test_not.rb +0 -29
  45. data/test/nodes/test_or.rb +0 -34
  46. data/test/nodes/test_over.rb +0 -67
  47. data/test/nodes/test_select_core.rb +0 -69
  48. data/test/nodes/test_select_statement.rb +0 -49
  49. data/test/nodes/test_sql_literal.rb +0 -73
  50. data/test/nodes/test_sum.rb +0 -24
  51. data/test/nodes/test_table_alias.rb +0 -36
  52. data/test/nodes/test_true.rb +0 -21
  53. data/test/nodes/test_update_statement.rb +0 -58
  54. data/test/nodes/test_window.rb +0 -79
  55. data/test/support/fake_record.rb +0 -135
  56. data/test/test_attributes.rb +0 -66
  57. data/test/test_crud.rb +0 -63
  58. data/test/test_delete_manager.rb +0 -42
  59. data/test/test_factory_methods.rb +0 -44
  60. data/test/test_insert_manager.rb +0 -171
  61. data/test/test_select_manager.rb +0 -1181
  62. data/test/test_table.rb +0 -253
  63. data/test/test_update_manager.rb +0 -124
  64. data/test/visitors/test_bind_visitor.rb +0 -60
  65. data/test/visitors/test_depth_first.rb +0 -258
  66. data/test/visitors/test_dispatch_contamination.rb +0 -22
  67. data/test/visitors/test_dot.rb +0 -76
  68. data/test/visitors/test_ibm_db.rb +0 -33
  69. data/test/visitors/test_informix.rb +0 -58
  70. data/test/visitors/test_mssql.rb +0 -70
  71. data/test/visitors/test_mysql.rb +0 -60
  72. data/test/visitors/test_oracle.rb +0 -170
  73. data/test/visitors/test_postgres.rb +0 -122
  74. data/test/visitors/test_sqlite.rb +0 -23
  75. data/test/visitors/test_to_sql.rb +0 -598
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- coverage/*
2
- config/database.yml
3
- spec/support/fixtures/*database*
4
- *.DS_Store
5
- debug.log
6
- pkg
7
- .bundle
8
- *.swp
9
- Gemfile.lock
@@ -1,18 +0,0 @@
1
- language: ruby
2
- script:
3
- - "rake test"
4
- - "gem build arel.gemspec"
5
- rvm:
6
- - rbx
7
- - jruby
8
- - 1.9.3
9
- - 2.0.0
10
- - 2.1
11
- - ruby-head
12
- matrix:
13
- allow_failures:
14
- - rvm: rbx
15
- notifications:
16
- email: false
17
- irc:
18
- - "irc.freenode.org#rails-contrib"
data/Gemfile DELETED
@@ -1,5 +0,0 @@
1
- source "https://rubygems.org/"
2
-
3
- gemspec
4
-
5
- gem 'rake'
data/Rakefile DELETED
@@ -1,15 +0,0 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
3
-
4
- specname = "arel.gemspec"
5
- deps = `git ls-files`.split("\n") - [specname]
6
-
7
- file specname => deps do
8
- files = `git ls-files`.split("\n") - ["#{specname}.erb"]
9
-
10
- require 'erb'
11
-
12
- File.open specname, 'w:utf-8' do |f|
13
- f.write ERB.new(File.read("#{specname}.erb")).result(binding)
14
- end
15
- end
@@ -1,24 +0,0 @@
1
- # # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "arel"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "arel"
7
- s.version = Arel::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ["Aaron Patterson", "Bryan Helmkamp", "Emilio Tagua", "Nick Kallen"]
10
- s.email = ["aaron@tenderlovemaking.com", "bryan@brynary.com", "miloops@gmail.com"]
11
- s.homepage = "https://github.com/rails/arel"
12
- s.description = "Arel Really Exasperates Logicians\n\nArel is a SQL AST manager for Ruby. It\n\n1. Simplifies the generation of complex SQL queries\n2. Adapts to various RDBMSes\n\nIt is intended to be a framework framework; that is, you can build your own ORM\nwith it, focusing on innovative object and collection modeling as opposed to\ndatabase compatibility and query generation."
13
- s.summary = "Arel Really Exasperates Logicians Arel is a SQL AST manager for Ruby"
14
- s.license = %q{MIT}
15
-
16
- s.rdoc_options = ["--main", "README.markdown"]
17
- s.extra_rdoc_files = ["History.txt", "MIT-LICENSE.txt", "README.markdown"]
18
-
19
- s.files = [".gitignore",".travis.yml","Gemfile","History.txt","MIT-LICENSE.txt","README.markdown","Rakefile","arel.gemspec","lib/arel.rb","lib/arel/alias_predication.rb","lib/arel/attributes.rb","lib/arel/attributes/attribute.rb","lib/arel/collectors/bind.rb","lib/arel/collectors/plain_string.rb","lib/arel/collectors/sql_string.rb","lib/arel/compatibility/wheres.rb","lib/arel/crud.rb","lib/arel/delete_manager.rb","lib/arel/expressions.rb","lib/arel/factory_methods.rb","lib/arel/insert_manager.rb","lib/arel/math.rb","lib/arel/nodes.rb","lib/arel/nodes/and.rb","lib/arel/nodes/ascending.rb","lib/arel/nodes/binary.rb","lib/arel/nodes/count.rb","lib/arel/nodes/delete_statement.rb","lib/arel/nodes/descending.rb","lib/arel/nodes/equality.rb","lib/arel/nodes/extract.rb","lib/arel/nodes/false.rb","lib/arel/nodes/full_outer_join.rb","lib/arel/nodes/function.rb","lib/arel/nodes/grouping.rb","lib/arel/nodes/in.rb","lib/arel/nodes/infix_operation.rb","lib/arel/nodes/inner_join.rb","lib/arel/nodes/insert_statement.rb","lib/arel/nodes/join_source.rb","lib/arel/nodes/matches.rb","lib/arel/nodes/named_function.rb","lib/arel/nodes/node.rb","lib/arel/nodes/outer_join.rb","lib/arel/nodes/over.rb","lib/arel/nodes/right_outer_join.rb","lib/arel/nodes/select_core.rb","lib/arel/nodes/select_statement.rb","lib/arel/nodes/sql_literal.rb","lib/arel/nodes/string_join.rb","lib/arel/nodes/table_alias.rb","lib/arel/nodes/terminal.rb","lib/arel/nodes/true.rb","lib/arel/nodes/unary.rb","lib/arel/nodes/unqualified_column.rb","lib/arel/nodes/update_statement.rb","lib/arel/nodes/values.rb","lib/arel/nodes/window.rb","lib/arel/nodes/with.rb","lib/arel/order_predications.rb","lib/arel/predications.rb","lib/arel/select_manager.rb","lib/arel/table.rb","lib/arel/tree_manager.rb","lib/arel/update_manager.rb","lib/arel/visitors.rb","lib/arel/visitors/bind_substitute.rb","lib/arel/visitors/bind_visitor.rb","lib/arel/visitors/depth_first.rb","lib/arel/visitors/dot.rb","lib/arel/visitors/ibm_db.rb","lib/arel/visitors/informix.rb","lib/arel/visitors/mssql.rb","lib/arel/visitors/mysql.rb","lib/arel/visitors/oracle.rb","lib/arel/visitors/postgresql.rb","lib/arel/visitors/reduce.rb","lib/arel/visitors/sqlite.rb","lib/arel/visitors/to_sql.rb","lib/arel/visitors/visitor.rb","lib/arel/visitors/where_sql.rb","lib/arel/window_predications.rb","test/attributes/test_attribute.rb","test/collectors/test_bind_collector.rb","test/collectors/test_sql_string.rb","test/helper.rb","test/nodes/test_and.rb","test/nodes/test_as.rb","test/nodes/test_ascending.rb","test/nodes/test_bin.rb","test/nodes/test_binary.rb","test/nodes/test_count.rb","test/nodes/test_delete_statement.rb","test/nodes/test_descending.rb","test/nodes/test_distinct.rb","test/nodes/test_equality.rb","test/nodes/test_extract.rb","test/nodes/test_false.rb","test/nodes/test_grouping.rb","test/nodes/test_infix_operation.rb","test/nodes/test_insert_statement.rb","test/nodes/test_named_function.rb","test/nodes/test_node.rb","test/nodes/test_not.rb","test/nodes/test_or.rb","test/nodes/test_over.rb","test/nodes/test_select_core.rb","test/nodes/test_select_statement.rb","test/nodes/test_sql_literal.rb","test/nodes/test_sum.rb","test/nodes/test_table_alias.rb","test/nodes/test_true.rb","test/nodes/test_update_statement.rb","test/nodes/test_window.rb","test/support/fake_record.rb","test/test_attributes.rb","test/test_crud.rb","test/test_delete_manager.rb","test/test_factory_methods.rb","test/test_insert_manager.rb","test/test_select_manager.rb","test/test_table.rb","test/test_update_manager.rb","test/visitors/test_bind_visitor.rb","test/visitors/test_depth_first.rb","test/visitors/test_dispatch_contamination.rb","test/visitors/test_dot.rb","test/visitors/test_ibm_db.rb","test/visitors/test_informix.rb","test/visitors/test_mssql.rb","test/visitors/test_mysql.rb","test/visitors/test_oracle.rb","test/visitors/test_postgres.rb","test/visitors/test_sqlite.rb","test/visitors/test_to_sql.rb"]
20
- s.require_paths = ["lib"]
21
-
22
- s.add_development_dependency('minitest', '~> 5.4')
23
- s.add_development_dependency('rdoc', '~> 4.0')
24
- end
@@ -1,910 +0,0 @@
1
- require 'helper'
2
-
3
- module Arel
4
- module Attributes
5
- describe 'attribute' do
6
- describe '#not_eq' do
7
- it 'should create a NotEqual node' do
8
- relation = Table.new(:users)
9
- relation[:id].not_eq(10).must_be_kind_of Nodes::NotEqual
10
- end
11
-
12
- it 'should generate != in sql' do
13
- relation = Table.new(:users)
14
- mgr = relation.project relation[:id]
15
- mgr.where relation[:id].not_eq(10)
16
- mgr.to_sql.must_be_like %{
17
- SELECT "users"."id" FROM "users" WHERE "users"."id" != 10
18
- }
19
- end
20
-
21
- it 'should handle nil' do
22
- relation = Table.new(:users)
23
- mgr = relation.project relation[:id]
24
- mgr.where relation[:id].not_eq(nil)
25
- mgr.to_sql.must_be_like %{
26
- SELECT "users"."id" FROM "users" WHERE "users"."id" IS NOT NULL
27
- }
28
- end
29
- end
30
-
31
- describe '#not_eq_any' do
32
- it 'should create a Grouping node' do
33
- relation = Table.new(:users)
34
- relation[:id].not_eq_any([1,2]).must_be_kind_of Nodes::Grouping
35
- end
36
-
37
- it 'should generate ORs in sql' do
38
- relation = Table.new(:users)
39
- mgr = relation.project relation[:id]
40
- mgr.where relation[:id].not_eq_any([1,2])
41
- mgr.to_sql.must_be_like %{
42
- SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 OR "users"."id" != 2)
43
- }
44
- end
45
- end
46
-
47
- describe '#not_eq_all' do
48
- it 'should create a Grouping node' do
49
- relation = Table.new(:users)
50
- relation[:id].not_eq_all([1,2]).must_be_kind_of Nodes::Grouping
51
- end
52
-
53
- it 'should generate ANDs in sql' do
54
- relation = Table.new(:users)
55
- mgr = relation.project relation[:id]
56
- mgr.where relation[:id].not_eq_all([1,2])
57
- mgr.to_sql.must_be_like %{
58
- SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 AND "users"."id" != 2)
59
- }
60
- end
61
- end
62
-
63
- describe '#gt' do
64
- it 'should create a GreaterThan node' do
65
- relation = Table.new(:users)
66
- relation[:id].gt(10).must_be_kind_of Nodes::GreaterThan
67
- end
68
-
69
- it 'should generate > in sql' do
70
- relation = Table.new(:users)
71
- mgr = relation.project relation[:id]
72
- mgr.where relation[:id].gt(10)
73
- mgr.to_sql.must_be_like %{
74
- SELECT "users"."id" FROM "users" WHERE "users"."id" > 10
75
- }
76
- end
77
-
78
- it 'should handle comparing with a subquery' do
79
- users = Table.new(:users)
80
-
81
- avg = users.project(users[:karma].average)
82
- mgr = users.project(Arel.star).where(users[:karma].gt(avg))
83
-
84
- mgr.to_sql.must_be_like %{
85
- SELECT * FROM "users" WHERE "users"."karma" > (SELECT AVG("users"."karma") AS avg_id FROM "users")
86
- }
87
- end
88
-
89
- it 'should accept various data types.' do
90
- relation = Table.new(:users)
91
- mgr = relation.project relation[:id]
92
- mgr.where relation[:name].gt('fake_name')
93
- mgr.to_sql.must_match %{"users"."name" > 'fake_name'}
94
-
95
- current_time = ::Time.now
96
- mgr.where relation[:created_at].gt(current_time)
97
- mgr.to_sql.must_match %{"users"."created_at" > '#{current_time}'}
98
- end
99
- end
100
-
101
- describe '#gt_any' do
102
- it 'should create a Grouping node' do
103
- relation = Table.new(:users)
104
- relation[:id].gt_any([1,2]).must_be_kind_of Nodes::Grouping
105
- end
106
-
107
- it 'should generate ORs in sql' do
108
- relation = Table.new(:users)
109
- mgr = relation.project relation[:id]
110
- mgr.where relation[:id].gt_any([1,2])
111
- mgr.to_sql.must_be_like %{
112
- SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 OR "users"."id" > 2)
113
- }
114
- end
115
- end
116
-
117
- describe '#gt_all' do
118
- it 'should create a Grouping node' do
119
- relation = Table.new(:users)
120
- relation[:id].gt_all([1,2]).must_be_kind_of Nodes::Grouping
121
- end
122
-
123
- it 'should generate ANDs in sql' do
124
- relation = Table.new(:users)
125
- mgr = relation.project relation[:id]
126
- mgr.where relation[:id].gt_all([1,2])
127
- mgr.to_sql.must_be_like %{
128
- SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 AND "users"."id" > 2)
129
- }
130
- end
131
- end
132
-
133
- describe '#gteq' do
134
- it 'should create a GreaterThanOrEqual node' do
135
- relation = Table.new(:users)
136
- relation[:id].gteq(10).must_be_kind_of Nodes::GreaterThanOrEqual
137
- end
138
-
139
- it 'should generate >= in sql' do
140
- relation = Table.new(:users)
141
- mgr = relation.project relation[:id]
142
- mgr.where relation[:id].gteq(10)
143
- mgr.to_sql.must_be_like %{
144
- SELECT "users"."id" FROM "users" WHERE "users"."id" >= 10
145
- }
146
- end
147
-
148
- it 'should accept various data types.' do
149
- relation = Table.new(:users)
150
- mgr = relation.project relation[:id]
151
- mgr.where relation[:name].gteq('fake_name')
152
- mgr.to_sql.must_match %{"users"."name" >= 'fake_name'}
153
-
154
- current_time = ::Time.now
155
- mgr.where relation[:created_at].gteq(current_time)
156
- mgr.to_sql.must_match %{"users"."created_at" >= '#{current_time}'}
157
- end
158
- end
159
-
160
- describe '#gteq_any' do
161
- it 'should create a Grouping node' do
162
- relation = Table.new(:users)
163
- relation[:id].gteq_any([1,2]).must_be_kind_of Nodes::Grouping
164
- end
165
-
166
- it 'should generate ORs in sql' do
167
- relation = Table.new(:users)
168
- mgr = relation.project relation[:id]
169
- mgr.where relation[:id].gteq_any([1,2])
170
- mgr.to_sql.must_be_like %{
171
- SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 OR "users"."id" >= 2)
172
- }
173
- end
174
- end
175
-
176
- describe '#gteq_all' do
177
- it 'should create a Grouping node' do
178
- relation = Table.new(:users)
179
- relation[:id].gteq_all([1,2]).must_be_kind_of Nodes::Grouping
180
- end
181
-
182
- it 'should generate ANDs in sql' do
183
- relation = Table.new(:users)
184
- mgr = relation.project relation[:id]
185
- mgr.where relation[:id].gteq_all([1,2])
186
- mgr.to_sql.must_be_like %{
187
- SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 AND "users"."id" >= 2)
188
- }
189
- end
190
- end
191
-
192
- describe '#lt' do
193
- it 'should create a LessThan node' do
194
- relation = Table.new(:users)
195
- relation[:id].lt(10).must_be_kind_of Nodes::LessThan
196
- end
197
-
198
- it 'should generate < in sql' do
199
- relation = Table.new(:users)
200
- mgr = relation.project relation[:id]
201
- mgr.where relation[:id].lt(10)
202
- mgr.to_sql.must_be_like %{
203
- SELECT "users"."id" FROM "users" WHERE "users"."id" < 10
204
- }
205
- end
206
-
207
- it 'should accept various data types.' do
208
- relation = Table.new(:users)
209
- mgr = relation.project relation[:id]
210
- mgr.where relation[:name].lt('fake_name')
211
- mgr.to_sql.must_match %{"users"."name" < 'fake_name'}
212
-
213
- current_time = ::Time.now
214
- mgr.where relation[:created_at].lt(current_time)
215
- mgr.to_sql.must_match %{"users"."created_at" < '#{current_time}'}
216
- end
217
- end
218
-
219
- describe '#lt_any' do
220
- it 'should create a Grouping node' do
221
- relation = Table.new(:users)
222
- relation[:id].lt_any([1,2]).must_be_kind_of Nodes::Grouping
223
- end
224
-
225
- it 'should generate ORs in sql' do
226
- relation = Table.new(:users)
227
- mgr = relation.project relation[:id]
228
- mgr.where relation[:id].lt_any([1,2])
229
- mgr.to_sql.must_be_like %{
230
- SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 OR "users"."id" < 2)
231
- }
232
- end
233
- end
234
-
235
- describe '#lt_all' do
236
- it 'should create a Grouping node' do
237
- relation = Table.new(:users)
238
- relation[:id].lt_all([1,2]).must_be_kind_of Nodes::Grouping
239
- end
240
-
241
- it 'should generate ANDs in sql' do
242
- relation = Table.new(:users)
243
- mgr = relation.project relation[:id]
244
- mgr.where relation[:id].lt_all([1,2])
245
- mgr.to_sql.must_be_like %{
246
- SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 AND "users"."id" < 2)
247
- }
248
- end
249
- end
250
-
251
- describe '#lteq' do
252
- it 'should create a LessThanOrEqual node' do
253
- relation = Table.new(:users)
254
- relation[:id].lteq(10).must_be_kind_of Nodes::LessThanOrEqual
255
- end
256
-
257
- it 'should generate <= in sql' do
258
- relation = Table.new(:users)
259
- mgr = relation.project relation[:id]
260
- mgr.where relation[:id].lteq(10)
261
- mgr.to_sql.must_be_like %{
262
- SELECT "users"."id" FROM "users" WHERE "users"."id" <= 10
263
- }
264
- end
265
-
266
- it 'should accept various data types.' do
267
- relation = Table.new(:users)
268
- mgr = relation.project relation[:id]
269
- mgr.where relation[:name].lteq('fake_name')
270
- mgr.to_sql.must_match %{"users"."name" <= 'fake_name'}
271
-
272
- current_time = ::Time.now
273
- mgr.where relation[:created_at].lteq(current_time)
274
- mgr.to_sql.must_match %{"users"."created_at" <= '#{current_time}'}
275
- end
276
- end
277
-
278
- describe '#lteq_any' do
279
- it 'should create a Grouping node' do
280
- relation = Table.new(:users)
281
- relation[:id].lteq_any([1,2]).must_be_kind_of Nodes::Grouping
282
- end
283
-
284
- it 'should generate ORs in sql' do
285
- relation = Table.new(:users)
286
- mgr = relation.project relation[:id]
287
- mgr.where relation[:id].lteq_any([1,2])
288
- mgr.to_sql.must_be_like %{
289
- SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 OR "users"."id" <= 2)
290
- }
291
- end
292
- end
293
-
294
- describe '#lteq_all' do
295
- it 'should create a Grouping node' do
296
- relation = Table.new(:users)
297
- relation[:id].lteq_all([1,2]).must_be_kind_of Nodes::Grouping
298
- end
299
-
300
- it 'should generate ANDs in sql' do
301
- relation = Table.new(:users)
302
- mgr = relation.project relation[:id]
303
- mgr.where relation[:id].lteq_all([1,2])
304
- mgr.to_sql.must_be_like %{
305
- SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 AND "users"."id" <= 2)
306
- }
307
- end
308
- end
309
-
310
- describe '#average' do
311
- it 'should create a AVG node' do
312
- relation = Table.new(:users)
313
- relation[:id].average.must_be_kind_of Nodes::Avg
314
- end
315
-
316
- # FIXME: backwards compat. Is this really necessary?
317
- it 'should set the alias to "avg_id"' do
318
- relation = Table.new(:users)
319
- mgr = relation.project relation[:id].average
320
- mgr.to_sql.must_be_like %{
321
- SELECT AVG("users"."id") AS avg_id
322
- FROM "users"
323
- }
324
- end
325
- end
326
-
327
- describe '#maximum' do
328
- it 'should create a MAX node' do
329
- relation = Table.new(:users)
330
- relation[:id].maximum.must_be_kind_of Nodes::Max
331
- end
332
-
333
- # FIXME: backwards compat. Is this really necessary?
334
- it 'should set the alias to "max_id"' do
335
- relation = Table.new(:users)
336
- mgr = relation.project relation[:id].maximum
337
- mgr.to_sql.must_be_like %{
338
- SELECT MAX("users"."id") AS max_id
339
- FROM "users"
340
- }
341
- end
342
- end
343
-
344
- describe '#minimum' do
345
- it 'should create a Min node' do
346
- relation = Table.new(:users)
347
- relation[:id].minimum.must_be_kind_of Nodes::Min
348
- end
349
- end
350
-
351
- describe '#sum' do
352
- it 'should create a SUM node' do
353
- relation = Table.new(:users)
354
- relation[:id].sum.must_be_kind_of Nodes::Sum
355
- end
356
-
357
- # FIXME: backwards compat. Is this really necessary?
358
- it 'should set the alias to "sum_id"' do
359
- relation = Table.new(:users)
360
- mgr = relation.project relation[:id].sum
361
- mgr.to_sql.must_be_like %{
362
- SELECT SUM("users"."id") AS sum_id
363
- FROM "users"
364
- }
365
- end
366
- end
367
-
368
- describe '#count' do
369
- it 'should return a count node' do
370
- relation = Table.new(:users)
371
- relation[:id].count.must_be_kind_of Nodes::Count
372
- end
373
-
374
- it 'should take a distinct param' do
375
- relation = Table.new(:users)
376
- count = relation[:id].count(nil)
377
- count.must_be_kind_of Nodes::Count
378
- count.distinct.must_be_nil
379
- end
380
- end
381
-
382
- describe '#eq' do
383
- it 'should return an equality node' do
384
- attribute = Attribute.new nil, nil
385
- equality = attribute.eq 1
386
- equality.left.must_equal attribute
387
- equality.right.val.must_equal 1
388
- equality.must_be_kind_of Nodes::Equality
389
- end
390
-
391
- it 'should generate = in sql' do
392
- relation = Table.new(:users)
393
- mgr = relation.project relation[:id]
394
- mgr.where relation[:id].eq(10)
395
- mgr.to_sql.must_be_like %{
396
- SELECT "users"."id" FROM "users" WHERE "users"."id" = 10
397
- }
398
- end
399
-
400
- it 'should handle nil' do
401
- relation = Table.new(:users)
402
- mgr = relation.project relation[:id]
403
- mgr.where relation[:id].eq(nil)
404
- mgr.to_sql.must_be_like %{
405
- SELECT "users"."id" FROM "users" WHERE "users"."id" IS NULL
406
- }
407
- end
408
- end
409
-
410
- describe '#eq_any' do
411
- it 'should create a Grouping node' do
412
- relation = Table.new(:users)
413
- relation[:id].eq_any([1,2]).must_be_kind_of Nodes::Grouping
414
- end
415
-
416
- it 'should generate ORs in sql' do
417
- relation = Table.new(:users)
418
- mgr = relation.project relation[:id]
419
- mgr.where relation[:id].eq_any([1,2])
420
- mgr.to_sql.must_be_like %{
421
- SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 OR "users"."id" = 2)
422
- }
423
- end
424
-
425
- it 'should not eat input' do
426
- relation = Table.new(:users)
427
- mgr = relation.project relation[:id]
428
- values = [1,2]
429
- mgr.where relation[:id].eq_any(values)
430
- values.must_equal [1,2]
431
- end
432
- end
433
-
434
- describe '#eq_all' do
435
- it 'should create a Grouping node' do
436
- relation = Table.new(:users)
437
- relation[:id].eq_all([1,2]).must_be_kind_of Nodes::Grouping
438
- end
439
-
440
- it 'should generate ANDs in sql' do
441
- relation = Table.new(:users)
442
- mgr = relation.project relation[:id]
443
- mgr.where relation[:id].eq_all([1,2])
444
- mgr.to_sql.must_be_like %{
445
- SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
446
- }
447
- end
448
-
449
- it 'should not eat input' do
450
- relation = Table.new(:users)
451
- mgr = relation.project relation[:id]
452
- values = [1,2]
453
- mgr.where relation[:id].eq_all(values)
454
- values.must_equal [1,2]
455
- end
456
- end
457
-
458
- describe '#matches' do
459
- it 'should create a Matches node' do
460
- relation = Table.new(:users)
461
- relation[:name].matches('%bacon%').must_be_kind_of Nodes::Matches
462
- end
463
-
464
- it 'should generate LIKE in sql' do
465
- relation = Table.new(:users)
466
- mgr = relation.project relation[:id]
467
- mgr.where relation[:name].matches('%bacon%')
468
- mgr.to_sql.must_be_like %{
469
- SELECT "users"."id" FROM "users" WHERE "users"."name" LIKE '%bacon%'
470
- }
471
- end
472
- end
473
-
474
- describe '#matches_any' do
475
- it 'should create a Grouping node' do
476
- relation = Table.new(:users)
477
- relation[:name].matches_any(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
478
- end
479
-
480
- it 'should generate ORs in sql' do
481
- relation = Table.new(:users)
482
- mgr = relation.project relation[:id]
483
- mgr.where relation[:name].matches_any(['%chunky%','%bacon%'])
484
- mgr.to_sql.must_be_like %{
485
- SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' OR "users"."name" LIKE '%bacon%')
486
- }
487
- end
488
- end
489
-
490
- describe '#matches_all' do
491
- it 'should create a Grouping node' do
492
- relation = Table.new(:users)
493
- relation[:name].matches_all(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
494
- end
495
-
496
- it 'should generate ANDs in sql' do
497
- relation = Table.new(:users)
498
- mgr = relation.project relation[:id]
499
- mgr.where relation[:name].matches_all(['%chunky%','%bacon%'])
500
- mgr.to_sql.must_be_like %{
501
- SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' AND "users"."name" LIKE '%bacon%')
502
- }
503
- end
504
- end
505
-
506
- describe '#does_not_match' do
507
- it 'should create a DoesNotMatch node' do
508
- relation = Table.new(:users)
509
- relation[:name].does_not_match('%bacon%').must_be_kind_of Nodes::DoesNotMatch
510
- end
511
-
512
- it 'should generate NOT LIKE in sql' do
513
- relation = Table.new(:users)
514
- mgr = relation.project relation[:id]
515
- mgr.where relation[:name].does_not_match('%bacon%')
516
- mgr.to_sql.must_be_like %{
517
- SELECT "users"."id" FROM "users" WHERE "users"."name" NOT LIKE '%bacon%'
518
- }
519
- end
520
- end
521
-
522
- describe '#does_not_match_any' do
523
- it 'should create a Grouping node' do
524
- relation = Table.new(:users)
525
- relation[:name].does_not_match_any(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
526
- end
527
-
528
- it 'should generate ORs in sql' do
529
- relation = Table.new(:users)
530
- mgr = relation.project relation[:id]
531
- mgr.where relation[:name].does_not_match_any(['%chunky%','%bacon%'])
532
- mgr.to_sql.must_be_like %{
533
- SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' OR "users"."name" NOT LIKE '%bacon%')
534
- }
535
- end
536
- end
537
-
538
- describe '#does_not_match_all' do
539
- it 'should create a Grouping node' do
540
- relation = Table.new(:users)
541
- relation[:name].does_not_match_all(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
542
- end
543
-
544
- it 'should generate ANDs in sql' do
545
- relation = Table.new(:users)
546
- mgr = relation.project relation[:id]
547
- mgr.where relation[:name].does_not_match_all(['%chunky%','%bacon%'])
548
- mgr.to_sql.must_be_like %{
549
- SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' AND "users"."name" NOT LIKE '%bacon%')
550
- }
551
- end
552
- end
553
-
554
- describe 'with a range' do
555
- it 'can be constructed with a standard range' do
556
- attribute = Attribute.new nil, nil
557
- node = attribute.between(1..3)
558
-
559
- node.must_equal Nodes::Between.new(
560
- attribute,
561
- Nodes::And.new([
562
- Nodes::Casted.new(1, attribute),
563
- Nodes::Casted.new(3, attribute)
564
- ])
565
- )
566
- end
567
-
568
- it 'can be constructed with a range starting from -Infinity' do
569
- attribute = Attribute.new nil, nil
570
- node = attribute.between(-::Float::INFINITY..3)
571
-
572
- node.must_equal Nodes::LessThanOrEqual.new(
573
- attribute,
574
- Nodes::Casted.new(3, attribute)
575
- )
576
- end
577
-
578
- it 'can be constructed with an exclusive range starting from -Infinity' do
579
- attribute = Attribute.new nil, nil
580
- node = attribute.between(-::Float::INFINITY...3)
581
-
582
- node.must_equal Nodes::LessThan.new(
583
- attribute,
584
- Nodes::Casted.new(3, attribute)
585
- )
586
- end
587
-
588
- it 'can be constructed with an infinite range' do
589
- attribute = Attribute.new nil, nil
590
- node = attribute.between(-::Float::INFINITY..::Float::INFINITY)
591
-
592
- node.must_equal Nodes::NotIn.new(attribute, [])
593
- end
594
-
595
- it 'can be constructed with a range ending at Infinity' do
596
- attribute = Attribute.new nil, nil
597
- node = attribute.between(0..::Float::INFINITY)
598
-
599
- node.must_equal Nodes::GreaterThanOrEqual.new(
600
- attribute,
601
- Nodes::Casted.new(0, attribute)
602
- )
603
- end
604
-
605
- it 'can be constructed with an exclusive range' do
606
- attribute = Attribute.new nil, nil
607
- node = attribute.between(0...3)
608
-
609
- node.must_equal Nodes::And.new([
610
- Nodes::GreaterThanOrEqual.new(
611
- attribute,
612
- Nodes::Casted.new(0, attribute)
613
- ),
614
- Nodes::LessThan.new(
615
- attribute,
616
- Nodes::Casted.new(3, attribute)
617
- )
618
- ])
619
- end
620
- end
621
-
622
- describe '#in' do
623
- it 'can be constructed with a subquery' do
624
- relation = Table.new(:users)
625
- mgr = relation.project relation[:id]
626
- mgr.where relation[:name].does_not_match_all(['%chunky%','%bacon%'])
627
- attribute = Attribute.new nil, nil
628
-
629
- node = attribute.in(mgr)
630
-
631
- node.must_equal Nodes::In.new(attribute, mgr.ast)
632
- end
633
-
634
- it 'can be constructed with a list' do
635
- attribute = Attribute.new nil, nil
636
- node = attribute.in([1, 2, 3])
637
-
638
- node.must_equal Nodes::In.new(
639
- attribute,
640
- [
641
- Nodes::Casted.new(1, attribute),
642
- Nodes::Casted.new(2, attribute),
643
- Nodes::Casted.new(3, attribute),
644
- ]
645
- )
646
- end
647
-
648
- it 'can be constructed with a random object' do
649
- attribute = Attribute.new nil, nil
650
- random_object = Object.new
651
- node = attribute.in(random_object)
652
-
653
- node.must_equal Nodes::In.new(
654
- attribute,
655
- Nodes::Casted.new(random_object, attribute)
656
- )
657
- end
658
-
659
- it 'should generate IN in sql' do
660
- relation = Table.new(:users)
661
- mgr = relation.project relation[:id]
662
- mgr.where relation[:id].in([1,2,3])
663
- mgr.to_sql.must_be_like %{
664
- SELECT "users"."id" FROM "users" WHERE "users"."id" IN (1, 2, 3)
665
- }
666
- end
667
- end
668
-
669
- describe '#in_any' do
670
- it 'should create a Grouping node' do
671
- relation = Table.new(:users)
672
- relation[:id].in_any([1,2]).must_be_kind_of Nodes::Grouping
673
- end
674
-
675
- it 'should generate ORs in sql' do
676
- relation = Table.new(:users)
677
- mgr = relation.project relation[:id]
678
- mgr.where relation[:id].in_any([[1,2], [3,4]])
679
- mgr.to_sql.must_be_like %{
680
- SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) OR "users"."id" IN (3, 4))
681
- }
682
- end
683
- end
684
-
685
- describe '#in_all' do
686
- it 'should create a Grouping node' do
687
- relation = Table.new(:users)
688
- relation[:id].in_all([1,2]).must_be_kind_of Nodes::Grouping
689
- end
690
-
691
- it 'should generate ANDs in sql' do
692
- relation = Table.new(:users)
693
- mgr = relation.project relation[:id]
694
- mgr.where relation[:id].in_all([[1,2], [3,4]])
695
- mgr.to_sql.must_be_like %{
696
- SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) AND "users"."id" IN (3, 4))
697
- }
698
- end
699
- end
700
-
701
- describe 'with a range' do
702
- it 'can be constructed with a standard range' do
703
- attribute = Attribute.new nil, nil
704
- node = attribute.not_between(1..3)
705
-
706
- node.must_equal Nodes::Grouping.new(Nodes::Or.new(
707
- Nodes::LessThan.new(
708
- attribute,
709
- Nodes::Casted.new(1, attribute)
710
- ),
711
- Nodes::GreaterThan.new(
712
- attribute,
713
- Nodes::Casted.new(3, attribute)
714
- )
715
- ))
716
- end
717
-
718
- it 'can be constructed with a range starting from -Infinity' do
719
- attribute = Attribute.new nil, nil
720
- node = attribute.not_between(-::Float::INFINITY..3)
721
-
722
- node.must_equal Nodes::GreaterThan.new(
723
- attribute,
724
- Nodes::Casted.new(3, attribute)
725
- )
726
- end
727
-
728
- it 'can be constructed with an exclusive range starting from -Infinity' do
729
- attribute = Attribute.new nil, nil
730
- node = attribute.not_between(-::Float::INFINITY...3)
731
-
732
- node.must_equal Nodes::GreaterThanOrEqual.new(
733
- attribute,
734
- Nodes::Casted.new(3, attribute)
735
- )
736
- end
737
-
738
- it 'can be constructed with an infinite range' do
739
- attribute = Attribute.new nil, nil
740
- node = attribute.not_between(-::Float::INFINITY..::Float::INFINITY)
741
-
742
- node.must_equal Nodes::In.new(attribute, [])
743
- end
744
-
745
- it 'can be constructed with a range ending at Infinity' do
746
- attribute = Attribute.new nil, nil
747
- node = attribute.not_between(0..::Float::INFINITY)
748
-
749
- node.must_equal Nodes::LessThan.new(
750
- attribute,
751
- Nodes::Casted.new(0, attribute)
752
- )
753
- end
754
-
755
- it 'can be constructed with an exclusive range' do
756
- attribute = Attribute.new nil, nil
757
- node = attribute.not_between(0...3)
758
-
759
- node.must_equal Nodes::Grouping.new(Nodes::Or.new(
760
- Nodes::LessThan.new(
761
- attribute,
762
- Nodes::Casted.new(0, attribute)
763
- ),
764
- Nodes::GreaterThanOrEqual.new(
765
- attribute,
766
- Nodes::Casted.new(3, attribute)
767
- )
768
- ))
769
- end
770
- end
771
-
772
- describe '#not_in' do
773
- it 'can be constructed with a subquery' do
774
- relation = Table.new(:users)
775
- mgr = relation.project relation[:id]
776
- mgr.where relation[:name].does_not_match_all(['%chunky%','%bacon%'])
777
- attribute = Attribute.new nil, nil
778
-
779
- node = attribute.not_in(mgr)
780
-
781
- node.must_equal Nodes::NotIn.new(attribute, mgr.ast)
782
- end
783
-
784
- it 'can be constructed with a list' do
785
- attribute = Attribute.new nil, nil
786
- node = attribute.not_in([1, 2, 3])
787
-
788
- node.must_equal Nodes::NotIn.new(
789
- attribute,
790
- [
791
- Nodes::Casted.new(1, attribute),
792
- Nodes::Casted.new(2, attribute),
793
- Nodes::Casted.new(3, attribute),
794
- ]
795
- )
796
- end
797
-
798
- it 'can be constructed with a random object' do
799
- attribute = Attribute.new nil, nil
800
- random_object = Object.new
801
- node = attribute.not_in(random_object)
802
-
803
- node.must_equal Nodes::NotIn.new(
804
- attribute,
805
- Nodes::Casted.new(random_object, attribute)
806
- )
807
- end
808
-
809
- it 'should generate NOT IN in sql' do
810
- relation = Table.new(:users)
811
- mgr = relation.project relation[:id]
812
- mgr.where relation[:id].not_in([1,2,3])
813
- mgr.to_sql.must_be_like %{
814
- SELECT "users"."id" FROM "users" WHERE "users"."id" NOT IN (1, 2, 3)
815
- }
816
- end
817
- end
818
-
819
- describe '#not_in_any' do
820
- it 'should create a Grouping node' do
821
- relation = Table.new(:users)
822
- relation[:id].not_in_any([1,2]).must_be_kind_of Nodes::Grouping
823
- end
824
-
825
- it 'should generate ORs in sql' do
826
- relation = Table.new(:users)
827
- mgr = relation.project relation[:id]
828
- mgr.where relation[:id].not_in_any([[1,2], [3,4]])
829
- mgr.to_sql.must_be_like %{
830
- SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) OR "users"."id" NOT IN (3, 4))
831
- }
832
- end
833
- end
834
-
835
- describe '#not_in_all' do
836
- it 'should create a Grouping node' do
837
- relation = Table.new(:users)
838
- relation[:id].not_in_all([1,2]).must_be_kind_of Nodes::Grouping
839
- end
840
-
841
- it 'should generate ANDs in sql' do
842
- relation = Table.new(:users)
843
- mgr = relation.project relation[:id]
844
- mgr.where relation[:id].not_in_all([[1,2], [3,4]])
845
- mgr.to_sql.must_be_like %{
846
- SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) AND "users"."id" NOT IN (3, 4))
847
- }
848
- end
849
- end
850
-
851
- describe '#eq_all' do
852
- it 'should create a Grouping node' do
853
- relation = Table.new(:users)
854
- relation[:id].eq_all([1,2]).must_be_kind_of Nodes::Grouping
855
- end
856
-
857
- it 'should generate ANDs in sql' do
858
- relation = Table.new(:users)
859
- mgr = relation.project relation[:id]
860
- mgr.where relation[:id].eq_all([1,2])
861
- mgr.to_sql.must_be_like %{
862
- SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
863
- }
864
- end
865
- end
866
-
867
- describe '#asc' do
868
- it 'should create an Ascending node' do
869
- relation = Table.new(:users)
870
- relation[:id].asc.must_be_kind_of Nodes::Ascending
871
- end
872
-
873
- it 'should generate ASC in sql' do
874
- relation = Table.new(:users)
875
- mgr = relation.project relation[:id]
876
- mgr.order relation[:id].asc
877
- mgr.to_sql.must_be_like %{
878
- SELECT "users"."id" FROM "users" ORDER BY "users"."id" ASC
879
- }
880
- end
881
- end
882
-
883
- describe '#desc' do
884
- it 'should create a Descending node' do
885
- relation = Table.new(:users)
886
- relation[:id].desc.must_be_kind_of Nodes::Descending
887
- end
888
-
889
- it 'should generate DESC in sql' do
890
- relation = Table.new(:users)
891
- mgr = relation.project relation[:id]
892
- mgr.order relation[:id].desc
893
- mgr.to_sql.must_be_like %{
894
- SELECT "users"."id" FROM "users" ORDER BY "users"."id" DESC
895
- }
896
- end
897
- end
898
- end
899
-
900
- describe 'equality' do
901
- describe '#to_sql' do
902
- it 'should produce sql' do
903
- table = Table.new :users
904
- condition = table['id'].eq 1
905
- condition.to_sql.must_equal '"users"."id" = 1'
906
- end
907
- end
908
- end
909
- end
910
- end