squeel 1.1.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +36 -4
  5. data/CHANGELOG.md +15 -0
  6. data/Gemfile +1 -1
  7. data/README.md +47 -6
  8. data/Rakefile +14 -2
  9. data/lib/squeel.rb +9 -1
  10. data/lib/squeel/adapters/active_record.rb +0 -1
  11. data/lib/squeel/adapters/active_record/3.0/join_dependency_extensions.rb +1 -0
  12. data/lib/squeel/adapters/active_record/3.0/relation_extensions.rb +12 -1
  13. data/lib/squeel/adapters/active_record/3.1/join_dependency_extensions.rb +1 -0
  14. data/lib/squeel/adapters/active_record/3.2/join_dependency_extensions.rb +1 -0
  15. data/lib/squeel/adapters/active_record/4.0/join_dependency_extensions.rb +1 -0
  16. data/lib/squeel/adapters/active_record/4.0/relation_extensions.rb +92 -0
  17. data/lib/squeel/adapters/active_record/4.1/compat.rb +15 -0
  18. data/lib/squeel/adapters/active_record/4.1/context.rb +88 -0
  19. data/lib/squeel/adapters/active_record/4.1/preloader_extensions.rb +31 -0
  20. data/lib/squeel/adapters/active_record/4.1/reflection_extensions.rb +37 -0
  21. data/lib/squeel/adapters/active_record/4.1/relation_extensions.rb +307 -0
  22. data/lib/squeel/adapters/active_record/4.2/compat.rb +1 -0
  23. data/lib/squeel/adapters/active_record/4.2/context.rb +1 -0
  24. data/lib/squeel/adapters/active_record/4.2/preloader_extensions.rb +1 -0
  25. data/lib/squeel/adapters/active_record/4.2/relation_extensions.rb +108 -0
  26. data/lib/squeel/adapters/active_record/context.rb +7 -7
  27. data/lib/squeel/adapters/active_record/join_dependency_extensions.rb +9 -13
  28. data/lib/squeel/adapters/active_record/relation_extensions.rb +38 -8
  29. data/lib/squeel/core_ext/symbol.rb +3 -3
  30. data/lib/squeel/dsl.rb +1 -1
  31. data/lib/squeel/nodes.rb +1 -0
  32. data/lib/squeel/nodes/as.rb +12 -0
  33. data/lib/squeel/nodes/join.rb +8 -4
  34. data/lib/squeel/nodes/key_path.rb +10 -1
  35. data/lib/squeel/nodes/node.rb +21 -0
  36. data/lib/squeel/nodes/stub.rb +8 -4
  37. data/lib/squeel/nodes/subquery_join.rb +44 -0
  38. data/lib/squeel/version.rb +1 -1
  39. data/lib/squeel/visitors.rb +2 -0
  40. data/lib/squeel/visitors/enumeration_visitor.rb +101 -0
  41. data/lib/squeel/visitors/order_visitor.rb +9 -2
  42. data/lib/squeel/visitors/predicate_visitor.rb +11 -0
  43. data/lib/squeel/visitors/preload_visitor.rb +12 -0
  44. data/lib/squeel/visitors/visitor.rb +89 -13
  45. data/spec/config.travis.yml +13 -0
  46. data/spec/config.yml +12 -0
  47. data/spec/console.rb +3 -12
  48. data/spec/core_ext/symbol_spec.rb +3 -3
  49. data/spec/helpers/squeel_helper.rb +8 -5
  50. data/spec/spec_helper.rb +4 -16
  51. data/spec/squeel/adapters/active_record/context_spec.rb +8 -4
  52. data/spec/squeel/adapters/active_record/join_dependency_extensions_spec.rb +123 -38
  53. data/spec/squeel/adapters/active_record/relation_extensions_spec.rb +350 -124
  54. data/spec/squeel/core_ext/symbol_spec.rb +3 -3
  55. data/spec/squeel/nodes/join_spec.rb +4 -4
  56. data/spec/squeel/nodes/stub_spec.rb +3 -3
  57. data/spec/squeel/nodes/subquery_join_spec.rb +46 -0
  58. data/spec/squeel/visitors/order_visitor_spec.rb +3 -3
  59. data/spec/squeel/visitors/predicate_visitor_spec.rb +69 -36
  60. data/spec/squeel/visitors/select_visitor_spec.rb +1 -1
  61. data/spec/squeel/visitors/visitor_spec.rb +7 -6
  62. data/spec/support/models.rb +99 -15
  63. data/spec/support/schema.rb +109 -4
  64. data/squeel.gemspec +8 -6
  65. metadata +89 -107
  66. data/.ruby-gemset +0 -1
  67. data/.ruby-version +0 -1
  68. data/spec/blueprints/articles.rb +0 -5
  69. data/spec/blueprints/comments.rb +0 -5
  70. data/spec/blueprints/notes.rb +0 -3
  71. data/spec/blueprints/people.rb +0 -4
  72. data/spec/blueprints/tags.rb +0 -3
