squeel 1.0.18 → 1.1.0

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 (50) hide show
  1. data/.ruby-gemset +1 -0
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +2 -7
  4. data/CHANGELOG.md +9 -0
  5. data/Gemfile +2 -2
  6. data/README.md +223 -147
  7. data/lib/generators/templates/squeel.rb +1 -1
  8. data/lib/squeel/adapters/active_record.rb +1 -1
  9. data/lib/squeel/adapters/active_record/4.0/compat.rb +17 -0
  10. data/lib/squeel/adapters/active_record/4.0/context.rb +1 -0
  11. data/lib/squeel/adapters/active_record/4.0/preloader_extensions.rb +1 -0
  12. data/lib/squeel/adapters/active_record/4.0/relation_extensions.rb +126 -0
  13. data/lib/squeel/adapters/active_record/base_extensions.rb +1 -1
  14. data/lib/squeel/adapters/active_record/context.rb +10 -10
  15. data/lib/squeel/adapters/active_record/relation_extensions.rb +24 -16
  16. data/lib/squeel/configuration.rb +1 -0
  17. data/lib/squeel/constants.rb +2 -2
  18. data/lib/squeel/context.rb +2 -2
  19. data/lib/squeel/dsl.rb +1 -1
  20. data/lib/squeel/nodes.rb +2 -0
  21. data/lib/squeel/nodes/binary.rb +1 -1
  22. data/lib/squeel/nodes/function.rb +5 -5
  23. data/lib/squeel/nodes/join.rb +2 -2
  24. data/lib/squeel/nodes/key_path.rb +10 -5
  25. data/lib/squeel/nodes/literal.rb +1 -1
  26. data/lib/squeel/nodes/nary.rb +5 -7
  27. data/lib/squeel/nodes/node.rb +6 -0
  28. data/lib/squeel/nodes/operation.rb +1 -1
  29. data/lib/squeel/nodes/order.rb +1 -1
  30. data/lib/squeel/nodes/predicate.rb +5 -5
  31. data/lib/squeel/nodes/predicate_methods.rb +11 -2
  32. data/lib/squeel/nodes/sifter.rb +2 -2
  33. data/lib/squeel/nodes/stub.rb +2 -2
  34. data/lib/squeel/nodes/unary.rb +1 -1
  35. data/lib/squeel/version.rb +1 -1
  36. data/lib/squeel/visitors/predicate_visitation.rb +6 -6
  37. data/lib/squeel/visitors/predicate_visitor.rb +1 -1
  38. data/lib/squeel/visitors/visitor.rb +20 -20
  39. data/spec/spec_helper.rb +6 -4
  40. data/spec/squeel/adapters/active_record/base_extensions_spec.rb +6 -6
  41. data/spec/squeel/adapters/active_record/relation_extensions_spec.rb +55 -24
  42. data/spec/squeel/core_ext/symbol_spec.rb +2 -2
  43. data/spec/squeel/nodes/key_path_spec.rb +3 -3
  44. data/spec/squeel/nodes/predicate_operators_spec.rb +4 -4
  45. data/spec/squeel/visitors/predicate_visitor_spec.rb +11 -11
  46. data/spec/squeel/visitors/visitor_spec.rb +9 -9
  47. data/spec/support/models.rb +25 -7
  48. data/spec/support/schema.rb +1 -1
  49. data/squeel.gemspec +4 -4
  50. metadata +19 -12
@@ -23,7 +23,7 @@ describe Symbol do
23
23
  it 'creates a function node' do
24
24
  function = :blah.func('foo')
25
25
  function.should be_a Squeel::Nodes::Function
26
- function.name.should eq :blah
26
+ function.function_name.should eq :blah
27
27
  function.args.should eq ['foo']
28
28
  end
29
29
  end
@@ -55,4 +55,4 @@ describe Symbol do
55
55
  join._klass.should eq Person
56
56
  end
57
57
  end
58
- end
58
+ end
@@ -46,7 +46,7 @@ module Squeel
46
46
  it 'creates a named function at its endpoint' do
47
47
  @k.third.fourth.fifth.max(1,2,3)
48
48
  @k.endpoint.should be_a Function
49
- @k.endpoint.name.should eq :max
49
+ @k.endpoint.function_name.should eq :max
50
50
  @k.endpoint.args.should eq [1,2,3]
51
51
  end
52
52
 
