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