squeel 0.5.0 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +115 -39
- data/lib/squeel/adapters/active_record.rb +22 -5
- data/lib/squeel/adapters/active_record/3.0/association_preload.rb +15 -0
- data/lib/squeel/adapters/active_record/3.0/compat.rb +143 -0
- data/lib/squeel/adapters/active_record/3.0/context.rb +67 -0
- data/lib/squeel/adapters/active_record/3.0/join_association.rb +54 -0
- data/lib/squeel/adapters/active_record/3.0/join_dependency.rb +84 -0
- data/lib/squeel/adapters/active_record/3.0/relation.rb +327 -0
- data/lib/squeel/adapters/active_record/context.rb +67 -0
- data/lib/squeel/adapters/active_record/join_association.rb +10 -56
- data/lib/squeel/adapters/active_record/join_dependency.rb +22 -7
- data/lib/squeel/adapters/active_record/preloader.rb +21 -0
- data/lib/squeel/adapters/active_record/relation.rb +84 -38
- data/lib/squeel/context.rb +38 -0
- data/lib/squeel/dsl.rb +1 -1
- data/lib/squeel/nodes/join.rb +18 -0
- data/lib/squeel/nodes/key_path.rb +2 -2
- data/lib/squeel/nodes/stub.rb +5 -1
- data/lib/squeel/version.rb +1 -1
- data/lib/squeel/visitors.rb +2 -2
- data/lib/squeel/visitors/{order_visitor.rb → attribute_visitor.rb} +1 -2
- data/lib/squeel/visitors/predicate_visitor.rb +13 -11
- data/lib/squeel/visitors/symbol_visitor.rb +48 -0
- data/spec/helpers/squeel_helper.rb +17 -1
- data/spec/spec_helper.rb +31 -0
- data/spec/squeel/adapters/active_record/context_spec.rb +50 -0
- data/spec/squeel/adapters/active_record/join_association_spec.rb +1 -1
- data/spec/squeel/adapters/active_record/join_depdendency_spec.rb +1 -1
- data/spec/squeel/adapters/active_record/relation_spec.rb +166 -25
- data/spec/squeel/dsl_spec.rb +6 -6
- data/spec/squeel/nodes/join_spec.rb +16 -3
- data/spec/squeel/nodes/stub_spec.rb +12 -0
- data/spec/squeel/visitors/{order_visitor_spec.rb → attribute_visitor_spec.rb} +4 -5
- data/spec/squeel/visitors/predicate_visitor_spec.rb +18 -6
- data/spec/squeel/visitors/symbol_visitor_spec.rb +42 -0
- data/squeel.gemspec +2 -2
- metadata +21 -13
- data/lib/squeel/contexts/join_dependency_context.rb +0 -74
- data/lib/squeel/visitors/select_visitor.rb +0 -103
- data/spec/squeel/contexts/join_dependency_context_spec.rb +0 -43
- data/spec/squeel/visitors/select_visitor_spec.rb +0 -115
data/spec/squeel/dsl_spec.rb
CHANGED
@@ -4,25 +4,25 @@ module Squeel
|
|
4
4
|
describe DSL do
|
5
5
|
|
6
6
|
it 'evaluates code' do
|
7
|
-
result = DSL.
|
7
|
+
result = DSL.eval { {id => 1} }
|
8
8
|
result.should be_a Hash
|
9
9
|
result.keys.first.should be_a Nodes::Stub
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'creates function nodes when a method has arguments' do
|
13
|
-
result = DSL.
|
13
|
+
result = DSL.eval { max(id) }
|
14
14
|
result.should be_a Nodes::Function
|
15
15
|
result.args.should eq [Nodes::Stub.new(:id)]
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'creates polymorphic join nodes when a method has a single class argument' do
|
19
|
-
result = DSL.
|
19
|
+
result = DSL.eval { association(Person) }
|
20
20
|
result.should be_a Nodes::Join
|
21
21
|
result.klass.should eq Person
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'handles OR between predicates' do
|
25
|
-
result = DSL.
|
25
|
+
result = DSL.eval {(name =~ 'Joe%') | (articles.title =~ 'Hello%')}
|
26
26
|
result.should be_a Nodes::Or
|
27
27
|
result.left.should be_a Nodes::Predicate
|
28
28
|
result.right.should be_a Nodes::KeyPath
|
@@ -36,7 +36,7 @@ module Squeel
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def dsl_test
|
39
|
-
DSL.
|
39
|
+
DSL.eval {name =~ a_method}
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -56,7 +56,7 @@ module Squeel
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def dsl_test
|
59
|
-
DSL.
|
59
|
+
DSL.eval {|q| q.name =~ a_method}
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -4,24 +4,37 @@ module Squeel
|
|
4
4
|
module Nodes
|
5
5
|
describe Join do
|
6
6
|
|
7
|
-
|
7
|
+
before do
|
8
8
|
@j = Join.new :name
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'defaults to Arel::InnerJoin' do
|
9
12
|
@j.type.should eq Arel::InnerJoin
|
10
13
|
end
|
11
14
|
|
12
15
|
it 'allows setting join type' do
|
13
|
-
@j = Join.new :name
|
14
16
|
@j.outer
|
15
17
|
@j.type.should eq Arel::OuterJoin
|
16
18
|
end
|
17
19
|
|
18
20
|
it 'allows setting polymorphic class' do
|
19
|
-
@j = Join.new :name
|
20
21
|
@j.klass = Person
|
21
22
|
@j.should be_polymorphic
|
22
23
|
@j.klass.should eq Person
|
23
24
|
end
|
24
25
|
|
26
|
+
it 'creates a KeyPath when sent an unknown method' do
|
27
|
+
keypath = @j.another
|
28
|
+
keypath.should be_a KeyPath
|
29
|
+
keypath.path_with_endpoint.should eq [@j, Stub.new(:another)]
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'creates a KeyPath with a join endpoint when sent a method with a Class param' do
|
33
|
+
keypath = @j.another(Person)
|
34
|
+
keypath.should be_a KeyPath
|
35
|
+
keypath.path_with_endpoint.should eq [@j, Join.new(:another, Arel::InnerJoin, Person)]
|
36
|
+
end
|
37
|
+
|
25
38
|
end
|
26
39
|
end
|
27
40
|
end
|
@@ -27,6 +27,18 @@ module Squeel
|
|
27
27
|
merged[Stub.new(:attribute)].should eq 2
|
28
28
|
end
|
29
29
|
|
30
|
+
it 'creates a KeyPath when sent an unknown method' do
|
31
|
+
keypath = @s.another
|
32
|
+
keypath.should be_a KeyPath
|
33
|
+
keypath.path_with_endpoint.should eq [@s, Stub.new(:another)]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'creates a KeyPath with a join endpoint when sent a method with a Class param' do
|
37
|
+
keypath = @s.another(Person)
|
38
|
+
keypath.should be_a KeyPath
|
39
|
+
keypath.path_with_endpoint.should eq [@s, Join.new(:another, Arel::InnerJoin, Person)]
|
40
|
+
end
|
41
|
+
|
30
42
|
Squeel::Constants::PREDICATES.each do |method_name|
|
31
43
|
it "creates #{method_name} predicates with no value" do
|
32
44
|
predicate = @s.send(method_name)
|
@@ -1,18 +1,17 @@
|
|
1
1
|
module Squeel
|
2
2
|
module Visitors
|
3
|
-
describe
|
3
|
+
describe AttributeVisitor do
|
4
4
|
|
5
5
|
before do
|
6
|
-
@jd =
|
7
|
-
new(Person, {
|
6
|
+
@jd = new_join_dependency(Person, {
|
8
7
|
:children => {
|
9
8
|
:children => {
|
10
9
|
:parent => :parent
|
11
10
|
}
|
12
11
|
}
|
13
12
|
}, [])
|
14
|
-
@c = Squeel::
|
15
|
-
@v =
|
13
|
+
@c = Squeel::Adapters::ActiveRecord::Context.new(@jd)
|
14
|
+
@v = AttributeVisitor.new(@c)
|
16
15
|
end
|
17
16
|
|
18
17
|
it 'creates a bare ARel attribute given a symbol with no asc/desc' do
|
@@ -5,15 +5,14 @@ module Squeel
|
|
5
5
|
describe PredicateVisitor do
|
6
6
|
|
7
7
|
before do
|
8
|
-
@jd =
|
9
|
-
new(Person, {
|
8
|
+
@jd = new_join_dependency(Person, {
|
10
9
|
:children => {
|
11
10
|
:children => {
|
12
11
|
:parent => :parent
|
13
12
|
}
|
14
13
|
}
|
15
14
|
}, [])
|
16
|
-
@c = Squeel::
|
15
|
+
@c = Squeel::Adapters::ActiveRecord::Context.new(@jd)
|
17
16
|
@v = PredicateVisitor.new(@c)
|
18
17
|
end
|
19
18
|
|
@@ -136,6 +135,20 @@ module Squeel
|
|
136
135
|
predicate.to_sql.should match /"people"."name" = "children_people"."name"/
|
137
136
|
end
|
138
137
|
|
138
|
+
it 'visits ActiveRecord::Relation values in predicates' do
|
139
|
+
predicate = @v.accept(dsl{id >> Person.select{id}.limit(3).order{id.desc}})
|
140
|
+
predicate.should be_a Arel::Nodes::In
|
141
|
+
predicate.right.should be_a Arel::Nodes::SelectStatement
|
142
|
+
predicate.to_sql.should be_like '"people"."id" IN (SELECT "people"."id" FROM "people" ORDER BY "people"."id" DESC LIMIT 3)'
|
143
|
+
end
|
144
|
+
|
145
|
+
it "doesn't try to sanitize_sql an array of strings in the value of a Predicate" do
|
146
|
+
predicate = @v.accept(dsl{name >> ['Aric Smith', 'Gladyce Kulas']})
|
147
|
+
predicate.should be_a Arel::Nodes::In
|
148
|
+
predicate.right.should be_an Array
|
149
|
+
predicate.to_sql.should match /"people"."name" IN \('Aric Smith', 'Gladyce Kulas'\)/
|
150
|
+
end
|
151
|
+
|
139
152
|
it 'creates a node of the proper type when a hash has a Predicate as a key' do
|
140
153
|
predicate = @v.accept(:name.matches => 'Joe%')
|
141
154
|
predicate.should be_a Arel::Nodes::Matches
|
@@ -248,9 +261,8 @@ module Squeel
|
|
248
261
|
|
249
262
|
context 'with polymorphic joins in the JoinDependency' do
|
250
263
|
before do
|
251
|
-
@jd =
|
252
|
-
|
253
|
-
@c = Squeel::Contexts::JoinDependencyContext.new(@jd)
|
264
|
+
@jd = new_join_dependency(Note, dsl{[notable(Article), notable(Person)]}, [])
|
265
|
+
@c = Squeel::Adapters::ActiveRecord::Context.new(@jd)
|
254
266
|
@v = PredicateVisitor.new(@c)
|
255
267
|
end
|
256
268
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Squeel
|
4
|
+
module Visitors
|
5
|
+
describe SymbolVisitor do
|
6
|
+
before do
|
7
|
+
@v = SymbolVisitor.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns symbols unmodified' do
|
11
|
+
@v.accept(:blah).should eq :blah
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'converts stubs to symbols' do
|
15
|
+
@v.accept(dsl{blah}).should eq :blah
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'converts joins to their names' do
|
19
|
+
@v.accept(dsl{blah(Article)}).should eq :blah
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'converts keypaths to their hash equivalents' do
|
23
|
+
@v.accept(dsl{one.two.three.four}).should eq({
|
24
|
+
:one => {:two => {:three => :four}}
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'visits hashes' do
|
29
|
+
@v.accept(dsl{{
|
30
|
+
blah1 => {blah2(Article) => blah3}
|
31
|
+
}}).should eq({:blah1 => {:blah2 => :blah3}})
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'visits arrays' do
|
35
|
+
@v.accept(dsl{[{
|
36
|
+
blah1 => {blah2(Article) => blah3}
|
37
|
+
}]}).should eq([{:blah1 => {:blah2 => :blah3}}])
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/squeel.gemspec
CHANGED
@@ -30,8 +30,8 @@ you're feeling especially appreciative. It'd help me justify this
|
|
30
30
|
|
31
31
|
s.rubyforge_project = "squeel"
|
32
32
|
|
33
|
-
s.add_dependency 'activerecord', '~> 3.
|
34
|
-
s.add_dependency 'activesupport', '~> 3.
|
33
|
+
s.add_dependency 'activerecord', '~> 3.0'
|
34
|
+
s.add_dependency 'activesupport', '~> 3.0'
|
35
35
|
s.add_development_dependency 'rspec', '~> 2.5.0'
|
36
36
|
s.add_development_dependency 'machinist', '~> 1.0.6'
|
37
37
|
s.add_development_dependency 'faker', '~> 0.9.5'
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: squeel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.5.
|
5
|
+
version: 0.5.5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ernie Miller
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-20 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 3.
|
23
|
+
version: "3.0"
|
24
24
|
type: :runtime
|
25
25
|
version_requirements: *id001
|
26
26
|
- !ruby/object:Gem::Dependency
|
@@ -31,7 +31,7 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 3.
|
34
|
+
version: "3.0"
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id002
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -97,12 +97,20 @@ files:
|
|
97
97
|
- lib/core_ext/symbol.rb
|
98
98
|
- lib/squeel.rb
|
99
99
|
- lib/squeel/adapters/active_record.rb
|
100
|
+
- lib/squeel/adapters/active_record/3.0/association_preload.rb
|
101
|
+
- lib/squeel/adapters/active_record/3.0/compat.rb
|
102
|
+
- lib/squeel/adapters/active_record/3.0/context.rb
|
103
|
+
- lib/squeel/adapters/active_record/3.0/join_association.rb
|
104
|
+
- lib/squeel/adapters/active_record/3.0/join_dependency.rb
|
105
|
+
- lib/squeel/adapters/active_record/3.0/relation.rb
|
106
|
+
- lib/squeel/adapters/active_record/context.rb
|
100
107
|
- lib/squeel/adapters/active_record/join_association.rb
|
101
108
|
- lib/squeel/adapters/active_record/join_dependency.rb
|
109
|
+
- lib/squeel/adapters/active_record/preloader.rb
|
102
110
|
- lib/squeel/adapters/active_record/relation.rb
|
103
111
|
- lib/squeel/configuration.rb
|
104
112
|
- lib/squeel/constants.rb
|
105
|
-
- lib/squeel/
|
113
|
+
- lib/squeel/context.rb
|
106
114
|
- lib/squeel/dsl.rb
|
107
115
|
- lib/squeel/nodes.rb
|
108
116
|
- lib/squeel/nodes/and.rb
|
@@ -127,10 +135,10 @@ files:
|
|
127
135
|
- lib/squeel/predicate_methods/symbol.rb
|
128
136
|
- lib/squeel/version.rb
|
129
137
|
- lib/squeel/visitors.rb
|
138
|
+
- lib/squeel/visitors/attribute_visitor.rb
|
130
139
|
- lib/squeel/visitors/base.rb
|
131
|
-
- lib/squeel/visitors/order_visitor.rb
|
132
140
|
- lib/squeel/visitors/predicate_visitor.rb
|
133
|
-
- lib/squeel/visitors/
|
141
|
+
- lib/squeel/visitors/symbol_visitor.rb
|
134
142
|
- spec/blueprints/articles.rb
|
135
143
|
- spec/blueprints/comments.rb
|
136
144
|
- spec/blueprints/notes.rb
|
@@ -140,10 +148,10 @@ files:
|
|
140
148
|
- spec/core_ext/symbol_spec.rb
|
141
149
|
- spec/helpers/squeel_helper.rb
|
142
150
|
- spec/spec_helper.rb
|
151
|
+
- spec/squeel/adapters/active_record/context_spec.rb
|
143
152
|
- spec/squeel/adapters/active_record/join_association_spec.rb
|
144
153
|
- spec/squeel/adapters/active_record/join_depdendency_spec.rb
|
145
154
|
- spec/squeel/adapters/active_record/relation_spec.rb
|
146
|
-
- spec/squeel/contexts/join_dependency_context_spec.rb
|
147
155
|
- spec/squeel/dsl_spec.rb
|
148
156
|
- spec/squeel/nodes/function_spec.rb
|
149
157
|
- spec/squeel/nodes/join_spec.rb
|
@@ -154,9 +162,9 @@ files:
|
|
154
162
|
- spec/squeel/nodes/predicate_operators_spec.rb
|
155
163
|
- spec/squeel/nodes/predicate_spec.rb
|
156
164
|
- spec/squeel/nodes/stub_spec.rb
|
157
|
-
- spec/squeel/visitors/
|
165
|
+
- spec/squeel/visitors/attribute_visitor_spec.rb
|
158
166
|
- spec/squeel/visitors/predicate_visitor_spec.rb
|
159
|
-
- spec/squeel/visitors/
|
167
|
+
- spec/squeel/visitors/symbol_visitor_spec.rb
|
160
168
|
- spec/support/schema.rb
|
161
169
|
- squeel.gemspec
|
162
170
|
homepage: http://metautonomo.us/projects/squeel
|
@@ -201,10 +209,10 @@ test_files:
|
|
201
209
|
- spec/core_ext/symbol_spec.rb
|
202
210
|
- spec/helpers/squeel_helper.rb
|
203
211
|
- spec/spec_helper.rb
|
212
|
+
- spec/squeel/adapters/active_record/context_spec.rb
|
204
213
|
- spec/squeel/adapters/active_record/join_association_spec.rb
|
205
214
|
- spec/squeel/adapters/active_record/join_depdendency_spec.rb
|
206
215
|
- spec/squeel/adapters/active_record/relation_spec.rb
|
207
|
-
- spec/squeel/contexts/join_dependency_context_spec.rb
|
208
216
|
- spec/squeel/dsl_spec.rb
|
209
217
|
- spec/squeel/nodes/function_spec.rb
|
210
218
|
- spec/squeel/nodes/join_spec.rb
|
@@ -215,7 +223,7 @@ test_files:
|
|
215
223
|
- spec/squeel/nodes/predicate_operators_spec.rb
|
216
224
|
- spec/squeel/nodes/predicate_spec.rb
|
217
225
|
- spec/squeel/nodes/stub_spec.rb
|
218
|
-
- spec/squeel/visitors/
|
226
|
+
- spec/squeel/visitors/attribute_visitor_spec.rb
|
219
227
|
- spec/squeel/visitors/predicate_visitor_spec.rb
|
220
|
-
- spec/squeel/visitors/
|
228
|
+
- spec/squeel/visitors/symbol_visitor_spec.rb
|
221
229
|
- spec/support/schema.rb
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
|
3
|
-
module Squeel
|
4
|
-
# Because the AR::Associations namespace is insane
|
5
|
-
JoinPart = ActiveRecord::Associations::JoinDependency::JoinPart
|
6
|
-
|
7
|
-
module Contexts
|
8
|
-
class JoinDependencyContext
|
9
|
-
attr_reader :base, :engine, :arel_visitor
|
10
|
-
|
11
|
-
def initialize(join_dependency)
|
12
|
-
@join_dependency = join_dependency
|
13
|
-
@base = join_dependency.join_base
|
14
|
-
@engine = @base.arel_engine
|
15
|
-
@arel_visitor = Arel::Visitors.visitor_for @engine
|
16
|
-
@default_table = Arel::Table.new(@base.table_name, :as => @base.aliased_table_name, :engine => @engine)
|
17
|
-
@tables = Hash.new {|hash, key| hash[key] = get_table(key)}
|
18
|
-
end
|
19
|
-
|
20
|
-
def find(object, parent = @base)
|
21
|
-
if JoinPart === parent
|
22
|
-
object = object.to_sym if String === object
|
23
|
-
case object
|
24
|
-
when Symbol, Nodes::Stub
|
25
|
-
@join_dependency.join_associations.detect { |j|
|
26
|
-
j.reflection.name == object.to_sym && j.parent == parent
|
27
|
-
}
|
28
|
-
when Nodes::Join
|
29
|
-
@join_dependency.join_associations.detect { |j|
|
30
|
-
j.reflection.name == object.name && j.parent == parent &&
|
31
|
-
(object.polymorphic? ? j.reflection.klass == object.klass : true)
|
32
|
-
}
|
33
|
-
else
|
34
|
-
@join_dependency.join_associations.detect { |j|
|
35
|
-
j.reflection == object && j.parent == parent
|
36
|
-
}
|
37
|
-
end
|
38
|
-
else
|
39
|
-
nil
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def traverse(keypath, parent = @base, include_endpoint = false)
|
44
|
-
parent = @base if keypath.absolute?
|
45
|
-
keypath.path.each do |key|
|
46
|
-
parent = find(key, parent)
|
47
|
-
end
|
48
|
-
parent = find(keypath.endpoint, parent) if include_endpoint
|
49
|
-
|
50
|
-
parent
|
51
|
-
end
|
52
|
-
|
53
|
-
def contextualize(object)
|
54
|
-
@tables[object]
|
55
|
-
end
|
56
|
-
|
57
|
-
def sanitize_sql(conditions, parent)
|
58
|
-
parent.active_record.send(:sanitize_sql, conditions, parent.aliased_table_name)
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def get_table(object)
|
64
|
-
if [Symbol, Nodes::Stub].include?(object.class)
|
65
|
-
Arel::Table.new(object.to_sym, :engine => @engine)
|
66
|
-
elsif object.respond_to?(:aliased_table_name)
|
67
|
-
Arel::Table.new(object.table_name, :as => object.aliased_table_name, :engine => @engine)
|
68
|
-
else
|
69
|
-
@default_table
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,103 +0,0 @@
|
|
1
|
-
require 'squeel/visitors/base'
|
2
|
-
require 'squeel/contexts/join_dependency_context'
|
3
|
-
|
4
|
-
module Squeel
|
5
|
-
module Visitors
|
6
|
-
class SelectVisitor < Base
|
7
|
-
|
8
|
-
def visit_Hash(o, parent)
|
9
|
-
o.map do |k, v|
|
10
|
-
if implies_context_change?(v)
|
11
|
-
visit_with_context_change(k, v, parent)
|
12
|
-
else
|
13
|
-
visit_without_context_change(k, v, parent)
|
14
|
-
end
|
15
|
-
end.flatten
|
16
|
-
end
|
17
|
-
|
18
|
-
def implies_context_change?(v)
|
19
|
-
Hash === v || can_accept?(v) ||
|
20
|
-
(Array === v && !v.empty? && v.all? {|val| can_accept?(val)})
|
21
|
-
end
|
22
|
-
|
23
|
-
def visit_with_context_change(k, v, parent)
|
24
|
-
parent = case k
|
25
|
-
when Nodes::KeyPath
|
26
|
-
traverse(k, parent, true)
|
27
|
-
else
|
28
|
-
find(k, parent)
|
29
|
-
end
|
30
|
-
|
31
|
-
if Array === v
|
32
|
-
v.map {|val| accept(val, parent || k)}
|
33
|
-
else
|
34
|
-
can_accept?(v) ? accept(v, parent || k) : v
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def visit_without_context_change(k, v, parent)
|
39
|
-
v
|
40
|
-
end
|
41
|
-
|
42
|
-
def visit_Array(o, parent)
|
43
|
-
o.map { |v| can_accept?(v) ? accept(v, parent) : v }.flatten
|
44
|
-
end
|
45
|
-
|
46
|
-
def visit_Symbol(o, parent)
|
47
|
-
contextualize(parent)[o]
|
48
|
-
end
|
49
|
-
|
50
|
-
def visit_Squeel_Nodes_Stub(o, parent)
|
51
|
-
contextualize(parent)[o.symbol]
|
52
|
-
end
|
53
|
-
|
54
|
-
def visit_Squeel_Nodes_KeyPath(o, parent)
|
55
|
-
parent = traverse(o, parent)
|
56
|
-
|
57
|
-
accept(o.endpoint, parent)
|
58
|
-
end
|
59
|
-
|
60
|
-
def visit_Squeel_Nodes_Function(o, parent)
|
61
|
-
args = o.args.map do |arg|
|
62
|
-
case arg
|
63
|
-
when Nodes::Function, Nodes::KeyPath
|
64
|
-
accept(arg, parent)
|
65
|
-
when Symbol, Nodes::Stub
|
66
|
-
Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
|
67
|
-
else
|
68
|
-
quoted?(arg) ? Arel.sql(arel_visitor.accept arg) : arg
|
69
|
-
end
|
70
|
-
end
|
71
|
-
Arel::Nodes::NamedFunction.new(o.name, args, o.alias)
|
72
|
-
end
|
73
|
-
|
74
|
-
def visit_Squeel_Nodes_Operation(o, parent)
|
75
|
-
args = o.args.map do |arg|
|
76
|
-
case arg
|
77
|
-
when Nodes::Function
|
78
|
-
accept(arg, parent)
|
79
|
-
when Symbol, Nodes::Stub
|
80
|
-
Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
|
81
|
-
else
|
82
|
-
quoted?(arg) ? Arel.sql(arel_visitor.accept arg) : arg
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
op = case o.operator
|
87
|
-
when :+
|
88
|
-
Arel::Nodes::Addition.new(args[0], args[1])
|
89
|
-
when :-
|
90
|
-
Arel::Nodes::Subtraction.new(args[0], args[1])
|
91
|
-
when :*
|
92
|
-
Arel::Nodes::Multiplication.new(args[0], args[1])
|
93
|
-
when :/
|
94
|
-
Arel::Nodes::Division.new(args[0], args[1])
|
95
|
-
else
|
96
|
-
Arel.sql("#{arel_visitor.accept(args[0])} #{o.operator} #{arel_visitor.accept(args[1])}")
|
97
|
-
end
|
98
|
-
o.alias ? op.as(o.alias) : op
|
99
|
-
end
|
100
|
-
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|