@@ -33,7 +33,7 @@ describe Symbol do
33
33
  join = :blah.inner
34
34
  join.should be_a Squeel::Nodes::Join
35
35
  join._name.should eq :blah
36
- join._type.should eq Arel::InnerJoin
36
+ join._type.should eq Squeel::InnerJoin
37
37
  end
38
38
  end
39
39
 
@@ -42,7 +42,7 @@ describe Symbol do
42
42
  join = :blah.outer
43
43
  join.should be_a Squeel::Nodes::Join
44
44
  join._name.should eq :blah
45
- join._type.should eq Arel::OuterJoin
45
+ join._type.should eq Squeel::OuterJoin
46
46
  end
47
47
  end
48
48
 
@@ -51,7 +51,7 @@ describe Symbol do
51
51
  join = :blah.of_class(Person)
52
52
  join.should be_a Squeel::Nodes::Join
53
53
  join._name.should eq :blah
54
- join._type.should eq Arel::InnerJoin
54
+ join._type.should eq Squeel::InnerJoin
55
55
  join._klass.should eq Person
56
56
  end
57
57
  end
@@ -8,13 +8,13 @@ module Squeel
8
8
  @j = Join.new :name
9
9
  end
10
10
 
11
- it 'defaults to Arel::InnerJoin' do
12
- @j._type.should eq Arel::InnerJoin
11
+ it 'defaults to Squeel::InnerJoin' do
12
+ @j._type.should eq Squeel::InnerJoin
13
13
  end
14
14
 
15
15
  it 'allows setting join type' do
16
16
  @j.outer
17
- @j._type.should eq Arel::OuterJoin
17
+ @j._type.should eq Squeel::OuterJoin
18
18
  end
19
19
 
20
20
  it 'allows setting polymorphic class' do
@@ -32,7 +32,7 @@ module Squeel
32
32
  it 'creates a KeyPath with a join endpoint when sent a method with a Class param' do
33
33
  keypath = @j.another(Person)
34
34
  keypath.should be_a KeyPath
35
- keypath.path.should eq [@j, Join.new(:another, Arel::InnerJoin, Person)]
35
+ keypath.path.should eq [@j, Join.new(:another, Squeel::InnerJoin, Person)]
36
36
  end
37
37
 
38
38
  it 'creates an absolute keypath with just an endpoint with ~' do
@@ -48,7 +48,7 @@ module Squeel
48
48
  it 'creates a KeyPath with a join endpoint when sent a method with a Class param' do
49
49
  keypath = @s.another(Person)
50
50
  keypath.should be_a KeyPath
51
- keypath.path.should eq [@s, Join.new(:another, Arel::InnerJoin, Person)]
51
+ keypath.path.should eq [@s, Join.new(:another, Squeel::InnerJoin, Person)]
52
52
  end
53
53
 
54
54
  it 'creates a KeyPath with a sifter endpoint when sent #sift' do
@@ -189,13 +189,13 @@ module Squeel
189
189
  it 'creates inner joins' do
190
190
  join = @s.inner
191
191
  join.should be_a Join
192
- join._type.should eq Arel::InnerJoin
192
+ join._type.should eq Squeel::InnerJoin
193
193
  end
194
194
 