@@ -77,7 +77,7 @@ module Squeel
77
77
  it 'creates Or nodes with | if the endpoint responds to |' do
78
78
  node = @k.third.fourth.eq('Bob') | Stub.new(:attr).eq('Joe')
79
79
  node.should be_a Or
80
- node.left.should eq @k
80
+ node.left.should eql @k
81
81
  node.right.should eql Stub.new(:attr).eq('Joe')
82
82
  end
83
83
 
@@ -99,7 +99,7 @@ module Squeel
99
99
  it 'creates NOT nodes with -@ if the endpoint responds to -@' do
100
100
  node = - @k.third.fourth.eq('Bob')
101
101
  node.should be_a Not
102
- node.expr.should eq @k
102
+ node.expr.should eql @k
103
103
  end
104
104
 
105
105
  it 'raises NoMethodError with -@ if the endpoint does not respond to -@' do
@@ -21,13 +21,13 @@ module Squeel
21
21
  n.children.should eq [left, right]
22
22
  end
23
23
 
24
- it 'appends nodes to children from other And nodes' do
24
+ it 'creates And nodes by appending a new child' do
25
25
  left = :name.matches % 'J%' & :name.matches % '%e'
26
26
  right = :id.gt % 0
27
27
  expected = left.children + [right]
28
- left & right
29
- left.should be_a And
30
- left.children.should eq expected
28
+ new_and = left & right
29
+ new_and.should be_a And
30
+ new_and.children.should eq expected
31
31
  end
32
32
  end
33
33
 
@@ -327,7 +327,7 @@ module Squeel
327
327
  predicate.to_sql.should be_like '"people"."id" IN (SELECT "people"."id" FROM "people" ORDER BY "people"."id" DESC LIMIT 3)'
328
328
  end
329
329
 
330
- it 'converts ActiveRecord::Relation values in function arguments to their ARel AST' do
330
+ it 'converts ActiveRecord::Relation values in function arguments to their Arel AST' do
331
331
  predicate = @v.accept(dsl{exists(Person.where{name == 'Aric Smith'})})
332
332
  predicate.should be_a Arel::Nodes::NamedFunction
333
333
  predicate.expressions.first.should be_a Arel::Nodes::SelectStatement
@@ -386,7 +386,7 @@ module Squeel
386
386
  predicate.right.should eq 'Joe'
387
387
  end
388
388
 
389
- it 'creates an ARel Grouping node containing an Or node for Or nodes' do
389
+ it 'creates an Arel Grouping node containing an Or node for Or nodes' do
390
390
  left = :name.matches % 'Joe%'
391
391
  right = :id.gt % 1
392
392
  predicate = @v.accept(left | right)
@@ -396,23 +396,23 @@ module Squeel
396
396
  predicate.expr.right.should be_a Arel::Nodes::GreaterThan
397
397
  end
398
398
 
399
- it 'creates an ARel Not node for a Not node' do
399
+ it 'creates an Arel Not node for a Not node' do
400
400
  expr = -(:name.matches % 'Joe%')
401
401
  predicate = @v.accept(expr)
402
402
  predicate.should be_a Arel::Nodes::Not
403
403
  end
404
404
 
405
- it 'creates an ARel NamedFunction node for a Function node' do
405
+ it 'creates an Arel NamedFunction node for a Function node' do
406
406
  function = @v.accept(:find_in_set.func())
407
407
  function.should be_a Arel::Nodes::NamedFunction
408
408
  end
409
409
 
410
- it 'maps symbols in Function args to ARel attributes' do
410
+ it 'maps symbols in Function args to Arel attributes' do
411
411
  function = @v.accept(:find_in_set.func(:id, '1,2,3'))
412
412
  function.to_sql.should match /"people"."id"/
413
413
  end
414
414
 
415
- it 'sets the alias on the ARel NamedFunction from the Function alias' do
415
+ it 'sets the alias on the Arel NamedFunction from the Function alias' do
416
416
  function = @v.accept(:find_in_set.func(:id, '1,2,3').as('newname'))
417
417
  function.to_sql.should match /newname/
418
418
  end
@@ -427,27 +427,27 @@ module Squeel
427
427
  as.to_sql.should match /"people"."name" AS other_name/
428
428
  end
429
429
 
