squeel 0.8.0 → 0.8.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.
- data/lib/squeel/adapters/active_record.rb +2 -0
- data/lib/squeel/adapters/active_record/3.0/compat.rb +11 -0
- data/lib/squeel/adapters/active_record/relation.rb +1 -1
- data/lib/squeel/nodes/as.rb +3 -0
- data/lib/squeel/version.rb +1 -1
- data/lib/squeel/visitors/attribute_visitor.rb +9 -0
- data/lib/squeel/visitors/predicate_visitor.rb +2 -0
- data/spec/squeel/adapters/active_record/relation_spec.rb +19 -0
- data/spec/squeel/core_ext/symbol_spec.rb +58 -0
- data/spec/squeel/visitors/attribute_visitor_spec.rb +6 -0
- data/spec/squeel/visitors/predicate_visitor_spec.rb +7 -0
- metadata +16 -14
@@ -1,5 +1,11 @@
|
|
1
1
|
module Arel
|
2
2
|
|
3
|
+
class SelectManager
|
4
|
+
def as other
|
5
|
+
Nodes::TableAlias.new Nodes::SqlLiteral.new(other), Nodes::Grouping.new(@ast)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
class Table
|
4
10
|
alias :table_name :name
|
5
11
|
|
@@ -130,6 +136,11 @@ module Arel
|
|
130
136
|
end
|
131
137
|
}.join ', '})"
|
132
138
|
end
|
139
|
+
|
140
|
+
def quote_table_name name
|
141
|
+
return name if Arel::Nodes::SqlLiteral === name
|
142
|
+
@quoted_tables[name] ||= @connection.quote_table_name(name)
|
143
|
+
end
|
133
144
|
end
|
134
145
|
end
|
135
146
|
|
@@ -101,7 +101,7 @@ module Squeel
|
|
101
101
|
end
|
102
102
|
|
103
103
|
# reverse_sql_order doesn't understand ARel ordering nodes, so we
|
104
|
-
# need to convert them to their corresponding SQL
|
104
|
+
# need to convert them to their corresponding SQL (for now)
|
105
105
|
def sqlify_order(order)
|
106
106
|
order.map do |o|
|
107
107
|
o.respond_to?(:to_sql) ? o.to_sql : o
|
data/lib/squeel/nodes/as.rb
CHANGED
@@ -4,6 +4,9 @@ module Squeel
|
|
4
4
|
module Nodes
|
5
5
|
# A node representing an SQL alias, which will result in same when visited.
|
6
6
|
class As < Binary
|
7
|
+
alias :expr :left
|
8
|
+
alias :alias :right
|
9
|
+
|
7
10
|
# @param left The node to be aliased
|
8
11
|
# @param right The alias name
|
9
12
|
def initialize(left, right)
|
data/lib/squeel/version.rb
CHANGED
@@ -145,6 +145,15 @@ module Squeel
|
|
145
145
|
accept(o.left, parent).as(o.right)
|
146
146
|
end
|
147
147
|
|
148
|
+
# Visit an ActiveRecord Relation, returning an Arel::SelectManager
|
149
|
+
# @param [ActiveRecord::Relation] o The Relation to visit
|
150
|
+
# @param parent The parent object in the context
|
151
|
+
# @return [Arel::SelectManager] The ARel select manager that represents
|
152
|
+
# the relation's query
|
153
|
+
def visit_ActiveRecord_Relation(o, parent)
|
154
|
+
o.arel
|
155
|
+
end
|
156
|
+
|
148
157
|
# @return [Boolean] Whether the given value implies a context change
|
149
158
|
# @param v The value to consider
|
150
159
|
def implies_context_change?(v)
|
@@ -115,6 +115,8 @@ module Squeel
|
|
115
115
|
case arg
|
116
116
|
when Nodes::Function
|
117
117
|
accept(arg, parent)
|
118
|
+
when ActiveRecord::Relation
|
119
|
+
arg.arel.ast
|
118
120
|
when Nodes::KeyPath
|
119
121
|
can_accept?(arg.endpoint) ? accept(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_sym]
|
120
122
|
when Symbol, Nodes::Stub
|
@@ -366,6 +366,13 @@ module Squeel
|
|
366
366
|
relation.first.flanderized_name.should eq 'Aric Smith-diddly'
|
367
367
|
end
|
368
368
|
|
369
|
+
it 'allows a subquery in the select values' do
|
370
|
+
subquery = Article.where(:person_id => 1).select(:id).order{id.desc}.limit(1)
|
371
|
+
relation = Person.where(:id => 1).select{[id, name, subquery.as('last_article_id')]}
|
372
|
+
aric = relation.first
|
373
|
+
aric.last_article_id.should eq Article.where(:person_id => 1).last.id
|
374
|
+
end
|
375
|
+
|
369
376
|
end
|
370
377
|
|
371
378
|
describe '#group' do
|
@@ -583,6 +590,18 @@ module Squeel
|
|
583
590
|
|
584
591
|
end
|
585
592
|
|
593
|
+
describe '#as' do
|
594
|
+
|
595
|
+
it 'aliases the relation in an As node' do
|
596
|
+
relation = Person.where{name == 'ernie'}
|
597
|
+
node = relation.as('ernie')
|
598
|
+
node.should be_a Squeel::Nodes::As
|
599
|
+
node.expr.should eq relation
|
600
|
+
node.alias.should eq 'ernie'
|
601
|
+
end
|
602
|
+
|
603
|
+
end
|
604
|
+
|
586
605
|
describe '#merge' do
|
587
606
|
|
588
607
|
it 'merges relations with the same base' do
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Symbol do
|
4
|
+
describe '#asc' do
|
5
|
+
it 'creates an ascending order node' do
|
6
|
+
order = :blah.asc
|
7
|
+
order.should be_a Squeel::Nodes::Order
|
8
|
+
order.expr.should eq :blah
|
9
|
+
order.should be_ascending
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#desc' do
|
14
|
+
it 'creates a descending order node' do
|
15
|
+
order = :blah.desc
|
16
|
+
order.should be_a Squeel::Nodes::Order
|
17
|
+
order.expr.should eq :blah
|
18
|
+
order.should be_descending
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#func' do
|
23
|
+
it 'creates a function node' do
|
24
|
+
function = :blah.func('foo')
|
25
|
+
function.should be_a Squeel::Nodes::Function
|
26
|
+
function.name.should eq :blah
|
27
|
+
function.args.should eq ['foo']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#inner' do
|
32
|
+
it 'creates an inner join' do
|
33
|
+
join = :blah.inner
|
34
|
+
join.should be_a Squeel::Nodes::Join
|
35
|
+
join._name.should eq :blah
|
36
|
+
join._type.should eq Arel::InnerJoin
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#outer' do
|
41
|
+
it 'creates an outer join' do
|
42
|
+
join = :blah.outer
|
43
|
+
join.should be_a Squeel::Nodes::Join
|
44
|
+
join._name.should eq :blah
|
45
|
+
join._type.should eq Arel::OuterJoin
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#of_class' do
|
50
|
+
it 'creates an inner polymorphic join with the given class' do
|
51
|
+
join = :blah.of_class(Person)
|
52
|
+
join.should be_a Squeel::Nodes::Join
|
53
|
+
join._name.should eq :blah
|
54
|
+
join._type.should eq Arel::InnerJoin
|
55
|
+
join._klass.should eq Person
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -67,6 +67,12 @@ module Squeel
|
|
67
67
|
ordering.direction.should eq :asc
|
68
68
|
end
|
69
69
|
|
70
|
+
it 'allows a subquery as a selection' do
|
71
|
+
relation = Person.where(:name => 'Aric Smith').select(:id)
|
72
|
+
node = @v.accept(relation.as('aric'))
|
73
|
+
node.to_sql.should be_like "(SELECT \"people\".\"id\" FROM \"people\" WHERE \"people\".\"name\" = 'Aric Smith') aric"
|
74
|
+
end
|
75
|
+
|
70
76
|
it 'creates an ARel NamedFunction node for a Function node' do
|
71
77
|
function = @v.accept(:find_in_set.func())
|
72
78
|
function.should be_a Arel::Nodes::NamedFunction
|
@@ -207,6 +207,13 @@ module Squeel
|
|
207
207
|
predicate.to_sql.should be_like '"people"."id" IN (SELECT "people"."id" FROM "people" ORDER BY "people"."id" DESC LIMIT 3)'
|
208
208
|
end
|
209
209
|
|
210
|
+
it 'converts ActiveRecord::Relation values in function arguments to their ARel AST' do
|
211
|
+
predicate = @v.accept(dsl{exists(Person.where{name == 'Aric Smith'})})
|
212
|
+
predicate.should be_a Arel::Nodes::NamedFunction
|
213
|
+
predicate.expressions.first.should be_a Arel::Nodes::SelectStatement
|
214
|
+
predicate.to_sql.should be_like "exists(SELECT \"people\".* FROM \"people\" WHERE \"people\".\"name\" = 'Aric Smith')"
|
215
|
+
end
|
216
|
+
|
210
217
|
it "doesn't try to sanitize_sql an array of strings in the value of a Predicate" do
|
211
218
|
predicate = @v.accept(dsl{name >> ['Aric Smith', 'Gladyce Kulas']})
|
212
219
|
predicate.should be_a Arel::Nodes::In
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squeel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-06-
|
12
|
+
date: 2011-06-16 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153932760 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153932760
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153932260 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153932260
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &2153931800 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.5.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2153931800
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: machinist
|
49
|
-
requirement: &
|
49
|
+
requirement: &2153931340 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.0.6
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2153931340
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: faker
|
60
|
-
requirement: &
|
60
|
+
requirement: &2153930880 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 0.9.5
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2153930880
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: sqlite3
|
71
|
-
requirement: &
|
71
|
+
requirement: &2153961900 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: 1.3.3
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *2153961900
|
80
80
|
description: ! "\n Squeel unlocks the power of ARel in your Rails 3 application
|
81
81
|
with\n a handy block-based syntax. You can write subqueries, access named\n
|
82
82
|
\ functions provided by your RDBMS, and more, all without writing\n SQL
|
@@ -150,6 +150,7 @@ files:
|
|
150
150
|
- spec/squeel/adapters/active_record/join_association_spec.rb
|
151
151
|
- spec/squeel/adapters/active_record/join_dependency_spec.rb
|
152
152
|
- spec/squeel/adapters/active_record/relation_spec.rb
|
153
|
+
- spec/squeel/core_ext/symbol_spec.rb
|
153
154
|
- spec/squeel/dsl_spec.rb
|
154
155
|
- spec/squeel/nodes/function_spec.rb
|
155
156
|
- spec/squeel/nodes/join_spec.rb
|
@@ -216,6 +217,7 @@ test_files:
|
|
216
217
|
- spec/squeel/adapters/active_record/join_association_spec.rb
|
217
218
|
- spec/squeel/adapters/active_record/join_dependency_spec.rb
|
218
219
|
- spec/squeel/adapters/active_record/relation_spec.rb
|
220
|
+
- spec/squeel/core_ext/symbol_spec.rb
|
219
221
|
- spec/squeel/dsl_spec.rb
|
220
222
|
- spec/squeel/nodes/function_spec.rb
|
221
223
|
- spec/squeel/nodes/join_spec.rb
|