195
195
  it 'creates outer joins' do
196
196
  join = @s.outer
197
197
  join.should be_a Join
198
- join._type.should eq Arel::OuterJoin
198
+ join._type.should eq Squeel::OuterJoin
199
199
  end
200
200
 
201
201
  it 'creates functions with #func' do
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Squeel
4
+ module Nodes
5
+ describe SubqueryJoin do
6
+ before(:each) do
7
+ @j =
8
+ if activerecord_version_at_least('4.1.0')
9
+ SubqueryJoin.new(OrderItem.all.as('items'), dsl {(items.orderable_id == id) & (items.orderable_type == 'Seat')} )
10
+ else
11
+ SubqueryJoin.new(OrderItem.scoped.as('items'), dsl {(items.orderable_id == id) & (items.orderable_type == 'Seat')} )
12
+ end
13
+ end
14
+
15
+ it 'defaults to Squeel::InnerJoin' do
16
+ @j.type.should eq Squeel::InnerJoin
17
+ end
18
+
19
+ it 'allows setting join type' do
20
+ @j.outer
21
+ @j.type.should eq Squeel::OuterJoin
22
+ end
23
+
24
+ it 'subquery should be a Nodes::As' do
25
+ @j.subquery.should be_kind_of(As)
26
+ end
27
+
28
+ it 'constraints should be a node' do
29
+ @j.constraints.should be_kind_of(Node)
30
+ end
31
+
32
+ it 'only convert an ActiveRecord::Relation to a SubqueryJoin' do
33
+ j =
34
+ if activerecord_version_at_least('4.1.0')
35
+ OrderItem.all.as('items').on{(items.orderable_id == id) & (items.orderable_type == 'Seat')}
36
+ else
37
+ OrderItem.scoped.as('items').on{(items.orderable_id == id) & (items.orderable_type == 'Seat')}
38
+ end
39
+
40
+ j.should be_kind_of(SubqueryJoin)
41
+
42
+ expect { As.new('name', 'alias').on{(items.orderable_id == id) & (items.orderable_type == 'Seat')} }.to raise_error
43
+ end
44
+ end
45
+ end
46
+ end
@@ -18,17 +18,17 @@ module Squeel
18
18
 
19
19
  it 'accepts Order with Function expression' do
20
20
  function = @v.accept(dsl{find_in_set(children.children.id, '1,2,3').desc})
21
- function.to_sql.should match /find_in_set\("children_people_2"."id", '1,2,3'\) DESC/
21
+ function.to_sql.should match /find_in_set\(#{Q}children_people_2#{Q}.#{Q}id#{Q}, '1,2,3'\) DESC/
22
22
  end
23
23
 
24
24
  it 'accepts Order with Operation expression' do
25
25
  operation = @v.accept(dsl{(id / 1).desc})
26
- operation.to_sql.should match /"people"."id" \/ 1 DESC/
26
+ operation.to_sql.should match /#{Q}people#{Q}.#{Q}id#{Q} \/ 1 DESC/
27
27
  end
28
28
 
29
29
  it 'orders by predicates' do
30
30
  orders = @v.accept(dsl{name == 'Ernie'})
31
- orders.to_sql.should match /"people"."name" = 'Ernie'/
31
+ orders.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} = 'Ernie'/
32
32
  end
33
33
 
34
34
  end
@@ -23,25 +23,38 @@ module Squeel
23
23
  node.right.should be_a Arel::Nodes::SelectStatement
24
24
  end
25
25
 
26
- it 'does not quote nil values in Predicate nodes' do
26
+ it 'quote nil values in Predicate nodes' do
27
27
  predicate = Nodes::Predicate.new(Nodes::Function.new(:blah, [1, 2]), :in, nil)
28
28
  node = @v.accept(predicate)
29
29
  node.should be_a Arel::Nodes::In
30
- node.right.should be_nil
30
+ if defined?(Arel::Nodes::Quoted)
31
+ node.right.expr.should == 'NULL'
32
+ else
33
+ node.right.should be_nil
34
+ end
35
+
31
36
  end
32
37
 
33
38
  it 'creates Equality nodes for simple hashes' do
