baby_squeel 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e25c11d1ea3b43b1911854cc0966350877f7d62
4
- data.tar.gz: a203af4f8f653617a5a64930e43501daf314489a
3
+ metadata.gz: 2c05b66383b8b74c1c6ba92af1164da82a4290a2
4
+ data.tar.gz: 19d23ae9dae15bc8f7b8acb91f18272f7101e9c7
5
5
  SHA512:
6
- metadata.gz: 1a0528486cceb39952ad82687a69a9a6fb920a1ba6faf16ebdf4544bcfd5d6769d457ce10c87b4ad167f3a4a17c5234a6c36a78609fad03806d983232df4b743
7
- data.tar.gz: aa45ff551f8d7c86c761749af179482011a2da522c9261ced4fab70ee1f5547f1b94eb6c93df3b5cf250e9169b72a3184bf1689c5bf614b7db20a69b476b3f88
6
+ metadata.gz: 4ff0c39cba1d8b76911020f7b1a66affacddfb6dbe5a4e63a6cf7752f40bcdc30180fcfb95fa5437c495146469a30dbf7e73ceeddf5ca7fbb75d5c6810ff245b
7
+ data.tar.gz: e765fd51a96096549e971be4a8ffd87a2ae24300475e49043eddf33b692500501f2a1ca3ca8933048aedc08ea60f18f9748dfc93d1bd69f84e5067a9cf9d2594
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
1
  ## [Unreleased]
2
2
 
3
- *Nothing yet.*
3
+ Nothing to see yet!
4
+
5
+ ## [1.1.0] - 2017-02-10
6
+ > This version drops support for Active Record 4.1. If you're stil on 4.1, you should seriously consider upgrading to at least 4.2.
7
+
8
+ ### Added
9
+ - DSLs for ActiveRecord::Relation::Calculations. You can not use `plucking`, `counting`, `summing`, `averaging`, `minimizing`, and `maximizing`.
4
10
 
5
11
  ## [1.0.3] - 2017-02-09
6
12
  ### Added
@@ -93,7 +99,8 @@
93
99
  ### Added
94
100
  - Initial support for selects, orders, wheres, and joins.
95
101
 
96
- [Unreleased]: https://github.com/rzane/baby_squeel/compare/v1.0.3...HEAD
102
+ [Unreleased]: https://github.com/rzane/baby_squeel/compare/v1.1.0...HEAD
103
+ [1.1.0]: https://github.com/rzane/baby_squeel/compare/v1.0.3...v1.1.0
97
104
  [1.0.3]: https://github.com/rzane/baby_squeel/compare/v1.0.2...v1.0.3
98
105
  [1.0.2]: https://github.com/rzane/baby_squeel/compare/v1.0.1...v1.0.2
99
106
  [1.0.1]: https://github.com/rzane/baby_squeel/compare/v1.0.0...v1.0.1
data/baby_squeel.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Ray Zane']
10
10
  spec.email = ['ray@promptworks.com']
11
11
 
12
- spec.summary = 'A tiny squeel implementation without all of the evil.'
12
+ spec.summary = 'An expressive query DSL for Active Record 4 and 5.'
13
13
  spec.description = spec.summary
14
14
  spec.homepage = 'https://github.com/rzane/baby_squeel'
15
15
  spec.license = 'MIT'
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.files = Dir.glob('{lib/**/*,*.{md,txt,gemspec}}')
21
21
 
22
- spec.add_dependency 'activerecord', '>= 4.1.0'
22
+ spec.add_dependency 'activerecord', '>= 4.2.0'
23
23
  spec.add_dependency 'polyamorous', '~> 1.3'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.11'
data/lib/baby_squeel.rb CHANGED
@@ -5,6 +5,7 @@ require 'baby_squeel/version'
5
5
  require 'baby_squeel/errors'
6
6
  require 'baby_squeel/active_record/base'
7
7
  require 'baby_squeel/active_record/query_methods'
8
+ require 'baby_squeel/active_record/calculations'
8
9
  require 'baby_squeel/active_record/where_chain'
9
10
 
10
11
  module BabySqueel
@@ -43,5 +44,6 @@ end
43
44
  ActiveSupport.on_load :active_record do
44
45
  ::ActiveRecord::Base.extend BabySqueel::ActiveRecord::Base
45
46
  ::ActiveRecord::Relation.prepend BabySqueel::ActiveRecord::QueryMethods
47
+ ::ActiveRecord::Relation.prepend BabySqueel::ActiveRecord::Calculations
46
48
  ::ActiveRecord::QueryMethods::WhereChain.prepend BabySqueel::ActiveRecord::WhereChain
47
49
  end
