squeel 1.0.9 → 1.0.11

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.
Files changed (46) hide show
  1. data/CHANGELOG.md +10 -0
  2. data/lib/squeel.rb +5 -0
  3. data/lib/squeel/adapters/active_record/3.0/association_preload_extensions.rb +2 -2
  4. data/lib/squeel/adapters/active_record/3.0/relation_extensions.rb +98 -46
  5. data/lib/squeel/adapters/active_record/3.1/preloader_extensions.rb +2 -2
  6. data/lib/squeel/adapters/active_record/3.1/relation_extensions.rb +71 -85
  7. data/lib/squeel/adapters/active_record/base_extensions.rb +0 -19
  8. data/lib/squeel/adapters/active_record/relation_extensions.rb +6 -9
  9. data/lib/squeel/nodes/binary.rb +4 -0
  10. data/lib/squeel/nodes/function.rb +10 -0
  11. data/lib/squeel/nodes/nary.rb +1 -1
  12. data/lib/squeel/nodes/order.rb +11 -1
  13. data/lib/squeel/nodes/predicate.rb +2 -2
  14. data/lib/squeel/nodes/stub.rb +2 -0
  15. data/lib/squeel/nodes/unary.rb +4 -0
  16. data/lib/squeel/version.rb +1 -1
  17. data/lib/squeel/visitors.rb +10 -3
  18. data/lib/squeel/visitors/from_visitor.rb +6 -0
  19. data/lib/squeel/visitors/group_visitor.rb +6 -0
  20. data/lib/squeel/visitors/having_visitor.rb +9 -0
  21. data/lib/squeel/visitors/order_visitor.rb +20 -0
  22. data/lib/squeel/visitors/predicate_visitation.rb +126 -0
  23. data/lib/squeel/visitors/predicate_visitor.rb +3 -326
  24. data/lib/squeel/visitors/{symbol_visitor.rb → preload_visitor.rb} +4 -4
  25. data/lib/squeel/visitors/select_visitor.rb +7 -0
  26. data/lib/squeel/visitors/visitor.rb +244 -12
  27. data/lib/squeel/visitors/where_visitor.rb +8 -0
  28. data/spec/helpers/squeel_helper.rb +14 -1
  29. data/spec/squeel/adapters/active_record/relation_extensions_spec.rb +65 -49
  30. data/spec/squeel/nodes/as_spec.rb +20 -0
  31. data/spec/squeel/nodes/function_spec.rb +6 -0
  32. data/spec/squeel/nodes/grouping_spec.rb +6 -0
  33. data/spec/squeel/nodes/key_path_spec.rb +3 -3
  34. data/spec/squeel/nodes/operation_spec.rb +6 -0
  35. data/spec/squeel/nodes/order_spec.rb +6 -1
  36. data/spec/squeel/nodes/predicate_operators_spec.rb +1 -1
  37. data/spec/squeel/nodes/predicate_spec.rb +14 -1
  38. data/spec/squeel/nodes/sifter_spec.rb +2 -1
  39. data/spec/squeel/nodes/stub_spec.rb +4 -0
  40. data/spec/squeel/visitors/order_visitor_spec.rb +36 -0
  41. data/spec/squeel/visitors/{symbol_visitor_spec.rb → preload_visitor_spec.rb} +4 -3
  42. data/spec/squeel/visitors/select_visitor_spec.rb +26 -0
  43. data/spec/squeel/visitors/{attribute_visitor_spec.rb → visitor_spec.rb} +23 -37
  44. data/spec/support/models.rb +4 -0
  45. metadata +22 -10
  46. data/lib/squeel/visitors/attribute_visitor.rb +0 -214
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Squeel
4
+ module Nodes
5
+ describe As do
6
+
7
+ subject { As.new 'name', 'alias'}
8
+
9
+ it { should respond_to :& }
10
+ it { should respond_to :| }
11
+ it { should respond_to :-@ }
12
+
13
+ specify { (subject & subject).should be_a And }
14
+ specify { (subject | subject).should be_a Or }
15
+ specify { (-subject).should be_a Not }
16
+ specify { [subject, As.new('name', 'alias')].uniq.should have(1).as }
17
+
18
+ end
19
+ end
20
+ end
@@ -153,6 +153,12 @@ module Squeel
153
153
  negated.expr.should eq @f
154
154
  end
155
155
 
156
+ it 'implements equivalence check' do
157
+ other = Function.new(:function, [1, 2, 3])
158
+ array = [@f, other]
159
+ array.uniq.should have(1).function
160
+ end
161
+
156
162
  end