34
39
  predicate = @v.accept(:name => 'Joe')
35
40
  predicate.should be_a Arel::Nodes::Equality
36
41
  predicate.left.name.to_s.should eq 'name'
37
- predicate.right.should eq 'Joe'
42
+ if defined?(Arel::Nodes::Casted)
43
+ predicate.right.val.should eq 'Joe'
44
+ else
45
+ predicate.right.should eq 'Joe'
46
+ end
38
47
  end
39
48
 
40
49
  it 'creates In nodes for simple hashes with an array as a value' do
41
50
  predicate = @v.accept(:name => ['Joe', 'Bob'])
42
51
  predicate.should be_a Arel::Nodes::In
43
52
  predicate.left.name.to_s.should eq 'name'
44
- predicate.right.should eq ['Joe', 'Bob']
53
+ if defined?(Arel::Nodes::Casted)
54
+ predicate.right.map(&:val).should eq ['Joe', 'Bob']
55
+ else
56
+ predicate.right.should eq ['Joe', 'Bob']
57
+ end
45
58
  end
46
59
 
47
60
  it 'generates "1=0" when given an empty array value in a hash' do
@@ -88,32 +101,32 @@ module Squeel
88
101
 
89
102
  it 'generates IS NULL for hash keys with a value of [nil]' do
90
103
  predicate = @v.accept(:id => [nil])
91
- predicate.to_sql.should be_like '"people"."id" IS NULL'
104
+ predicate.to_sql.should be_like "#{Q}people#{Q}.#{Q}id#{Q} IS NULL"
92
105
  end
93
106
 
94
107
  it 'generates IS NULL for in predicates with a value of [nil]' do
95
108
  predicate = @v.accept(:id.in => [nil])
96
- predicate.to_sql.should be_like '"people"."id" IS NULL'
109
+ predicate.to_sql.should be_like "#{Q}people#{Q}.#{Q}id#{Q} IS NULL"
97
110
  end
98
111
 
99
112
  it 'generates IS NOT NULL for not_in predicates with a value of [nil]' do
100
113
  predicate = @v.accept(:id.not_in => [nil])
101
- predicate.to_sql.should be_like '"people"."id" IS NOT NULL'
114
+ predicate.to_sql.should be_like "#{Q}people#{Q}.#{Q}id#{Q} IS NOT NULL"
102
115
  end
103
116
 
104
117
  it 'generates IN OR IS NULL for hash keys with a value of [1, 2, 3, nil]' do
105
118
  predicate = @v.accept(:id => [1, 2, 3, nil])
106
- predicate.to_sql.should be_like '("people"."id" IN (1, 2, 3) OR "people"."id" IS NULL)'
119
+ predicate.to_sql.should be_like "(#{Q}people#{Q}.#{Q}id#{Q} IN (1, 2, 3) OR #{Q}people#{Q}.#{Q}id#{Q} IS NULL)"
107
120
  end
108
121
 
109
122
  it 'generates IN OR IS NULL for in predicates with a value of [1, 2, 3, nil]' do
110
123
  predicate = @v.accept(:id.in => [1, 2, 3, nil])
111
- predicate.to_sql.should be_like '("people"."id" IN (1, 2, 3) OR "people"."id" IS NULL)'
124
+ predicate.to_sql.should be_like "(#{Q}people#{Q}.#{Q}id#{Q} IN (1, 2, 3) OR #{Q}people#{Q}.#{Q}id#{Q} IS NULL)"
112
125
  end
113
126
 
114
127
  it 'generates IN AND IS NOT NULL for not_in predicates with a value of [1, 2, 3, nil]' do
115
128
  predicate = @v.accept(:id.not_in => [1, 2, 3, nil])
116
- predicate.to_sql.should be_like '"people"."id" NOT IN (1, 2, 3) AND "people"."id" IS NOT NULL'
129
+ predicate.to_sql.should be_like "#{Q}people#{Q}.#{Q}id#{Q} NOT IN (1, 2, 3) AND #{Q}people#{Q}.#{Q}id#{Q} IS NOT NULL"
117
130
  end
118
131
 
