squeel 0.5.0 → 0.5.5
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.
- 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
|