@@ -4,7 +4,9 @@ module BabySqueel
4
4
  module ActiveRecord
5
5
  module Base
6
6
  delegate :joining, :joining!, :selecting, :ordering,
7
- :grouping, :when_having, :plucking, to: :all
7
+ :grouping, :when_having, :plucking,
8
+ :averaging, :counting, :maximizing,
9
+ :minimizing, :summing, to: :all
8
10
 
9
11
  # Define a sifter that can be used within DSL blocks.
10
12
  #
@@ -0,0 +1,52 @@
1
+ require 'baby_squeel/calculation'
2
+ require 'baby_squeel/pluck'
3
+
4
+ module BabySqueel
5
+ module ActiveRecord
6
+ module Calculations
7
+ def plucking(&block)
8
+ pluck Pluck.wrap(DSL.evaluate(self, &block))
9
+ end
10
+
11
+ def counting(&block)
12
+ count Calculation.new(DSL.evaluate(self, &block))
13
+ end
14
+
15
+ def summing(&block)
16
+ sum Calculation.new(DSL.evaluate(self, &block))
17
+ end
18
+
19
+ def averaging(&block)
20
+ average Calculation.new(DSL.evaluate(self, &block))
21
+ end
22
+
23
+ def minimizing(&block)
24
+ minimum Calculation.new(DSL.evaluate(self, &block))
25
+ end
26
+
27
+ def maximizing(&block)
28
+ maximum Calculation.new(DSL.evaluate(self, &block))
29
+ end
30
+
31
+ # @override
32
+ def aggregate_column(column_name)
33
+ if column_name.kind_of? Calculation
34
+ column_name.node
35
+ else
36
+ super
37
+ end
38
+ end
39
+
40
+ if ::ActiveRecord::VERSION::MAJOR < 5
41
+ # @override
42
+ def type_for(field)
43
+ if field.kind_of? Calculation
44
+ field
45
+ else
46
+ super
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -29,40 +29,6 @@ module BabySqueel
29
29
  having DSL.evaluate(self, &block)
30
30
  end
31
31
 
32
- if ::ActiveRecord::VERSION::MAJOR >= 5
33
- def plucking(&block)
34
- pluck DSL.evaluate(self, &block)
35
- end
36
- elsif ::ActiveRecord::VERSION::STRING >= '4.2.0'
37
- def plucking(&block)
38
- relation = selecting(&block)
39
- binds = relation.arel.bind_values + bind_values
40
- result = klass.connection.select_all(relation.arel, nil, binds)
41
- result.cast_values(klass.column_types)
42
- end
43
- else
44
- def plucking(&block)
45
- relation = selecting(&block)
46
- binds = relation.arel.bind_values + bind_values
47
- result = klass.connection.select_all(relation.arel, nil, binds)
48
- columns = result.columns.map do |key|
49
- klass.column_types.fetch(key) {
50
- result.column_types.fetch(key) { result.identity_type }
51
- }
52
- end
53
-
54
- result = result.rows.map do |values|
55
- values = result.columns.zip(values).map do |column_name, value|
56
- single_attr_hash = { column_name => value }
57
- klass.initialize_attributes(single_attr_hash).values.first
58
- end
59
-
60
- columns.zip(values).map { |column, value| column.type_cast value }
61
- end
62
- columns.one? ? result.map!(&:first) : result
63
- end
64
- end
65
-
66
32
  private
67
33
 
68
34
  # This is a monkey patch, and I'm not happy about it.
@@ -99,7 +99,7 @@ module BabySqueel
99
99
  if ActiveRecord::VERSION::MAJOR >= 5
100
100
  def build_where_clause(other)
101
101
  if valid_where_clause?(other)
102
- relation = @parent._scope.where(nil)
102
+ relation = @parent._scope.all
103
103
  factory = relation.send(:where_clause_factory)
104
104
  factory.build({ _reflection.name => other }, [])
105
105
  else
@@ -0,0 +1,35 @@
1
+ module BabySqueel
2
+ class Calculation # :nodoc:
3
+ attr_reader :node
4
+
5
+ def initialize(node)
6
+ @node = node
7
+ end
8
+
9
+ # This is only used in 4.2. We're just pretending to be
10
+ # a database column to fake the casting here.
11
+ def type_cast_from_database(value)
12
+ value
13
+ end
14
+
15
+ # In Active Record 5, we don't *need* this class to make
16
+ # calculations work. They happily accept arel. However,
17
+ # when grouping with a calculation, there's a really,
18
+ # really weird alias name. It calls #to_s on the Arel.
19
+ #
20
+ # If this were not addressed, it would likely break query
21
+ # caching because the alias would have a unique name every
22
+ # time.
23
+ def to_s
24
+ names = node.map do |child|
25
+ if child.kind_of?(String) || child.kind_of?(Symbol)
26
+ child.to_s
27
+ elsif child.respond_to?(:name)
28
+ child.name.to_s
29
+ end
30
+ end
31
+
32
+ names.compact.uniq.join('_')
33
+ end
34
+ end
35
+ end
@@ -5,19 +5,11 @@ require 'baby_squeel/association'
5
5
  module BabySqueel