157
163
  end
158
164
  end
@@ -153,6 +153,12 @@ module Squeel
153
153
  negated.expr.should eq @g
154
154
  end
155
155
 
156
+ it 'implements equivalence check' do
157
+ other = Grouping.new('foo')
158
+ array = [@g, other]
159
+ array.uniq.should have(1).grouping
160
+ end
161
+
156
162
  describe '#as' do
157
163
 
158
164
  it 'aliases the function' do
@@ -20,7 +20,7 @@ module Squeel
20
20
 
21
21
  it 'stops appending once its endpoint is not a Stub' do
22
22
  @k.third.fourth.fifth == 'cinco'
23
- @k.endpoint.should eq Predicate.new(Stub.new(:fifth), :eq, 'cinco')
23
+ @k.endpoint.should eql Predicate.new(Stub.new(:fifth), :eq, 'cinco')
24
24
  expect { @k.another }.to raise_error NoMethodError
25
25
  end
26
26
 
@@ -67,7 +67,7 @@ module Squeel
67
67
  it 'creates AND nodes with & if the endpoint responds to &' do
68
68
  node = @k.third.fourth.eq('Bob') & Stub.new(:attr).eq('Joe')
69
69
  node.should be_a And
70
- node.children.should eq [@k, Stub.new(:attr).eq('Joe')]
70
+ node.children.should eql [@k, Stub.new(:attr).eq('Joe')]
71
71
  end
72
72
 
73
73
  it 'raises NoMethodError with & if the endpoint does not respond to &' do
@@ -78,7 +78,7 @@ module Squeel
78
78
  node = @k.third.fourth.eq('Bob') | Stub.new(:attr).eq('Joe')
79
79
  node.should be_a Or
80
80
  node.left.should eq @k
81
- node.right.should eq Stub.new(:attr).eq('Joe')
81
+ node.right.should eql Stub.new(:attr).eq('Joe')
82
82
  end
83
83
 
84
84
  it 'raises NoMethodError with | if the endpoint does not respond to |' do
@@ -153,6 +153,12 @@ module Squeel
153
153
  negated.expr.should eq @o
154
154
  end
155
155
 
156
+ it 'implements equivalence check' do
157
+ other = dsl{name + 1}
158
+ array = [@o, other]
159
+ array.uniq.should have(1).operation
160
+ end
161
+
156
162
  end
157
163
  end
158
164
  end
@@ -25,6 +25,11 @@ module Squeel
25
25
  @o.should be_descending
26
26
  end
27
27
 
28
+ it 'implements equivalence check' do
29
+ array = [Order.new(:attribute, 1), Order.new(:attribute, 1)]
30
+ array.uniq.should have(1).order
31
+ end
32
+
28
33
  end
29
34
  end
30
- end
35
+ end
@@ -85,4 +85,4 @@ module Squeel
85
85
 
86
86
  end
87
87
  end
88
- end
88
+ end
@@ -45,6 +45,19 @@ module Squeel
45
45
  combined.children.should eq [left, right]
46
46
  end
47
47
 
48
+ it 'implements equivalence check' do
49
+ p1 = dsl{name.eq 'blargh'}
50
+ p2 = dsl{name.eq 'blargh'}
51
+ [p1, p2].uniq.should have(1).predicate
52
+ end
53
+
54
+ it 'can be aliased' do
55
+ aliased = dsl{(name == 'joe').as('zomg_its_joe')}
56
+ aliased.should be_a Squeel::Nodes::As
57
+ aliased.left.should eql dsl{(name == 'joe')}
58
+ aliased.right.should eq 'zomg_its_joe'
59
+ end
60
+
48
61
  end
49
62
  end
50
- end
63
+ end
@@ -16,7 +16,8 @@ module Squeel
16
16
  specify { (subject & subject).should be_a And }
17
17
  specify { (subject | subject).should be_a Or }
18
18
  specify { (-subject).should be_a Not }
19
+ specify { [subject, Sifter.new(:title_or_body_contains, ['awesome'])].uniq.should have(1).sifter }
19
20
 
20
21
  end
21
22
  end
22
- end
23
+ end
@@ -211,6 +211,10 @@ module Squeel
211
211
  as.right.should eq 'other_name'
212
212
  end
213
213
 
214
+ it 'implements equivalence check' do
215
+ [@s, Stub.new(:attribute)].uniq.should have(1).element
216
+ end
217
+
214
218
  end
215
219
  end