119
132
  it 'allows a subquery on the value side of an explicit predicate' do
@@ -133,39 +146,47 @@ module Squeel
133
146
  it 'selects the primary key of a relation with no select_values with an explicit predicate' do
134
147
  predicate = @v.accept dsl{name.in(PersonWithNamePrimaryKey.where{name.in(['Aric Smith', 'Gladyce Kulas'])})}
135
148
  predicate.right.should be_a Arel::Nodes::SelectStatement
136
- predicate.right.to_sql.should match /SELECT "people"."name"/
149
+ predicate.right.to_sql.should match /SELECT #{Q}people#{Q}.#{Q}name#{Q}/
137
150
  end
138
151
 
139
152
  it 'selects the primary key of a relation with no select_values with an implicit predicate' do
140
153
  predicate = @v.accept(:name => PersonWithNamePrimaryKey.where{name.in(['Aric Smith', 'Gladyce Kulas'])})
141
154
  predicate.right.should be_a Arel::Nodes::SelectStatement
142
- predicate.right.to_sql.should match /SELECT "people"."name"/
155
+ predicate.right.to_sql.should match /SELECT #{Q}people#{Q}.#{Q}name#{Q}/
143
156
  end
144
157
 
145
158
  it "doesn't clobber a relation value's existing select_values if present with an explicit predicate" do
146
159
  predicate = @v.accept dsl{name.in(Person.select{name})}
147
160
  predicate.right.should be_a Arel::Nodes::SelectStatement
148
- predicate.right.to_sql.should match /SELECT "people"."name"/
161
+ predicate.right.to_sql.should match /SELECT #{Q}people#{Q}.#{Q}name#{Q}/
149
162
  end
150
163
 
151
164
  it "doesn't clobber a relation value's existing select_values if present with an implicit predicate" do
152
165
  predicate = @v.accept(:name => Person.select{name})
153
166
  predicate.right.should be_a Arel::Nodes::SelectStatement
154
- predicate.right.to_sql.should match /SELECT "people"."name"/
167
+ predicate.right.to_sql.should match /SELECT #{Q}people#{Q}.#{Q}name#{Q}/
155
168
  end
156
169
 
157
170
  it 'converts ActiveRecord::Base objects to their id' do
158
171
  predicate = @v.accept(:id => Person.first)
159
172
  predicate.should be_a Arel::Nodes::Equality
160
173
  predicate.left.name.to_s.should eq 'id'
161
- predicate.right.should eq 1
174
+ if defined?(Arel::Nodes::Casted)
175
+ predicate.right.val.should eq 1
176
+ else
177
+ predicate.right.should eq 1
178
+ end
162
179
  end
163
180
 
164
181
  it 'converts arrays of ActiveRecord::Base objects to their ids' do
165
182
  predicate = @v.accept(:id => [Person.first, Person.last])
166
183
  predicate.should be_a Arel::Nodes::In
167
184
  predicate.left.name.to_s.should eq 'id'
168
- predicate.right.should eq [1, 332]
185
+ if defined?(Arel::Nodes::Casted)
186
+ predicate.right.map(&:val).should eq [Person.first.id, Person.last.id]
187
+ else
188
+ predicate.right.should eq [Person.first.id, Person.last.id]
189
+ end
169
190
  end
170
191
 
171
192
  it 'creates the node against the proper table for nested hashes' do
@@ -182,7 +203,11 @@ module Squeel
182
203
  })
183
204
  predicate.should be_a Arel::Nodes::Equality
184
205
  predicate.left.relation.table_alias.should eq 'parents_people_2'
185
- predicate.right.should eq 'Joe'
206
+ if defined?(Arel::Nodes::Casted)
207
+ predicate.right.val.should eq 'Joe'
208
+ else
209
+ predicate.right.should eq 'Joe'
210
+ end
186
211
  end
187
212
 
188
213
  it 'treats keypath keys like nested hashes' do
@@ -255,28 +280,28 @@ module Squeel
255
280
  predicate = @v.accept(dsl{{name => name}})
256
281
  predicate.should be_a Arel::Nodes::Equality
