arel 6.0.0.beta2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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