430
- it 'creates an ARel Addition node for an Operation node with + as operator' do
430
+ it 'creates an Arel Addition node for an Operation node with + as operator' do
431
431
  operation = @v.accept(dsl{id + 1})
432
432
  operation.should be_a Arel::Nodes::Addition
433
433
  end
434
434
 
435
- it 'creates an ARel Subtraction node for an Operation node with - as operator' do
435
+ it 'creates an Arel Subtraction node for an Operation node with - as operator' do
436
436
  operation = @v.accept(dsl{id - 1})
437
437
  operation.should be_a Arel::Nodes::Subtraction
438
438
  end
439
439
 
440
- it 'creates an ARel Multiplication node for an Operation node with * as operator' do
440
+ it 'creates an Arel Multiplication node for an Operation node with * as operator' do
441
441
  operation = @v.accept(dsl{id * 1})
442
442
  operation.should be_a Arel::Nodes::Multiplication
443
443
  end
444
444
 
445
- it 'creates an ARel Division node for an Operation node with / as operator' do
445
+ it 'creates an Arel Division node for an Operation node with / as operator' do
446
446
  operation = @v.accept(dsl{id / 1})
447
447
  operation.should be_a Arel::Nodes::Division
448
448
  end
449
449
 
450
- it 'creates an ARel InfixOperation node for an Operation with a custom operator' do
450
+ it 'creates an Arel InfixOperation node for an Operation with a custom operator' do
451
451
  operation = @v.accept(dsl{id.op(:blah, 1)})
452
452
  operation.should be_a Arel::Nodes::InfixOperation
453
453
  end
@@ -16,7 +16,7 @@ module Squeel
16
16
  @v = Visitor.new(@c)
17
17
  end
18
18
 
19
- it 'creates a bare ARel attribute given a symbol with no asc/desc' do
19
+ it 'creates a bare Arel attribute given a symbol with no asc/desc' do
20
20
  attribute = @v.accept(:name)
21
21
  attribute.should be_a Arel::Attribute
22
22
  attribute.name.should eq :name
@@ -71,12 +71,12 @@ module Squeel
71
71
  node.to_sql.should be_like "(SELECT \"people\".\"id\" FROM \"people\" WHERE \"people\".\"name\" = 'Aric Smith') aric"
72
72
  end
73
73
 
74
- it 'creates an ARel NamedFunction node for a Function node' do
74
+ it 'creates an Arel NamedFunction node for a Function node' do
75
75
  function = @v.accept(:find_in_set.func())
76
76
  function.should be_a Arel::Nodes::NamedFunction
77
77
  end
78
78
 
79
- it 'maps symbols in Function args to ARel attributes' do
79
+ it 'maps symbols in Function args to Arel attributes' do
80
80
  function = @v.accept(:find_in_set.func(:id, '1,2,3'))
81
81
  function.to_sql.should match /find_in_set\("people"."id", '1,2,3'\)/
82
82
  end
@@ -86,7 +86,7 @@ module Squeel
86
86
  function.to_sql.should match /find_in_set\("children_people_2"."id", '1,2,3'\)/
87
87
  end
88
88
 
89
- it 'sets the alias on the ARel NamedFunction from the Function alias' do
89
+ it 'sets the alias on the Arel NamedFunction from the Function alias' do
90
90
  function = @v.accept(:find_in_set.func(:id, '1,2,3').as('newname'))
91
91
  function.to_sql.should match /newname/
92
92
  end
@@ -106,27 +106,27 @@ module Squeel
106
106
  as.to_sql.should match /"children_people"."name" AS other_name/
107
107
  end
108
108
 
109
- it 'creates an ARel Grouping node for a Squeel Grouping node' do
109
+ it 'creates an Arel Grouping node for a Squeel Grouping node' do
110
110
  grouping = @v.accept(dsl{_(id)})
111
111
  grouping.should be_a Arel::Nodes::Grouping
112
112
  end
113
113
 
114
- it 'creates an ARel Addition node for an Operation node with + as operator' do
114
+ it 'creates an Arel Addition node for an Operation node with + as operator' do
115
115
  operation = @v.accept(dsl{id + 1})
116
116
  operation.should be_a Arel::Nodes::Addition
117
117
  end
118
118
 
119
- it 'creates an ARel Subtraction node for an Operation node with - as operator' do
119
+ it 'creates an Arel Subtraction node for an Operation node with - as operator' do
120
120
  operation = @v.accept(dsl{id - 1})