257
282
  predicate.right.should be_a Arel::Attribute
258
- predicate.to_sql.should match /"people"."name" = "people"."name"/
283
+ predicate.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} = #{Q}people#{Q}.#{Q}name#{Q}/
259
284
  end
260
285
 
261
286
  it 'contextualizes Symbol values' do
262
287
  predicate = @v.accept(:name => :name)
263
288
  predicate.should be_a Arel::Nodes::Equality
264
289
  predicate.right.should be_a Arel::Attribute
265
- predicate.to_sql.should match /"people"."name" = "people"."name"/
290
+ predicate.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} = #{Q}people#{Q}.#{Q}name#{Q}/
266
291
  end
267
292
 
268
293
  it 'contextualizes KeyPath values in hashes' do
269
294
  predicate = @v.accept(dsl{{name => children.name}})
270
295
  predicate.should be_a Arel::Nodes::Equality
271
296
  predicate.right.should be_a Arel::Attribute
272
- predicate.to_sql.should match /"people"."name" = "children_people"."name"/
297
+ predicate.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} = #{Q}children_people#{Q}.#{Q}name#{Q}/
273
298
  end
274
299
 
275
300
  it 'contextualizes KeyPath values in predicates' do
276
301
  predicate = @v.accept(dsl{name == children.name})
277
302
  predicate.should be_a Arel::Nodes::Equality
278
303
  predicate.right.should be_a Arel::Attribute
279
- predicate.to_sql.should match /"people"."name" = "children_people"."name"/
304
+ predicate.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} = #{Q}children_people#{Q}.#{Q}name#{Q}/
280
305
  end
281
306
 
282
307
  it 'visits Squeel Sifters at top level' do
@@ -284,8 +309,8 @@ module Squeel
284
309
  predicate.should be_a Arel::Nodes::Grouping
285
310
  expr = predicate.expr
286
311
  expr.should be_a Arel::Nodes::Or
287
- expr.left.to_sql.should match /"people"."name" LIKE 'smith%'/
288
- expr.right.to_sql.should match /"people"."name" LIKE '%smith'/
312
+ expr.left.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} [I]*LIKE 'smith%'/
313
+ expr.right.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} [I]*LIKE '%smith'/
289
314
  end
290
315
 
291
316
  it 'visits nested Squeel sifters' do
@@ -293,8 +318,8 @@ module Squeel
293
318
  predicate.should be_a Arel::Nodes::Grouping
294
319
  expr = predicate.expr
295
320
  expr.should be_a Arel::Nodes::Or
296
- expr.left.to_sql.should match /"children_people"."name" LIKE 'smith%'/
297
- expr.right.to_sql.should match /"children_people"."name" LIKE '%smith'/
321
+ expr.left.to_sql.should match /#{Q}children_people#{Q}.#{Q}name#{Q} [I]*LIKE 'smith%'/
322
+ expr.right.to_sql.should match /#{Q}children_people#{Q}.#{Q}name#{Q} [I]*LIKE '%smith'/
298
323
  end
299
324
 
300
325
  it 'visits sifters in a keypath' do
@@ -302,14 +327,14 @@ module Squeel
302
327
  predicate.should be_a Arel::Nodes::Grouping
303
328
  expr = predicate.expr
304
329
  expr.should be_a Arel::Nodes::Or
305
- expr.left.to_sql.should match /"children_people"."name" LIKE 'smith%'/
306
- expr.right.to_sql.should match /"children_people"."name" LIKE '%smith'/
330
+ expr.left.to_sql.should match /#{Q}children_people#{Q}.#{Q}name#{Q} [I]*LIKE 'smith%'/
331
+ expr.right.to_sql.should match /#{Q}children_people#{Q}.#{Q}name#{Q} [I]*LIKE '%smith'/
307
332
  end
308
333
 
309
334
  it 'honors an explicit table in string keys' do
310
335
  predicate = @v.accept('things.attribute' => 'retro')
311
336
  predicate.should be_a Arel::Nodes::Equality
312
- predicate.to_sql.should match /"things"."attribute" = 'retro'/
337
+ predicate.to_sql.should match /#{Q}things#{Q}.#{Q}attribute#{Q} = 'retro'/
313
338
  end
