calculate-all 0.2.0 → 0.2.2
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 +5 -5
- data/.github/workflows/build.yml +39 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +10 -4
- data/README.md +42 -33
- data/Rakefile +6 -6
- data/_config.yml +1 -0
- data/bin/setup +5 -2
- data/calculate-all.gemspec +14 -22
- data/gemfiles/activerecord42.gemfile +11 -0
- data/gemfiles/activerecord50.gemfile +11 -0
- data/gemfiles/activerecord51.gemfile +11 -0
- data/gemfiles/activerecord52.gemfile +11 -0
- data/gemfiles/activerecord60.gemfile +11 -0
- data/gemfiles/activerecord61.gemfile +11 -0
- data/lib/calculate-all/helpers.rb +3 -2
- data/lib/calculate-all/querying.rb +4 -1
- data/lib/calculate-all/version.rb +1 -1
- data/lib/calculate-all.rb +60 -56
- metadata +16 -95
- data/.travis.yml +0 -4
- data/bin/console +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3cd324cd911d0d4998540ce59b30addac7a8e9842676f1adbf75b5bf6adee1c0
|
4
|
+
data.tar.gz: 26ff146cce10d207334d6232e72dae5d8d558246fd47f58da7571a6e84bbba7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1570c270af925b14130207b5905235d02f19960fc83f2ae189c67cd482a06538b341a031279daea5c8dc01933eb5303c0cc5db30a7fb706a4ff111c79bac4ec4
|
7
|
+
data.tar.gz: 38f29b21183c14901b61790e5e4a69ce70918e2c99bac4ba4a714a5ee8a1be4466bfcc6ab6cfd93e43a098041d8cbedfa4206c2adc1d6ce766111cdbd0db26f1
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: build
|
2
|
+
on: [push, pull_request]
|
3
|
+
jobs:
|
4
|
+
build:
|
5
|
+
strategy:
|
6
|
+
fail-fast: false
|
7
|
+
matrix:
|
8
|
+
include:
|
9
|
+
- ruby: "3.1"
|
10
|
+
gemfile: Gemfile
|
11
|
+
- ruby: "3.0"
|
12
|
+
gemfile: gemfiles/activerecord61.gemfile
|
13
|
+
- ruby: "2.7"
|
14
|
+
gemfile: gemfiles/activerecord60.gemfile
|
15
|
+
- ruby: "2.6"
|
16
|
+
gemfile: gemfiles/activerecord52.gemfile
|
17
|
+
- ruby: "2.6"
|
18
|
+
gemfile: gemfiles/activerecord51.gemfile
|
19
|
+
- ruby: "2.6"
|
20
|
+
gemfile: gemfiles/activerecord50.gemfile
|
21
|
+
- ruby: "2.5"
|
22
|
+
gemfile: gemfiles/activerecord42.gemfile
|
23
|
+
runs-on: ubuntu-latest
|
24
|
+
env:
|
25
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
26
|
+
steps:
|
27
|
+
- uses: actions/checkout@v2
|
28
|
+
- uses: ruby/setup-ruby@v1
|
29
|
+
with:
|
30
|
+
ruby-version: ${{ matrix.ruby }}
|
31
|
+
bundler-cache: true
|
32
|
+
- uses: ankane/setup-postgres@v1
|
33
|
+
with:
|
34
|
+
database: calculate_all_test
|
35
|
+
- uses: ankane/setup-mysql@v1
|
36
|
+
with:
|
37
|
+
database: calculate_all_test
|
38
|
+
- run: mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
|
39
|
+
- run: bundle exec rake test
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 0.2.2
|
2
|
+
|
3
|
+
* Added support for Groupdate 4+ (Andrew <acekane1@gmail.com>)
|
4
|
+
* Tested with sqlite3, ruby 3.1, Rails 7
|
5
|
+
|
6
|
+
## 0.2.1
|
7
|
+
|
8
|
+
* Silence deprecation warnings (Forrest Ye <fye@mutan.io>)
|
9
|
+
|
10
|
+
## 0.2.0
|
11
|
+
|
12
|
+
* Rails 5 compatibility (Stef Schenkelaars <stef.schenkelaars@gmail.com>)
|
13
|
+
|
1
14
|
## 0.1.1
|
2
15
|
|
3
16
|
* groupdate compatibility
|
data/Gemfile
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
|
-
# Specify your gem's dependencies in calculate-all.gemspec
|
4
3
|
gemspec
|
5
4
|
|
6
|
-
gem
|
7
|
-
gem
|
5
|
+
gem "rake"
|
6
|
+
gem "minitest"
|
7
|
+
gem "activerecord", "~> 7.0.0"
|
8
|
+
gem "groupdate", "~> 5.2.0"
|
9
|
+
gem "pg"
|
10
|
+
gem "mysql2"
|
11
|
+
gem "sqlite3", "~> 1.4"
|
12
|
+
|
13
|
+
gem "standardrb", require: false
|
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# CalculateAll
|
2
2
|
|
3
|
-
Provides `#calculate_all` method
|
4
|
-
It's a
|
5
|
-
It allows to fetch all of the above
|
3
|
+
Provides the `#calculate_all` method for your Active Record models, scopes and relations.
|
4
|
+
It's a small addition to Active Record's `#count`, `#maximum`, `#minimum`, `#average` and `#sum`.
|
5
|
+
It allows you to fetch all of the above, as well as other aggregate function results,
|
6
|
+
in a single request, with support for grouping.
|
6
7
|
|
7
|
-
|
8
|
+
Currently tested with Postgres, MySQL and sqlite3, ruby >= 2.3, rails >= 4, groupdate >= 4.
|
8
9
|
|
9
10
|
## Usage
|
10
11
|
|
@@ -27,8 +28,8 @@ stats = Order.group(:department_id).group(:payment_method).calculate_all(
|
|
27
28
|
# count_distinct_user_id: 5,
|
28
29
|
# price_max: 500,
|
29
30
|
# price_min: 100,
|
30
|
-
# price_avg:
|
31
|
-
# price_median:
|
31
|
+
# price_avg: 0.3e3,
|
32
|
+
# price_median: 0.4e3
|
32
33
|
# },
|
33
34
|
# [1, "card"] => {
|
34
35
|
# ...
|
@@ -36,23 +37,24 @@ stats = Order.group(:department_id).group(:payment_method).calculate_all(
|
|
36
37
|
# }
|
37
38
|
```
|
38
39
|
|
40
|
+
(median example works in Postgres only, but check out very cool https://github.com/ankane/active_median)
|
41
|
+
|
39
42
|
## Rationale
|
40
43
|
|
41
|
-
Active Record
|
42
|
-
But there's a whole world of
|
43
|
-
|
44
|
-
|
45
|
-
[too](http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html).
|
44
|
+
Active Record makes it really easy to use most common database aggregate functions like COUNT(), MAX(), MIN(), AVG(), SUM().
|
45
|
+
But there's a whole world of other [powerful functions](http://www.postgresql.org/docs/current/functions-aggregate.html) in
|
46
|
+
Postgres, which I can’t recommend enough, especially if you’re working with statistics or business intelligence.
|
47
|
+
MySQL has some useful ones [as well](https://dev.mysql.com/doc/refman/9.3/en/aggregate-functions.html).
|
46
48
|
|
47
|
-
Also, in many cases you
|
48
|
-
|
49
|
+
Also, in many cases, you’ll need multiple metrics at once. Typically, the database performs a full scan of the table for each metric.
|
50
|
+
However, it can calculate all of them in a single scan and a single request.
|
49
51
|
|
50
52
|
`#calculate_all` to the rescue!
|
51
53
|
|
52
54
|
## Arguments
|
53
55
|
|
54
|
-
`#calculate_all` accepts a list of expression aliases and/or expression
|
55
|
-
It
|
56
|
+
`#calculate_all` accepts a list of expression aliases and/or expression mappings.
|
57
|
+
It can be a single string of SQL,
|
56
58
|
|
57
59
|
```ruby
|
58
60
|
Model.calculate_all('SUM(price) / COUNT(DISTINCT user_id)')
|
@@ -63,7 +65,7 @@ a hash of expressions with arbitrary symbol keys
|
|
63
65
|
```ruby
|
64
66
|
Model.calculate_all(total: 'COUNT(*)', average_spendings: 'SUM(price) / COUNT(DISTINCT user_id)')
|
65
67
|
```
|
66
|
-
or a list of one or more symbols without expressions, in which case `#calculate_all` tries to guess
|
68
|
+
and/or a list of one or more symbols without expressions, in which case `#calculate_all` tries to guess
|
67
69
|
what you wanted from it.
|
68
70
|
|
69
71
|
```ruby
|
@@ -82,6 +84,9 @@ It's not so smart right now, but here's a cheatsheet:
|
|
82
84
|
| `:avg_column1`, `:column1_avg`, `:average_column1`, `:column1_average` | `AVG(column1)`
|
83
85
|
| `:sum_column1`, `:column1_sum` | `SUM(column1)`
|
84
86
|
|
87
|
+
Please don't put values from unverified sources (like HTML form or javascript call) into expression list,
|
88
|
+
it could result in malicious SQL injection.
|
89
|
+
|
85
90
|
## Result
|
86
91
|
|
87
92
|
`#calculate_all` tries to mimic magic of Active Record's `#group`, `#count` and `#pluck`
|
@@ -90,16 +95,16 @@ so result type depends on arguments and on groupings.
|
|
90
95
|
If you have no `group()` on underlying scope, `#calculate_all` will return just one result.
|
91
96
|
|
92
97
|
```ruby
|
93
|
-
#
|
94
|
-
#
|
98
|
+
# Same as Order.distinct.count(:user_id), so probably a useless example.
|
99
|
+
# But you can use any expression with aggregate functions there.
|
95
100
|
Order.calculate_all('COUNT(DISTINCT user_id)')
|
96
101
|
# => 50
|
97
102
|
```
|
98
103
|
|
99
|
-
If you have
|
104
|
+
If you have a single `group()`, it will return a hash of results with simple keys.
|
100
105
|
|
101
106
|
```ruby
|
102
|
-
#
|
107
|
+
# Again, Order.group(:department_id).distinct.count(:user_id) would do the same.
|
103
108
|
Order.group(:department_id).calculate_all(:count_distinct_user_id)
|
104
109
|
# => {
|
105
110
|
# 1 => 20,
|
@@ -120,8 +125,8 @@ Order.group(:department_id).group(:department_method).calculate_all(:count_disti
|
|
120
125
|
# }
|
121
126
|
```
|
122
127
|
|
123
|
-
If you provide
|
124
|
-
Otherwise results
|
128
|
+
If you provide only one argument to `#calculate_all`, its calculated value will be returned as-is.
|
129
|
+
Otherwise, the results will be returned as hash(es) with symbol keys.
|
125
130
|
|
126
131
|
so, `Order.calculate_all(:count)` will return just a single integer, but
|
127
132
|
|
@@ -134,8 +139,8 @@ Order.group(:department_id).group(:payment_method).calculate_all(:min_price, exp
|
|
134
139
|
# }
|
135
140
|
```
|
136
141
|
|
137
|
-
You can pass block to calculate_all
|
138
|
-
row in result hash (or returned as
|
142
|
+
You can pass a block to `calculate_all`. Rows will be passed to it, and returned value will be used instead of
|
143
|
+
the row in the result hash (or returned as-is if there's no grouping).
|
139
144
|
|
140
145
|
```ruby
|
141
146
|
Order.group(:country_id).calculate_all(:count, :avg_price) { |count:, avg_price:|
|
@@ -161,16 +166,18 @@ Order.calculate_all(:count, :max_price, &OpenStruct.method(:new))
|
|
161
166
|
calculate-all should work with [groupdate](https://github.com/ankane/groupdate) too:
|
162
167
|
|
163
168
|
```ruby
|
164
|
-
Order.group_by_year(:created_at, last: 5
|
165
|
-
=> {
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
}
|
169
|
+
Order.group_by_year(:created_at, last: 5).calculate_all(:price_min, :price_max)
|
170
|
+
# => {
|
171
|
+
# Sun, 01 Jan 2012 => {},
|
172
|
+
# Tue, 01 Jan 2013 => {},
|
173
|
+
# Wed, 01 Jan 2014 => {},
|
174
|
+
# Thu, 01 Jan 2015 => {},
|
175
|
+
# Fri, 01 Jan 2016 => {:price_min=>100, :price_max=>500}
|
176
|
+
# }
|
172
177
|
```
|
173
178
|
|
179
|
+
It works even with groupdate < 4, though you'd have to explicitly provide `default_value: {}` for blank periods.
|
180
|
+
|
174
181
|
## Installation
|
175
182
|
|
176
183
|
Add this line to your application's Gemfile:
|
@@ -189,7 +196,9 @@ Or install it yourself as:
|
|
189
196
|
|
190
197
|
## Development
|
191
198
|
|
192
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
|
199
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
|
200
|
+
Run `BUNDLE_GEMFILE=gemfiles/activerecord60.gemfile bundle` then `BUNDLE_GEMFILE=gemfiles/activerecord60.gemfile rake`
|
201
|
+
to test agains specific active record version.
|
193
202
|
|
194
203
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
195
204
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
3
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs <<
|
6
|
-
t.libs <<
|
7
|
-
t.test_files = FileList[
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
-
task :
|
10
|
+
task default: :test
|
data/_config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
theme: jekyll-theme-cayman
|
data/bin/setup
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
set -euo pipefail
|
3
3
|
IFS=$'\n\t'
|
4
4
|
|
5
|
+
echo "Installing gems..."
|
5
6
|
bundle install
|
6
|
-
|
7
|
-
|
7
|
+
echo "Creating postgres database..."
|
8
|
+
createdb calculate_all_test || echo "...failed"
|
9
|
+
echo "Creating mysql database..."
|
10
|
+
mysqladmin -u root create calculate_all_test || echo "...failed"
|
data/calculate-all.gemspec
CHANGED
@@ -1,30 +1,22 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "calculate-all/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
6
|
+
spec.name = "calculate-all"
|
7
|
+
spec.version = CalculateAll::VERSION
|
8
|
+
spec.authors = ["Alexey Trofimenko"]
|
9
|
+
spec.email = ["aronaxis@gmail.com"]
|
11
10
|
|
12
|
-
spec.summary
|
13
|
-
spec.description
|
14
|
-
spec.homepage
|
15
|
-
spec.license
|
11
|
+
spec.summary = "Fetch from database results of several aggregate functions at once"
|
12
|
+
spec.description = "Extends Active Record with #calculate_all method"
|
13
|
+
spec.homepage = "http://github.com/codesnik/calculate-all"
|
14
|
+
spec.license = "MIT"
|
16
15
|
|
17
|
-
spec.files
|
18
|
-
spec.bindir
|
19
|
-
spec.executables
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
19
|
spec.require_paths = ["lib"]
|
21
20
|
|
22
|
-
spec.add_dependency "
|
23
|
-
|
24
|
-
spec.add_development_dependency "bundler", "~> 1.10"
|
25
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
-
spec.add_development_dependency "minitest"
|
27
|
-
spec.add_development_dependency "pg"
|
28
|
-
spec.add_development_dependency "mysql2"
|
29
|
-
spec.add_development_dependency "groupdate"
|
21
|
+
spec.add_dependency "activesupport"
|
30
22
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module CalculateAll
|
2
2
|
module Helpers
|
3
3
|
module_function
|
4
|
-
|
4
|
+
|
5
|
+
# Convert aliases like :count to SQL aggregate functions like 'COUNT(*)'
|
5
6
|
def decode_function_aliases(aliases)
|
6
7
|
aliases.map do |key|
|
7
8
|
function =
|
@@ -9,7 +10,7 @@ module CalculateAll
|
|
9
10
|
when String
|
10
11
|
key
|
11
12
|
when :count
|
12
|
-
|
13
|
+
"COUNT(*)"
|
13
14
|
when /^(.*)_distinct_count$/, /^count_distinct_(.*)$/
|
14
15
|
"COUNT(DISTINCT #{$1})"
|
15
16
|
when /^(.*)_(count|sum|max|min|avg)$/
|
data/lib/calculate-all.rb
CHANGED
@@ -1,84 +1,88 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'calculate-all/querying'
|
1
|
+
require "active_support"
|
2
|
+
require "calculate-all/version"
|
4
3
|
|
5
4
|
module CalculateAll
|
6
|
-
#
|
5
|
+
# Calculates multiple aggregate values on a scope in one request, similarly to #calculate
|
7
6
|
def calculate_all(*function_aliases, **functions, &block)
|
8
|
-
|
9
|
-
#
|
10
|
-
|
11
|
-
if function_aliases.size == 1 && functions == {}
|
7
|
+
# If only one aggregate is given without explicit naming,
|
8
|
+
# return row(s) directly without wrapping in Hash
|
9
|
+
if function_aliases.size == 1 && functions.size == 0
|
12
10
|
return_plain_values = true
|
13
11
|
end
|
14
12
|
|
15
13
|
# Convert the function_aliases to actual SQL
|
16
|
-
functions.merge!(
|
17
|
-
CalculateAll::Helpers.decode_function_aliases(function_aliases)
|
18
|
-
)
|
14
|
+
functions.merge!(CalculateAll::Helpers.decode_function_aliases(function_aliases))
|
19
15
|
|
20
16
|
# Check if any functions are given
|
21
17
|
if functions == {}
|
22
|
-
raise ArgumentError,
|
23
|
-
end
|
24
|
-
|
25
|
-
# If function is called without a group, the pluck method will still return
|
26
|
-
# an array but it is an array with the final results instead of each group
|
27
|
-
# The plain_rows boolean states how the results should be used
|
28
|
-
if functions.size == 1 && group_values.size == 0
|
29
|
-
plain_rows = true
|
18
|
+
raise ArgumentError, "provide at least one function to calculate"
|
30
19
|
end
|
31
20
|
|
32
|
-
|
21
|
+
columns = (group_values.map(&:to_s) + functions.values).map { |sql| Arel.sql(sql) }
|
33
22
|
results = {}
|
23
|
+
pluck(*columns).each do |row|
|
24
|
+
# If pluck called without any groups and with a single argument,
|
25
|
+
# it will return an array of simple results instead of array of arrays
|
26
|
+
if functions.size == 1 && group_values.size == 0
|
27
|
+
row = [row]
|
28
|
+
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# If no grouping, make sure it is still a results array
|
42
|
-
row = [row] if plain_rows
|
43
|
-
|
44
|
-
# If only one value, return a single value, else return a hash
|
45
|
-
if return_plain_values
|
46
|
-
value = row.last
|
30
|
+
key = if group_values.size == 0
|
31
|
+
:ALL
|
32
|
+
elsif group_values.size == 1
|
33
|
+
# If only one group is provided, the resulting key is just a scalar value
|
34
|
+
row.shift
|
47
35
|
else
|
48
|
-
|
36
|
+
# if multiple groups, the key will be an array.
|
37
|
+
row.shift(group_values.size)
|
49
38
|
end
|
50
39
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
# Return unwrapped hash directly for scope without any .group()
|
55
|
-
return value if group_values.empty?
|
56
|
-
|
57
|
-
# If only one group is provided, the resulting key is just the group name
|
58
|
-
# if multiple group methods are provided, the key will be an array.
|
59
|
-
if group_values.size == 1
|
60
|
-
key = row.first
|
40
|
+
value = if return_plain_values
|
41
|
+
row.last
|
61
42
|
else
|
62
|
-
|
43
|
+
# it is possible to have more actual group values returned than group_values.size
|
44
|
+
functions.keys.zip(row.last(functions.size)).to_h
|
63
45
|
end
|
64
46
|
|
65
|
-
# Set the value in the output array
|
66
47
|
results[key] = value
|
67
48
|
end
|
68
49
|
|
69
|
-
#
|
70
|
-
|
50
|
+
# Additional groupdate magic of filling empty periods with defaults
|
51
|
+
if defined?(Groupdate.process_result)
|
52
|
+
# Since that hash is the same instance for every backfilled raw, at least
|
53
|
+
# freeze it to prevent surprize modifications in calling code.
|
54
|
+
default_value = return_plain_values ? nil : {}.freeze
|
55
|
+
results = Groupdate.process_result(self, results, default_value: default_value)
|
56
|
+
end
|
57
|
+
|
58
|
+
if block
|
59
|
+
results.transform_values! do |value|
|
60
|
+
return_plain_values ? block.call(value) : block.call(**value)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return unwrapped hash directly for scope without any .group()
|
65
|
+
if group_values.empty?
|
66
|
+
results[:ALL]
|
67
|
+
else
|
68
|
+
results
|
69
|
+
end
|
71
70
|
end
|
72
71
|
end
|
73
72
|
|
74
|
-
|
75
|
-
|
73
|
+
ActiveSupport.on_load(:active_record) do
|
74
|
+
require "calculate-all/helpers"
|
75
|
+
require "calculate-all/querying"
|
76
76
|
|
77
|
-
# Make the calculate_all method available for all ActiveRecord::
|
78
|
-
|
79
|
-
ActiveRecord::Base.extend CalculateAll::Querying
|
77
|
+
# Make the calculate_all method available for all ActiveRecord::Relations instances
|
78
|
+
ActiveRecord::Relation.include CalculateAll
|
80
79
|
|
81
|
-
#
|
82
|
-
#
|
83
|
-
|
84
|
-
|
80
|
+
# Make the calculate_all method available for all ActiveRecord::Base classes
|
81
|
+
# You can for example call Orders.calculate_all(:count, :sum_cents)
|
82
|
+
ActiveRecord::Base.extend CalculateAll::Querying
|
83
|
+
|
84
|
+
# A hack for groupdate 3.0 since it checks if the calculate_all method is defined
|
85
|
+
# on the ActiveRecord::Calculations module. It is never called but it is just
|
86
|
+
# needed for the check.
|
87
|
+
ActiveRecord::Calculations.include CalculateAll::Querying
|
88
|
+
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: calculate-all
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
autorequire:
|
7
|
+
- Alexey Trofimenko
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -24,90 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.10'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.10'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '10.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '10.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: minitest
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: pg
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: mysql2
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: groupdate
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
27
|
description: 'Extends Active Record with #calculate_all method'
|
112
28
|
email:
|
113
29
|
- aronaxis@gmail.com
|
@@ -115,16 +31,22 @@ executables: []
|
|
115
31
|
extensions: []
|
116
32
|
extra_rdoc_files: []
|
117
33
|
files:
|
34
|
+
- ".github/workflows/build.yml"
|
118
35
|
- ".gitignore"
|
119
|
-
- ".travis.yml"
|
120
36
|
- CHANGELOG.md
|
121
37
|
- Gemfile
|
122
38
|
- LICENSE.txt
|
123
39
|
- README.md
|
124
40
|
- Rakefile
|
125
|
-
-
|
41
|
+
- _config.yml
|
126
42
|
- bin/setup
|
127
43
|
- calculate-all.gemspec
|
44
|
+
- gemfiles/activerecord42.gemfile
|
45
|
+
- gemfiles/activerecord50.gemfile
|
46
|
+
- gemfiles/activerecord51.gemfile
|
47
|
+
- gemfiles/activerecord52.gemfile
|
48
|
+
- gemfiles/activerecord60.gemfile
|
49
|
+
- gemfiles/activerecord61.gemfile
|
128
50
|
- lib/calculate-all.rb
|
129
51
|
- lib/calculate-all/helpers.rb
|
130
52
|
- lib/calculate-all/querying.rb
|
@@ -133,7 +55,7 @@ homepage: http://github.com/codesnik/calculate-all
|
|
133
55
|
licenses:
|
134
56
|
- MIT
|
135
57
|
metadata: {}
|
136
|
-
post_install_message:
|
58
|
+
post_install_message:
|
137
59
|
rdoc_options: []
|
138
60
|
require_paths:
|
139
61
|
- lib
|
@@ -148,9 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
70
|
- !ruby/object:Gem::Version
|
149
71
|
version: '0'
|
150
72
|
requirements: []
|
151
|
-
|
152
|
-
|
153
|
-
signing_key:
|
73
|
+
rubygems_version: 3.4.19
|
74
|
+
signing_key:
|
154
75
|
specification_version: 4
|
155
76
|
summary: Fetch from database results of several aggregate functions at once
|
156
77
|
test_files: []
|
data/.travis.yml
DELETED