121
121
  operation.should be_a Arel::Nodes::Subtraction
122
122
  end
123
123
 
124
- it 'creates an ARel Multiplication node for an Operation node with * as operator' do
124
+ it 'creates an Arel Multiplication node for an Operation node with * as operator' do
125
125
  operation = @v.accept(dsl{id * 1})
126
126
  operation.should be_a Arel::Nodes::Multiplication
127
127
  end
128
128
 
129
- it 'creates an ARel Division node for an Operation node with / as operator' do
129
+ it 'creates an Arel Division node for an Operation node with / as operator' do
130
130
  operation = @v.accept(dsl{id / 1})
131
131
  operation.should be_a Arel::Nodes::Division
132
132
  end
@@ -2,10 +2,24 @@ class Person < ActiveRecord::Base
2
2
  belongs_to :parent, :class_name => 'Person', :foreign_key => :parent_id
3
3
  has_many :children, :class_name => 'Person', :foreign_key => :parent_id
4
4
  has_many :articles
5
- has_many :articles_with_condition, :class_name => 'Article', :conditions => {:title => 'Condition'}
6
5
  has_many :comments
6
+ if ActiveRecord::VERSION::MAJOR == 4
7
+ has_many :articles_with_condition, lambda { where :title => 'Condition' },
8
+ :class_name => 'Article'
9
+ has_many :article_comments_with_first_post,
10
+ lambda { where :body => 'first post' },
11
+ :through => :articles, :source => :comments
12
+ else
13
+ has_many :articles_with_condition, :conditions => {:title => 'Condition'},
14
+ :class_name => 'Article'
15
+ has_many :article_comments_with_first_post,
16
+ :conditions => { :body => 'first post' },
17
+ :through => :articles, :source => :comments
18
+ end
7
19
  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'}
20
+ if ActiveRecord::VERSION::MAJOR == 4
21
+ else
22
+ end
9
23
  has_many :authored_article_comments, :through => :articles,
10
24
  :source => :comments
11
25
  has_many :notes, :as => :notable
@@ -28,18 +42,22 @@ class Person < ActiveRecord::Base
28
42
  end
29
43
 
30
44
  class PersonWithNamePrimaryKey < ActiveRecord::Base
31
- set_primary_key 'name'
45
+ self.primary_key = 'name'
32
46
  # Set this second, because I'm lazy and don't want to populate another table,
33
47
  # and also don't want to clobber the AR connection's primary_key cache.
34
- set_table_name 'people'
48
+ self.table_name = 'people'
35
49
  end
36
50
 
37
51
  class PersonNamedBill < ActiveRecord::Base
38
52
  self.table_name = 'people'
39
53
  belongs_to :parent, :class_name => 'Person', :foreign_key => :parent_id
40
- default_scope where{name == 'Bill'}.order{id}
41
- scope :highly_compensated, where{salary > 200000}
42
- scope :ending_with_ill, where{name =~ '%ill'}
54
+ if ActiveRecord::VERSION::MAJOR > 3 || ActiveRecord::VERSION::MINOR > 0
55
+ default_scope lambda { where{name == 'Bill'}.order{id} }
56
+ else # 3.0 doesn't support callables for default_scope
57
+ default_scope where{name == 'Bill'}.order{id}
58
+ end
59
+ scope :highly_compensated, lambda { where {salary > 200000} }
60
+ scope :ending_with_ill, lambda { where{name =~ '%ill'} }
43
61
  scope :with_salary_equal_to, lambda { |value| where{abs(salary) == value} }
44
62
  end
45
63
 
@@ -6,7 +6,7 @@ ActiveRecord::Base.establish_connection(
6
6
  :database => ':memory:'
7
7
  )
8
8
 
9
- ActiveRecord::Base.silence do
9
+ silence_stream(STDOUT) do
10
10
  ActiveRecord::Migration.verbose = false
11
11
 
12
12
  ActiveRecord::Schema.define do
@@ -11,16 +11,16 @@ Gem::Specification.new do |s|
11
11
  s.homepage = "http://erniemiller.org/projects/squeel"
12
12
  s.summary = %q{Active Record 3, improved.}
13
13
  s.description = %q{
14
- Squeel unlocks the power of ARel in your Rails 3 application with
14
+ Squeel unlocks the power of Arel in your Rails 3 application with
15
15
  a handy block-based syntax. You can write subqueries, access named
16
16
  functions provided by your RDBMS, and more, all without writing
17
17
  SQL strings.
18
18
  }
