calculations_by_time_range 0.2.0 → 0.2.1
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.
- data/README.rdoc +2 -2
- data/VERSION +1 -1
- data/calculations_by_time_range.gemspec +2 -1
- data/lib/calculations_by_time_range.rb +4 -54
- data/lib/calculations_by_time_range/active_record/calculations.rb +58 -0
- data/rails/init.rb +0 -1
- metadata +2 -1
data/README.rdoc
CHANGED
@@ -14,8 +14,8 @@ You could count how many people register by day:
|
|
14
14
|
User.counts_by_day
|
15
15
|
|
16
16
|
|
17
|
-
Found sum of ages by month:
|
18
|
-
User.
|
17
|
+
Found sum of ages by month in field updated_at:
|
18
|
+
User.sums_by :month, 'age', 'updated_at'
|
19
19
|
|
20
20
|
== Note on Patches/Pull Requests
|
21
21
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.1
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{calculations_by_time_range}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Nikitochkin"]
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"calculations_by_time_range.gemspec",
|
27
27
|
"lib/calculations_by_time_range.rb",
|
28
|
+
"lib/calculations_by_time_range/active_record/calculations.rb",
|
28
29
|
"rails/init.rb",
|
29
30
|
"test/helper.rb",
|
30
31
|
"test/test_calculations_by_time_range.rb"
|
@@ -1,56 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
QUERY = (ActiveRecord::Base.connection.adapter_name == "PostgreSQL") ? "EXTRACT(%s FROM %s + INTERVAL '%d hour')" : "EXTRACT(%s FROM %s + INTERVAL %d hour)"
|
6
|
-
|
7
|
-
COLUMNS = {
|
8
|
-
:year => [:year],
|
9
|
-
:month => [:year, :month],
|
10
|
-
:week => [:year, :month, :week],
|
11
|
-
:day => [:year, :month, :week, :day],
|
12
|
-
:hour => [:year, :month, :week, :day, :hour]
|
13
|
-
}
|
14
|
-
|
15
|
-
OPERATIONS = ["sum", "count", "min", "max", "avg"]
|
16
|
-
|
17
|
-
COLUMNS.each do |k,v|
|
18
|
-
OPERATIONS.each do |o|
|
19
|
-
define_method "#{o.pluralize}_by_#{k.to_s}" do
|
20
|
-
calculations_by_time_column(o.to_sym, v, :column => 'id', :time_column => 'created_at')
|
21
|
-
end
|
22
|
-
|
23
|
-
define_method "#{o.pluralize}_by" do |*args|
|
24
|
-
range, column, time_column = args
|
25
|
-
calculations_by_time_column(o.to_sym, COLUMNS[range.to_sym], :column => column || "id", :time_column => time_column || "created_at")
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def calculations_by_time_column(operation, fields = [], opts = {})
|
33
|
-
options = {:time_column => 'created_at', :column => 'id'}
|
34
|
-
options = options.merge(opts)
|
35
|
-
|
36
|
-
fields = [fields] if !fields.is_a?(Array)
|
37
|
-
select_q, order_by_q, group_by_q = [], [], []
|
38
|
-
|
39
|
-
fields.each_with_index do|range, indx|
|
40
|
-
q = QUERY % [range, options[:time_column], @@time_zone_offset_in_hours]
|
41
|
-
select_q << ((q + " AS %s_%s") % [range.to_s, options[:time_column]])
|
42
|
-
group_by_q << q
|
43
|
-
order_by_q << 2 + indx
|
44
|
-
end
|
45
|
-
|
46
|
-
sql = "SELECT %s(%s) AS %s_all, %s FROM %s " % [operation, options[:column], operation, select_q.join(','), table_name]
|
47
|
-
|
48
|
-
add_conditions!(sql, options[:conditions])
|
49
|
-
sql << "GROUP BY #{group_by_q.join(',')}
|
50
|
-
ORDER BY #{order_by_q.join(',')}"
|
51
|
-
find_by_sql(sql)
|
52
|
-
end
|
53
|
-
|
1
|
+
require 'calculations_by_time_range/active_record/calculations'
|
2
|
+
module ActiveRecord
|
3
|
+
class Base
|
4
|
+
class << self; include CalculationsByTimeRange::ActiveRecord::Calculations end
|
54
5
|
end
|
55
6
|
end
|
56
|
-
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module CalculationsByTimeRange
|
2
|
+
module ActiveRecord
|
3
|
+
module Calculations
|
4
|
+
|
5
|
+
TIME_OFFSET = Time.zone.utc_offset / 3600
|
6
|
+
|
7
|
+
COLUMNS = {
|
8
|
+
:year => [:year],
|
9
|
+
:month => [:year, :month],
|
10
|
+
:week => [:year, :month, :week],
|
11
|
+
:day => [:year, :month, :week, :day],
|
12
|
+
:hour => [:year, :month, :week, :day, :hour]
|
13
|
+
}
|
14
|
+
|
15
|
+
OPERATIONS = ["sum", "count", "min", "max", "avg"]
|
16
|
+
|
17
|
+
COLUMNS.each do |k,v|
|
18
|
+
OPERATIONS.each do |o|
|
19
|
+
define_method "#{o.pluralize}_by_#{k.to_s}" do |*args|
|
20
|
+
column, time_column = args
|
21
|
+
calculations_by_time_column(o.to_sym, v, :column => column || 'id', :time_column => time_column || 'created_at')
|
22
|
+
end
|
23
|
+
|
24
|
+
define_method "#{o.pluralize}_by" do |*args|
|
25
|
+
range, column, time_column = args
|
26
|
+
calculations_by_time_column(o.to_sym, COLUMNS[range.to_sym], :column => column || "id", :time_column => time_column || "created_at")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def calculations_by_time_column(operation, fields = [], opts = {})
|
34
|
+
query = (::ActiveRecord::Base.connection.adapter_name == "PostgreSQL") ? "EXTRACT(%s FROM %s + INTERVAL '%d hour')" : "EXTRACT(%s FROM %s + INTERVAL %d hour)"
|
35
|
+
options = {:time_column => 'created_at', :column => 'id'}
|
36
|
+
options = options.merge(opts)
|
37
|
+
|
38
|
+
fields = [fields] if !fields.is_a?(Array)
|
39
|
+
select_q, order_by_q, group_by_q = [], [], []
|
40
|
+
|
41
|
+
fields.each_with_index do|range, indx|
|
42
|
+
q = query % [range, options[:time_column], TIME_OFFSET]
|
43
|
+
select_q << ((q + " AS %s_%s") % [range.to_s, options[:time_column]])
|
44
|
+
group_by_q << q
|
45
|
+
order_by_q << 2 + indx
|
46
|
+
end
|
47
|
+
|
48
|
+
sql = "SELECT %s(%s) AS %s_all, %s FROM %s " % [operation, options[:column], operation, select_q.join(','), table_name]
|
49
|
+
|
50
|
+
add_conditions!(sql, options[:conditions])
|
51
|
+
sql << "GROUP BY #{group_by_q.join(',')}
|
52
|
+
ORDER BY #{order_by_q.join(',')}"
|
53
|
+
find_by_sql(sql)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/rails/init.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: calculations_by_time_range
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Nikitochkin
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- VERSION
|
41
41
|
- calculations_by_time_range.gemspec
|
42
42
|
- lib/calculations_by_time_range.rb
|
43
|
+
- lib/calculations_by_time_range/active_record/calculations.rb
|
43
44
|
- rails/init.rb
|
44
45
|
- test/helper.rb
|
45
46
|
- test/test_calculations_by_time_range.rb
|