216
220
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ module Squeel
4
+ module Visitors
5
+ describe OrderVisitor do
6
+
7
+ before do
8
+ @jd = new_join_dependency(Person, {
9
+ :children => {
10
+ :children => {
11
+ :parent => :parent
12
+ }
13
+ }
14
+ }, [])
15
+ @c = Squeel::Adapters::ActiveRecord::Context.new(@jd)
16
+ @v = OrderVisitor.new(@c)
17
+ end
18
+
19
+ it 'accepts Order with Function expression' do
20
+ function = @v.accept(dsl{find_in_set(children.children.id, '1,2,3').desc})
21
+ function.to_sql.should match /find_in_set\("children_people_2"."id", '1,2,3'\) DESC/
22
+ end
23
+
24
+ it 'accepts Order with Operation expression' do
25
+ operation = @v.accept(dsl{(id / 1).desc})
26
+ operation.to_sql.should match /"people"."id" \/ 1 DESC/
27
+ end
28
+
29
+ it 'orders by predicates' do
30
+ orders = @v.accept(dsl{name == 'Ernie'})
31
+ orders.to_sql.should match /"people"."name" = 'Ernie'/
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -2,9 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  module Squeel
4
4
  module Visitors
5
- describe SymbolVisitor do
5
+ describe PreloadVisitor do
6
+
6
7
  before do
7
- @v = SymbolVisitor.new
8
+ @v = PreloadVisitor.new
8
9
  end
9
10
 
10
11
  it 'returns symbols unmodified' do
@@ -39,4 +40,4 @@ module Squeel
39
40
 
40
41
  end
41
42
  end
42
- end
43
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Squeel
4
+ module Visitors
5
+ describe SelectVisitor do
6
+
7
+ before do
8
+ @jd = new_join_dependency(Person, {
9
+ :children => {
10
+ :children => {
11
+ :parent => :parent
12
+ }
13
+ }
14
+ }, [])
15
+ @c = Squeel::Adapters::ActiveRecord::Context.new(@jd)
16
+ @v = SelectVisitor.new(@c)
17
+ end
18
+
19
+ it 'selects predicates' do
20
+ selects = @v.accept(dsl{name == 'Ernie'})
21
+ selects.to_sql.should match /"people"."name" = 'Ernie'/
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  module Squeel
4
4
  module Visitors
5
- describe AttributeVisitor do
5
+ describe Visitor do
6
6
 
7
7
  before do
8
8
  @jd = new_join_dependency(Person, {
@@ -13,7 +13,7 @@ module Squeel
13
13
  }
14
14
  }, [])
15
15
  @c = Squeel::Adapters::ActiveRecord::Context.new(@jd)
16
- @v = AttributeVisitor.new(@c)
16
+ @v = Visitor.new(@c)
17
17
  end
18
18
 
19
19
  it 'creates a bare ARel attribute given a symbol with no asc/desc' do
@@ -23,50 +23,46 @@ module Squeel
23
23
  attribute.relation.name.should eq 'people'
24
24
  end
25
25
 