19
19
  s.rubyforge_project = "squeel"
20
20
 
21
- s.add_dependency 'activerecord', '~> 3.0'
22
- s.add_dependency 'activesupport', '~> 3.0'
23
- s.add_dependency 'polyamorous', '~> 0.5.0'
21
+ s.add_dependency 'activerecord', '>= 3.0'
22
+ s.add_dependency 'activesupport', '>= 3.0'
23
+ s.add_dependency 'polyamorous', '~> 0.6.0'
24
24
  s.add_development_dependency 'rspec', '~> 2.6.0'
25
25
  s.add_development_dependency 'machinist', '~> 1.0.6'
26
26
  s.add_development_dependency 'faker', '~> 0.9.5'
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.18
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,14 +9,14 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-07 00:00:00.000000000 Z
12
+ date: 2013-07-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: '3.0'
22
22
  type: :runtime
@@ -24,7 +24,7 @@ dependencies:
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '3.0'
30
30
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ~>
35
+ - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
37
  version: '3.0'
38
38
  type: :runtime
@@ -40,7 +40,7 @@ dependencies:
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ~>
43
+ - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '3.0'
46
46
  - !ruby/object:Gem::Dependency
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 0.5.0
53
+ version: 0.6.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 0.5.0
61
+ version: 0.6.0
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: rspec
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -123,7 +123,7 @@ dependencies:
123
123
  - - ~>
124
124
  - !ruby/object:Gem::Version
125
125
  version: 1.3.3
126
- description: ! "\n Squeel unlocks the power of ARel in your Rails 3 application
126
+ description: ! "\n Squeel unlocks the power of Arel in your Rails 3 application
127
127
  with\n a handy block-based syntax. You can write subqueries, access named\n
128
128
  \ functions provided by your RDBMS, and more, all without writing\n SQL
129
129
  strings.\n "
@@ -134,6 +134,8 @@ extensions: []
134
134
  extra_rdoc_files: []
135
135
  files:
136
136
  - .gitignore
137
+ - .ruby-gemset
138
+ - .ruby-version
137
139
  - .travis.yml
138
140
  - .yardopts
139
141
  - CHANGELOG.md
@@ -157,6 +159,10 @@ files:
157
159
  - lib/squeel/adapters/active_record/3.2/context.rb
158
160
  - lib/squeel/adapters/active_record/3.2/preloader_extensions.rb
159
161
  - lib/squeel/adapters/active_record/3.2/relation_extensions.rb
162
+ - lib/squeel/adapters/active_record/4.0/compat.rb
163
+ - lib/squeel/adapters/active_record/4.0/context.rb
164
+ - lib/squeel/adapters/active_record/4.0/preloader_extensions.rb
165
+ - lib/squeel/adapters/active_record/4.0/relation_extensions.rb
160
166
  - lib/squeel/adapters/active_record/base_extensions.rb
161
167
  - lib/squeel/adapters/active_record/compat.rb
162
168
  - lib/squeel/adapters/active_record/context.rb
@@ -180,6 +186,7 @@ files:
180
186
  - lib/squeel/nodes/key_path.rb
181
187
  - lib/squeel/nodes/literal.rb
182
188
  - lib/squeel/nodes/nary.rb
189
+ - lib/squeel/nodes/node.rb
183
190
  - lib/squeel/nodes/not.rb
184
191
  - lib/squeel/nodes/operation.rb
185
192
  - lib/squeel/nodes/operators.rb
@@ -255,7 +262,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
255
262
  version: '0'
256
263
  segments:
257
264
  - 0
258
- hash: -663297487386746255
265
+ hash: 3013172818139711392
259
266
  required_rubygems_version: !ruby/object:Gem::Requirement
260
267
  none: false
261
268
  requirements:
@@ -264,10 +271,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
271
  version: '0'
265
272
  segments:
266
273
  - 0
267
- hash: -663297487386746255
274
+ hash: 3013172818139711392
268
275
  requirements: []
269
276
  rubyforge_project: squeel
270
- rubygems_version: 1.8.24
277
+ rubygems_version: 1.8.25
271
278
  signing_key:
272
279
  specification_version: 3
273
280
  summary: Active Record 3, improved.