baby_squeel 1.0.3 → 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.
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: []