Commit 3cd62d0b681d545450db695e770c0d955762c321
1 parent
21208ef8
Exists in
cumulative_sum
Added cumulative_sum for PostgreSQL
Showing
3 changed files
with
33 additions
and
8 deletions
Show diff stats
lib/groupdate/magic.rb
... | ... | @@ -25,8 +25,7 @@ module Groupdate |
25 | 25 | |
26 | 26 | adapter_name = relation.connection.adapter_name |
27 | 27 | query = |
28 | - case adapter_name | |
29 | - when "MySQL", "Mysql2" | |
28 | + if mysql?(adapter_name) | |
30 | 29 | case field |
31 | 30 | when :day_of_week # Sunday = 0, Monday = 1, etc |
32 | 31 | # use CONCAT for consistent return type (String) |
... | ... | @@ -54,7 +53,7 @@ module Groupdate |
54 | 53 | |
55 | 54 | ["DATE_ADD(CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} HOUR), '+00:00', ?), '#{format}'), ?, '+00:00'), INTERVAL #{day_start} HOUR)", time_zone, time_zone] |
56 | 55 | end |
57 | - when "PostgreSQL", "PostGIS" | |
56 | + elsif postgresql?(adapter_name) | |
58 | 57 | case field |
59 | 58 | when :day_of_week |
60 | 59 | ["EXTRACT(DOW from (#{column}::timestamptz AT TIME ZONE ? - INTERVAL '#{day_start} hour'))::integer", time_zone] |
... | ... | @@ -230,15 +229,21 @@ module Groupdate |
230 | 229 | lambda{|k| k } |
231 | 230 | end |
232 | 231 | |
233 | - value = nil | |
234 | - | |
232 | + value = 0 | |
235 | 233 | Hash[series.map do |k| |
236 | - value = count[k] || (@options[:carry_forward] ? value : false) || default_value | |
237 | - | |
234 | + value = count[k] || (@options[:carry_forward] && value) || default_value | |
238 | 235 | [multiple_groups ? k[0...@group_index] + [key_format.call(k[@group_index])] + k[(@group_index + 1)..-1] : key_format.call(k), value] |
239 | 236 | end] |
240 | 237 | end |
241 | 238 | |
239 | + def mysql?(adapter_name) | |
240 | + ["MySQL", "Mysql2"].include?(adapter_name) | |
241 | + end | |
242 | + | |
243 | + def postgresql?(adapter_name) | |
244 | + ["PostgreSQL", "PostGIS"].include?(adapter_name) | |
245 | + end | |
246 | + | |
242 | 247 | def round_time(time) |
243 | 248 | time = time.to_time.in_time_zone(time_zone) - day_start.hours |
244 | 249 | ... | ... |
lib/groupdate/series.rb
... | ... | @@ -8,7 +8,15 @@ module Groupdate |
8 | 8 | end |
9 | 9 | |
10 | 10 | def cumulative_sum |
11 | - custom("SUM(COUNT(id)) OVER (ORDER BY #{relation.group_values[0]})::integer") | |
11 | + magic.options[:carry_forward] = true | |
12 | + sql = | |
13 | + if magic.send(:postgresql?, connection.adapter_name) | |
14 | + "SUM(COUNT(id)) OVER (ORDER BY #{relation.group_values[0]})::integer" | |
15 | + else | |
16 | + raise "`cumulative_sum` not supported with MySQL" | |
17 | + end | |
18 | + | |
19 | + custom(sql) | |
12 | 20 | end |
13 | 21 | |
14 | 22 | # clone to prevent modifying original variables | ... | ... |
test/test_helper.rb
... | ... | @@ -636,6 +636,18 @@ module TestGroupdate |
636 | 636 | assert_equal expected, User.group_by_year(:created_at).cumulative_sum |
637 | 637 | end |
638 | 638 | |
639 | + def test_cumulative_sum_last | |
640 | + create_user "2011-05-01 00:00:00 UTC" | |
641 | + create_user "2013-05-01 00:00:00 UTC" | |
642 | + create_user "2013-05-01 00:00:00 UTC" | |
643 | + expected = { | |
644 | + utc.parse("2012-01-01 00:00:00 UTC") => 1, | |
645 | + utc.parse("2013-01-01 00:00:00 UTC") => 3, | |
646 | + utc.parse("2014-01-01 00:00:00 UTC") => 3 | |
647 | + } | |
648 | + assert_equal expected, User.group_by_year(:created_at, last: 3).cumulative_sum | |
649 | + end | |
650 | + | |
639 | 651 | # helpers |
640 | 652 | |
641 | 653 | def assert_format(method, expected, format, options = {}) | ... | ... |