6
6
  class DSL < Relation
7
7
  class << self
8
- # Evaluates a block and unwraps the nodes
9
- def evaluate(scope, &block)
10
- Nodes.unwrap evaluate!(scope, &block)
8
+ def evaluate(scope, &block) # :nodoc:
9
+ Nodes.unwrap new(scope).evaluate(&block)
11
10
  end
12
11
 
13
- # Evaluates a block in the context of a DSL instance
14
- def evaluate!(scope, &block)
15
- new(scope).evaluate(&block)
16
- end
17
-
18
- # Evaluates a block in the context of a new DSL instance
19
- # and passes all arguments to the block.
20
- def evaluate_sifter(scope, *args, &block)
12
+ def evaluate_sifter(scope, *args, &block) # :nodoc:
21
13
  evaluate scope do |root|
22
14
  root.instance_exec(*args, &block)
23
15
  end
@@ -17,6 +17,14 @@ module BabySqueel
17
17
  end
18
18
  end
19
19
 
20
+ def not_in(rel)
21
+ if rel.is_a? ::ActiveRecord::Relation
22
+ ::Arel::Nodes::NotIn.new(self, Arel.sql(rel.to_sql))
23
+ else
24
+ super
25
+ end
26
+ end
27
+
20
28
  def _arel
21
29
  if @parent.kind_of? BabySqueel::Association
22
30
  @parent.find_alias[@name]
@@ -0,0 +1,25 @@
1
+ module BabySqueel
2
+ class Pluck # :nodoc:
3
+ # In Active Record 4.2, #pluck chokes when you give it
4
+ # Arel. It calls #to_s on whatever you pass in. So the
5
+ # hacky solution is to wrap the node in a class that
6
+ # returns the node when you call #to_s. Then, it works!
7
+ #
8
+ # In Active Record 5, #pluck accepts Arel, so we won't
9
+ # bother to use this there.
10
+
11
+ if ::ActiveRecord::VERSION::MAJOR >= 5
12
+ def self.wrap(node); node; end
13
+ else
14
+ def self.wrap(node); new(node); end
15
+ end
16
+
17
+ def initialize(node)
18
+ @node = node
19
+ end
20
+
21
+ def to_s
22
+ @node
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module BabySqueel
2
- VERSION = '1.0.3'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baby_squeel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Zane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-09 00:00:00.000000000 Z
11
+ date: 2017-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.1.0
19
+ version: 4.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 4.1.0
26
+ version: 4.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: polyamorous
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +94,7 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: A tiny squeel implementation without all of the evil.
97
+ description: An expressive query DSL for Active Record 4 and 5.
98
98
  email:
99
99
  - ray@promptworks.com
100
100
  executables: []
@@ -108,9 +108,11 @@ files:
108
108
  - baby_squeel.gemspec
109
109
  - lib/baby_squeel.rb
110
110
  - lib/baby_squeel/active_record/base.rb
111
+ - lib/baby_squeel/active_record/calculations.rb
111
112
  - lib/baby_squeel/active_record/query_methods.rb
112
113
  - lib/baby_squeel/active_record/where_chain.rb
113
114
  - lib/baby_squeel/association.rb
115
+ - lib/baby_squeel/calculation.rb
114
116
  - lib/baby_squeel/compat.rb
115
117
  - lib/baby_squeel/dsl.rb
116
118
  - lib/baby_squeel/errors.rb
@@ -125,6 +127,7 @@ files:
125
127
  - lib/baby_squeel/nodes/node.rb
126
128
  - lib/baby_squeel/nodes/proxy.rb
127
129
  - lib/baby_squeel/operators.rb
130
+ - lib/baby_squeel/pluck.rb
128
131
  - lib/baby_squeel/relation.rb
129
132
  - lib/baby_squeel/table.rb
130
133
  - lib/baby_squeel/version.rb
@@ -151,5 +154,5 @@ rubyforge_project:
151
154
  rubygems_version: 2.6.8
152
155
  signing_key:
153
156
  specification_version: 4
154
- summary: A tiny squeel implementation without all of the evil.
157
+ summary: An expressive query DSL for Active Record 4 and 5.
155
158
  test_files: []