314
339
 
315
340
  it 'does not allow "table.column" keys after context change' do
@@ -324,28 +349,32 @@ module Squeel
324
349
  predicate = @v.accept(dsl{id >> Person.select{id}.limit(3).order{id.desc}})
325
350
  predicate.should be_a Arel::Nodes::In
326
351
  predicate.right.should be_a Arel::Nodes::SelectStatement
327
- predicate.to_sql.should be_like '"people"."id" IN (SELECT "people"."id" FROM "people" ORDER BY "people"."id" DESC LIMIT 3)'
352
+ predicate.to_sql.should be_like "#{Q}people#{Q}.#{Q}id#{Q} IN (SELECT #{Q}people#{Q}.#{Q}id#{Q} FROM #{Q}people#{Q} ORDER BY #{Q}people#{Q}.#{Q}id#{Q} DESC LIMIT 3)"
328
353
  end
329
354
 
330
355
  it 'converts ActiveRecord::Relation values in function arguments to their Arel AST' do
331
356
  predicate = @v.accept(dsl{exists(Person.where{name == 'Aric Smith'})})
332
357
  predicate.should be_a Arel::Nodes::NamedFunction
333
358
  predicate.expressions.first.should be_a Arel::Nodes::SelectStatement
334
- predicate.to_sql.should be_like "exists(SELECT \"people\".* FROM \"people\" WHERE \"people\".\"name\" = 'Aric Smith')"
359
+ predicate.to_sql.should be_like "exists(SELECT #{Q}people#{Q}.* FROM #{Q}people#{Q} WHERE #{Q}people#{Q}.#{Q}name#{Q} = 'Aric Smith')"
335
360
  end
336
361
 
337
362
  it "doesn't try to sanitize_sql an array of strings in the value of a Predicate" do
338
363
  predicate = @v.accept(dsl{name >> ['Aric Smith', 'Gladyce Kulas']})
339
364
  predicate.should be_a Arel::Nodes::In
340
365
  predicate.right.should be_an Array
341
- predicate.to_sql.should match /"people"."name" IN \('Aric Smith', 'Gladyce Kulas'\)/
366
+ predicate.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} IN \('Aric Smith', 'Gladyce Kulas'\)/
342
367
  end
343
368
 
344
369
  it 'creates a node of the proper type when a hash has a Predicate as a key' do
345
370
  predicate = @v.accept(:name.matches => 'Joe%')
346
371
  predicate.should be_a Arel::Nodes::Matches
347
372
  predicate.left.name.should eq :name
348
- predicate.right.should eq 'Joe%'
373
+ if defined?(Arel::Nodes::Casted)
374
+ predicate.right.val.should eq 'Joe%'
375
+ else
376
+ predicate.right.should eq 'Joe%'
377
+ end
349
378
  end
350
379
 
351
380
  it 'treats hash keys as an association when there is an Or on the value side' do
@@ -383,7 +412,11 @@ module Squeel
383
412
  predicate.should be_a Arel::Nodes::Equality
384
413
  predicate.left.relation.table_alias.should eq 'children_people_2'
385
414
  predicate.left.name.to_s.should eq 'name'
386
- predicate.right.should eq 'Joe'
415
+ if defined?(Arel::Nodes::Casted)
416
+ predicate.right.val.should eq 'Joe'
417
+ else
418
+ predicate.right.should eq 'Joe'
419
+ end
387
420
  end
388
421
 
389
422
  it 'creates an Arel Grouping node containing an Or node for Or nodes' do
@@ -409,7 +442,7 @@ module Squeel
409
442
 
410
443
  it 'maps symbols in Function args to Arel attributes' do
411
444
  function = @v.accept(:find_in_set.func(:id, '1,2,3'))
412
- function.to_sql.should match /"people"."id"/
445
+ function.to_sql.should match /#{Q}people#{Q}.#{Q}id#{Q}/
413
446
  end
414
447
 
415
448
  it 'sets the alias on the Arel NamedFunction from the Function alias' do
@@ -419,12 +452,12 @@ module Squeel
419
452
 
