squeel 1.1.1 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/.travis.yml +36 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/README.md +47 -6
- data/Rakefile +14 -2
- data/lib/squeel.rb +9 -1
- data/lib/squeel/adapters/active_record.rb +0 -1
- data/lib/squeel/adapters/active_record/3.0/join_dependency_extensions.rb +1 -0
- data/lib/squeel/adapters/active_record/3.0/relation_extensions.rb +12 -1
- data/lib/squeel/adapters/active_record/3.1/join_dependency_extensions.rb +1 -0
- data/lib/squeel/adapters/active_record/3.2/join_dependency_extensions.rb +1 -0
- data/lib/squeel/adapters/active_record/4.0/join_dependency_extensions.rb +1 -0
- data/lib/squeel/adapters/active_record/4.0/relation_extensions.rb +92 -0
- data/lib/squeel/adapters/active_record/4.1/compat.rb +15 -0
- data/lib/squeel/adapters/active_record/4.1/context.rb +88 -0
- data/lib/squeel/adapters/active_record/4.1/preloader_extensions.rb +31 -0
- data/lib/squeel/adapters/active_record/4.1/reflection_extensions.rb +37 -0
- data/lib/squeel/adapters/active_record/4.1/relation_extensions.rb +307 -0
- data/lib/squeel/adapters/active_record/4.2/compat.rb +1 -0
- data/lib/squeel/adapters/active_record/4.2/context.rb +1 -0
- data/lib/squeel/adapters/active_record/4.2/preloader_extensions.rb +1 -0
- data/lib/squeel/adapters/active_record/4.2/relation_extensions.rb +108 -0
- data/lib/squeel/adapters/active_record/context.rb +7 -7
- data/lib/squeel/adapters/active_record/join_dependency_extensions.rb +9 -13
- data/lib/squeel/adapters/active_record/relation_extensions.rb +38 -8
- data/lib/squeel/core_ext/symbol.rb +3 -3
- data/lib/squeel/dsl.rb +1 -1
- data/lib/squeel/nodes.rb +1 -0
- data/lib/squeel/nodes/as.rb +12 -0
- data/lib/squeel/nodes/join.rb +8 -4
- data/lib/squeel/nodes/key_path.rb +10 -1
- data/lib/squeel/nodes/node.rb +21 -0
- data/lib/squeel/nodes/stub.rb +8 -4
- data/lib/squeel/nodes/subquery_join.rb +44 -0
- data/lib/squeel/version.rb +1 -1
- data/lib/squeel/visitors.rb +2 -0
- data/lib/squeel/visitors/enumeration_visitor.rb +101 -0
- data/lib/squeel/visitors/order_visitor.rb +9 -2
- data/lib/squeel/visitors/predicate_visitor.rb +11 -0
- data/lib/squeel/visitors/preload_visitor.rb +12 -0
- data/lib/squeel/visitors/visitor.rb +89 -13
- data/spec/config.travis.yml +13 -0
- data/spec/config.yml +12 -0
- data/spec/console.rb +3 -12
- data/spec/core_ext/symbol_spec.rb +3 -3
- data/spec/helpers/squeel_helper.rb +8 -5
- data/spec/spec_helper.rb +4 -16
- data/spec/squeel/adapters/active_record/context_spec.rb +8 -4
- data/spec/squeel/adapters/active_record/join_dependency_extensions_spec.rb +123 -38
- data/spec/squeel/adapters/active_record/relation_extensions_spec.rb +350 -124
- data/spec/squeel/core_ext/symbol_spec.rb +3 -3
- data/spec/squeel/nodes/join_spec.rb +4 -4
- data/spec/squeel/nodes/stub_spec.rb +3 -3
- data/spec/squeel/nodes/subquery_join_spec.rb +46 -0
- data/spec/squeel/visitors/order_visitor_spec.rb +3 -3
- data/spec/squeel/visitors/predicate_visitor_spec.rb +69 -36
- data/spec/squeel/visitors/select_visitor_spec.rb +1 -1
- data/spec/squeel/visitors/visitor_spec.rb +7 -6
- data/spec/support/models.rb +99 -15
- data/spec/support/schema.rb +109 -4
- data/squeel.gemspec +8 -6
- metadata +89 -107
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/spec/blueprints/articles.rb +0 -5
- data/spec/blueprints/comments.rb +0 -5
- data/spec/blueprints/notes.rb +0 -3
- data/spec/blueprints/people.rb +0 -4
- 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
|
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
|
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
|
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
|
12
|
-
@j._type.should eq
|
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
|
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,
|
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,
|
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
|
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
|
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\(
|
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
|
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
|
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 '
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
288
|
-
expr.right.to_sql.should match
|
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
|
297
|
-
expr.right.to_sql.should match
|
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
|
306
|
-
expr.right.to_sql.should match
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
@@ -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
|
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\(
|
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\(
|
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
|
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
|
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
|
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
|