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 +4 -4
- data/CHANGELOG.md +9 -2
- data/baby_squeel.gemspec +2 -2
- data/lib/baby_squeel.rb +2 -0
- data/lib/baby_squeel/active_record/base.rb +3 -1
- data/lib/baby_squeel/active_record/calculations.rb +52 -0
- data/lib/baby_squeel/active_record/query_methods.rb +0 -34
- data/lib/baby_squeel/association.rb +1 -1
- data/lib/baby_squeel/calculation.rb +35 -0
- data/lib/baby_squeel/dsl.rb +3 -11
- data/lib/baby_squeel/nodes/attribute.rb +8 -0
- data/lib/baby_squeel/pluck.rb +25 -0
- data/lib/baby_squeel/version.rb +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c05b66383b8b74c1c6ba92af1164da82a4290a2
|
4
|
+
data.tar.gz: 19d23ae9dae15bc8f7b8acb91f18272f7101e9c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ff0c39cba1d8b76911020f7b1a66affacddfb6dbe5a4e63a6cf7752f40bcdc30180fcfb95fa5437c495146469a30dbf7e73ceeddf5ca7fbb75d5c6810ff245b
|
7
|
+
data.tar.gz: e765fd51a96096549e971be4a8ffd87a2ae24300475e49043eddf33b692500501f2a1ca3ca8933048aedc08ea60f18f9748dfc93d1bd69f84e5067a9cf9d2594
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
|
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
|
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 = '
|
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.
|
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,
|
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.
|
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
|
data/lib/baby_squeel/dsl.rb
CHANGED
@@ -5,19 +5,11 @@ require 'baby_squeel/association'
|
|
5
5
|
module BabySqueel
|
6
6
|
class DSL < Relation
|
7
7
|
class << self
|
8
|
-
|
9
|
-
|
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
|
-
|
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
|
data/lib/baby_squeel/version.rb
CHANGED
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
|
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-
|
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.
|
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.
|
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:
|
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:
|
157
|
+
summary: An expressive query DSL for Active Record 4 and 5.
|
155
158
|
test_files: []
|