420
453
  it 'accepts As nodes containing symbols' do
421
454
  as = @v.accept(:name.as('other_name'))
422
- as.to_sql.should match /"people"."name" AS other_name/
455
+ as.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} AS other_name/
423
456
  end
424
457
 
425
458
  it 'accepts As nodes containing stubs' do
426
459
  as = @v.accept(dsl{name.as(other_name)})
427
- as.to_sql.should match /"people"."name" AS other_name/
460
+ as.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} AS other_name/
428
461
  end
429
462
 
430
463
  it 'creates an Arel Addition node for an Operation node with + as operator' do
@@ -18,7 +18,7 @@ module Squeel
18
18
 
19
19
  it 'selects predicates' do
20
20
  selects = @v.accept(dsl{name == 'Ernie'})
21
- selects.to_sql.should match /"people"."name" = 'Ernie'/
21
+ selects.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} = 'Ernie'/
22
22
  end
23
23
 
24
24
  end
@@ -33,6 +33,7 @@ module Squeel
33
33
  }
34
34
  }
35
35
  })
36
+
36
37
  attributes.should be_a Array
37
38
  attribute = attributes.first
38
39
  attribute.should be_a Arel::Attributes::Attribute
@@ -68,7 +69,7 @@ module Squeel
68
69
  it 'allows a subquery as a selection' do
69
70
  relation = Person.where(:name => 'Aric Smith').select(:id)
70
71
  node = @v.accept(relation.as('aric'))
71
- node.to_sql.should be_like "(SELECT \"people\".\"id\" FROM \"people\" WHERE \"people\".\"name\" = 'Aric Smith') aric"
72
+ node.to_sql.should be_like "(SELECT #{Q}people#{Q}.#{Q}id#{Q} FROM #{Q}people#{Q} WHERE #{Q}people#{Q}.#{Q}name#{Q} = 'Aric Smith') aric"
72
73
  end
73
74
 
74
75
  it 'creates an Arel NamedFunction node for a Function node' do
@@ -78,12 +79,12 @@ module Squeel
78
79
 
79
80
  it 'maps symbols in Function args to Arel attributes' do
80
81
  function = @v.accept(:find_in_set.func(:id, '1,2,3'))
81
- function.to_sql.should match /find_in_set\("people"."id", '1,2,3'\)/
82
+ function.to_sql.should match /find_in_set\(#{Q}people#{Q}.#{Q}id#{Q}, '1,2,3'\)/
82
83
  end
83
84
 
84
85
  it 'accepts keypaths as function args' do
85
86
  function = @v.accept(dsl{find_in_set(children.children.id, '1,2,3')})
86
- function.to_sql.should match /find_in_set\("children_people_2"."id", '1,2,3'\)/
87
+ function.to_sql.should match /find_in_set\(#{Q}children_people_2#{Q}.#{Q}id#{Q}, '1,2,3'\)/
87
88
  end
88
89
 
89
90
  it 'sets the alias on the Arel NamedFunction from the Function alias' do
@@ -93,17 +94,17 @@ module Squeel
93
94
 
94
95
  it 'accepts As nodes containing symbols' do
95
96
  as = @v.accept(:name.as('other_name'))
96
- as.to_sql.should match /"people"."name" AS other_name/
97
+ as.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} AS other_name/
97
98
  end
98
99
 
99
100
  it 'accepts As nodes containing stubs' do
100
101
  as = @v.accept(dsl{name.as(other_name)})
101
- as.to_sql.should match /"people"."name" AS other_name/
102
+ as.to_sql.should match /#{Q}people#{Q}.#{Q}name#{Q} AS other_name/
102
103
  end
103
104
 
104
105
  it 'accepts As nodes containing keypaths' do
105
106
  as = @v.accept(dsl{children.name.as(other_name)})
106
- as.to_sql.should match /"children_people"."name" AS other_name/
107
+ as.to_sql.should match /#{Q}children_people#{Q}.#{Q}name#{Q} AS other_name/
107
108
  end
108
109
 
109
110
  it 'creates an Arel Grouping node for a Squeel Grouping node' do