squeel 1.1.1 → 1.2.1

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