26
- it 'creates the ordering against the proper table for nested hashes' do
27
- orders = @v.accept({
26
+ it 'creates attributes against the proper table for nested hashes' do
27
+ attributes = @v.accept({
28
28
  :children => {
29
29
  :children => {
30
30
  :parent => {
31
- :parent => :name.asc
31
+ :parent => :name
32
32
  }
33
33
  }
34
34
  }
35
35
  })
36
- orders.should be_a Array
37
- ordering = orders.first
38
- ordering.should be_a Arel::Nodes::Ordering
39
- ordering.expr.relation.table_alias.should eq 'parents_people_2'
40
- ordering.direction.should eq :asc
36
+ attributes.should be_a Array
37
+ attribute = attributes.first
38
+ attribute.should be_a Arel::Attributes::Attribute
39
+ attribute.relation.table_alias.should eq 'parents_people_2'
41
40
  end
42
41
 
43
42
  it 'does not alter values it is unable to accept' do
44
- orders = @v.accept(['THIS PARAMETER', 'WHAT DOES IT MEAN???'])
45
- orders.should eq ['THIS PARAMETER', 'WHAT DOES IT MEAN???']
43
+ values = @v.accept(['THIS PARAMETER', 'WHAT DOES IT MEAN???'])
44
+ values.should eq ['THIS PARAMETER', 'WHAT DOES IT MEAN???']
46
45
  end
47
46
 
48
47
  it 'treats keypath keys like nested hashes' do
49
- ordering = @v.accept(Nodes::Stub.new(:children).children.parent.parent.name.asc)
50
- ordering.should be_a Arel::Nodes::Ordering
51
- ordering.expr.relation.table_alias.should eq 'parents_people_2'
52
- ordering.direction.should eq :asc
48
+ attribute = @v.accept(Nodes::Stub.new(:children).children.parent.parent.name)
49
+ attribute.should be_a Arel::Attributes::Attribute
50
+ attribute.relation.table_alias.should eq 'parents_people_2'
53
51
  end
54
52
 
55
53
  it 'honors absolute keypaths' do
56
- orders = @v.accept(dsl{{children => {children => ~children.children.name.asc}}})
57
- orders.should be_a Array
58
- ordering = orders.first
59
- ordering.expr.relation.table_alias.should eq 'children_people_2'
60
- ordering.direction.should eq :asc
54
+ attributes = @v.accept(dsl{{children => {children => ~children.children.name}}})
55
+ attributes.should be_a Array
56
+ attribute = attributes.first
57
+ attribute.relation.table_alias.should eq 'children_people_2'
61
58
  end
62
59
 
63
60
  it 'allows hashes with keypath keys' do
64
- orders = @v.accept(Nodes::Stub.new(:children).children.parent.parent => :name.asc)
65
- orders.should be_a Array
66
- ordering = orders.first
67
- ordering.should be_a Arel::Nodes::Ordering
68
- ordering.expr.relation.table_alias.should eq 'parents_people_2'
69
- ordering.direction.should eq :asc
61
+ attributes = @v.accept(Nodes::Stub.new(:children).children.parent.parent => :name)
62
+ attributes.should be_a Array
63
+ attribute = attributes.first
64
+ attribute.should be_a Arel::Attributes::Attribute
65
+ attribute.relation.table_alias.should eq 'parents_people_2'
70
66
  end
71
67
 
72
68
  it 'allows a subquery as a selection' do
@@ -85,11 +81,6 @@ module Squeel
85
81
  function.to_sql.should match /find_in_set\("people"."id", '1,2,3'\)/
86
82
  end
87
83
 
88
- it 'accepts Order with Function expression' do
89
- function = @v.accept(dsl{find_in_set(children.children.id, '1,2,3').desc})
90
- function.to_sql.should match /find_in_set\("children_people_2"."id", '1,2,3'\) DESC/
91
- end
92
-
93
84
  it 'accepts keypaths as function args' do
94
85
  function = @v.accept(dsl{find_in_set(children.children.id, '1,2,3')})
95
86
  function.to_sql.should match /find_in_set\("children_people_2"."id", '1,2,3'\)/
@@ -145,11 +136,6 @@ module Squeel
145
136
  operation.to_sql.should match /incremented_id/
146
137
  end
147
138
 
148
- it 'accepts Order with Operation expression' do
149
- operation = @v.accept(dsl{(id / 1).desc})
150
- operation.to_sql.should match /"people"."id" \/ 1 DESC/
151
- end
152
-
153
139
  end
154
140
  end
155
141
  end
@@ -5,6 +5,7 @@ class Person < ActiveRecord::Base
5
5
  has_many :articles_with_condition, :class_name => 'Article', :conditions => {:title => 'Condition'}
6
6
  has_many :comments
7
7
  has_many :condition_article_comments, :through => :articles_with_condition, :source => :comments
8
+ has_many :article_comments_with_first_post, :through => :articles, :source => :comments, :conditions => {:body => 'first post'}
8
9
  has_many :authored_article_comments, :through => :articles,
9
10
  :source => :comments
10
11
  has_many :notes, :as => :notable
@@ -14,6 +15,8 @@ class Person < ActiveRecord::Base
14
15
  has_many :incoming_messages, :class_name => 'Message', :foreign_key => :recipient_id
15
16
 
16
17
  scope :nil_scope, lambda { nil }
18
+ scope :with_article_title, lambda {|t| joins{articles}.where{articles.title == t}}
19
+ scope :with_article_condition_title, lambda {|t| joins{articles_with_condition}.where{articles_with_condition.title == t}}
17
20
 
18
21
  sifter :name_starts_or_ends_with do |value|
19
22
  (name =~ "#{value}%") | (name =~ "%#{value}")
@@ -33,6 +36,7 @@ class PersonNamedBill < ActiveRecord::Base
33
36
  default_scope where{name == 'Bill'}.order{id}
34
37
  scope :highly_compensated, where{salary > 200000}
35
38
  scope :ending_with_ill, where{name =~ '%ill'}
39
+ scope :with_salary_equal_to, lambda { |value| where{abs(salary) == value} }
36
40
  end
37
41
 
38
42
  class Message < ActiveRecord::Base
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: 1.0.9
4
+ version: 1.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-06 00:00:00.000000000 Z
12
+ date: 2012-09-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -190,10 +190,16 @@ files:
190
190
  - lib/squeel/nodes/unary.rb
191
191
  - lib/squeel/version.rb
192
192
  - lib/squeel/visitors.rb
193
- - lib/squeel/visitors/attribute_visitor.rb
193
+ - lib/squeel/visitors/from_visitor.rb
194
+ - lib/squeel/visitors/group_visitor.rb
195
+ - lib/squeel/visitors/having_visitor.rb
196
+ - lib/squeel/visitors/order_visitor.rb
197
+ - lib/squeel/visitors/predicate_visitation.rb
194
198
  - lib/squeel/visitors/predicate_visitor.rb
195
- - lib/squeel/visitors/symbol_visitor.rb
199
+ - lib/squeel/visitors/preload_visitor.rb
200
+ - lib/squeel/visitors/select_visitor.rb
196
201
  - lib/squeel/visitors/visitor.rb
202
+ - lib/squeel/visitors/where_visitor.rb
197
203
  - spec/blueprints/articles.rb
198
204
  - spec/blueprints/comments.rb
199
205
  - spec/blueprints/notes.rb
@@ -209,6 +215,7 @@ files:
209
215
  - spec/squeel/adapters/active_record/relation_extensions_spec.rb
210
216
  - spec/squeel/core_ext/symbol_spec.rb
211
217
  - spec/squeel/dsl_spec.rb
218
+ - spec/squeel/nodes/as_spec.rb
212
219
  - spec/squeel/nodes/function_spec.rb
213
220
  - spec/squeel/nodes/grouping_spec.rb
214
221
  - spec/squeel/nodes/join_spec.rb
@@ -221,9 +228,11 @@ files:
221
228
  - spec/squeel/nodes/predicate_spec.rb
222
229
  - spec/squeel/nodes/sifter_spec.rb
223
230
  - spec/squeel/nodes/stub_spec.rb
224
- - spec/squeel/visitors/attribute_visitor_spec.rb
231
+ - spec/squeel/visitors/order_visitor_spec.rb
225
232
  - spec/squeel/visitors/predicate_visitor_spec.rb
226
- - spec/squeel/visitors/symbol_visitor_spec.rb
233
+ - spec/squeel/visitors/preload_visitor_spec.rb
234
+ - spec/squeel/visitors/select_visitor_spec.rb
235
+ - spec/squeel/visitors/visitor_spec.rb
227
236
  - spec/support/models.rb
228
237
  - spec/support/schema.rb
229
238
  - squeel.gemspec
@@ -241,7 +250,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
241
250
  version: '0'
242
251
  segments:
243
252
  - 0
244
- hash: -377980682331781514
253
+ hash: -801751597998124956
245
254
  required_rubygems_version: !ruby/object:Gem::Requirement
246
255
  none: false
247
256
  requirements:
@@ -250,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
259
  version: '0'
251
260
  segments:
252
261
  - 0
253
- hash: -377980682331781514
262
+ hash: -801751597998124956
254
263
  requirements: []
255
264
  rubyforge_project: squeel
256
265
  rubygems_version: 1.8.24
@@ -273,6 +282,7 @@ test_files:
273
282
  - spec/squeel/adapters/active_record/relation_extensions_spec.rb
274
283
  - spec/squeel/core_ext/symbol_spec.rb
275
284
  - spec/squeel/dsl_spec.rb
285
+ - spec/squeel/nodes/as_spec.rb
276
286
  - spec/squeel/nodes/function_spec.rb
277
287
  - spec/squeel/nodes/grouping_spec.rb
278
288
  - spec/squeel/nodes/join_spec.rb
@@ -285,8 +295,10 @@ test_files:
285
295
  - spec/squeel/nodes/predicate_spec.rb
286
296
  - spec/squeel/nodes/sifter_spec.rb
287
297
  - spec/squeel/nodes/stub_spec.rb
288
- - spec/squeel/visitors/attribute_visitor_spec.rb
298
+ - spec/squeel/visitors/order_visitor_spec.rb
289
299
  - spec/squeel/visitors/predicate_visitor_spec.rb
290
- - spec/squeel/visitors/symbol_visitor_spec.rb
300
+ - spec/squeel/visitors/preload_visitor_spec.rb
301
+ - spec/squeel/visitors/select_visitor_spec.rb
302
+ - spec/squeel/visitors/visitor_spec.rb
291
303
  - spec/support/models.rb
292
304
  - spec/support/schema.rb