groupdate 1.0.1 → 1.0.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 +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +8 -1
- data/lib/groupdate/scopes.rb +12 -3
- data/lib/groupdate/series.rb +6 -4
- data/lib/groupdate/version.rb +1 -1
- data/test/test_helper.rb +58 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e473d607f5f1bf038d605fb7bb99c07876d4e20
|
4
|
+
data.tar.gz: 33f2c1067c4ac21b2dcb4e9c07402426e7d0abc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 957ef7d7bb9ef5ef0857094c9330e5b294a7d4b001a2d83e04e536d0c6cc119fbab6f2c913b005029baba8f117444c181449e464a64258142d85c48734e03cf9
|
7
|
+
data.tar.gz: d8e4ac13ab0194543382942698373577fd40b8299f4b81acd220636d0bd505ba3ac92abe0581e28fb9b9a991235f3da7a1b542adb5fa86159717bdaf6ca14093
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -61,7 +61,14 @@ time_zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"]
|
|
61
61
|
User.group_by_week(:created_at, time_zone).count
|
62
62
|
```
|
63
63
|
|
64
|
-
**Note:** Weeks start on Sunday.
|
64
|
+
**Note:** Weeks start on Sunday by default. For other days, use:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
User.group_by_week(:created_at, :start => :mon) # first three letters of day
|
68
|
+
|
69
|
+
# must be the last argument
|
70
|
+
User.group_by_week(:created_at, time_zone, :start => :sat)
|
71
|
+
```
|
65
72
|
|
66
73
|
You can also group by the day of the week or hour of the day.
|
67
74
|
|
data/lib/groupdate/scopes.rb
CHANGED
@@ -35,6 +35,8 @@ module Groupdate
|
|
35
35
|
(time_fields + number_fields).each do |field|
|
36
36
|
# no define_singleton_method in ruby 1.8
|
37
37
|
(class << self; self end).send :define_method, :"group_by_#{field}" do |*args|
|
38
|
+
args = args.dup
|
39
|
+
options = args[-1].is_a?(Hash) ? args.pop : {}
|
38
40
|
column = connection.quote_table_name(args[0])
|
39
41
|
time_zone = args[1] || Time.zone || "Etc/UTC"
|
40
42
|
if time_zone.is_a?(ActiveSupport::TimeZone) or time_zone = ActiveSupport::TimeZone[time_zone]
|
@@ -42,6 +44,13 @@ module Groupdate
|
|
42
44
|
else
|
43
45
|
raise "Unrecognized time zone"
|
44
46
|
end
|
47
|
+
|
48
|
+
# for week
|
49
|
+
week_start = [:mon, :tue, :wed, :thu, :fri, :sat, :sun].index((options[:start] || :sun).to_sym)
|
50
|
+
if field == "week" and !week_start
|
51
|
+
raise "Unrecognized :start option"
|
52
|
+
end
|
53
|
+
|
45
54
|
query =
|
46
55
|
case connection.adapter_name
|
47
56
|
when "MySQL", "Mysql2"
|
@@ -52,7 +61,7 @@ module Groupdate
|
|
52
61
|
when "hour_of_day"
|
53
62
|
["EXTRACT(HOUR from CONVERT_TZ(#{column}, '+00:00', ?))", time_zone]
|
54
63
|
when "week"
|
55
|
-
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL (
|
64
|
+
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL ((#{7 - week_start} + WEEKDAY(CONVERT_TZ(#{column}, '+00:00', ?))) % 7) DAY), '+00:00', ?), '%Y-%m-%d 00:00:00'), ?, '+00:00')", time_zone, time_zone, time_zone]
|
56
65
|
else
|
57
66
|
format =
|
58
67
|
case field
|
@@ -79,7 +88,7 @@ module Groupdate
|
|
79
88
|
when "hour_of_day"
|
80
89
|
["EXTRACT(HOUR from #{column}::timestamptz AT TIME ZONE ?)::integer", time_zone]
|
81
90
|
when "week" # start on Sunday, not PostgreSQL default Monday
|
82
|
-
["(DATE_TRUNC('#{field}', (#{column}::timestamptz
|
91
|
+
["(DATE_TRUNC('#{field}', (#{column}::timestamptz - INTERVAL '#{week_start} day') AT TIME ZONE ?) + INTERVAL '#{week_start} day') AT TIME ZONE ?", time_zone, time_zone]
|
83
92
|
else
|
84
93
|
["DATE_TRUNC('#{field}', #{column}::timestamptz AT TIME ZONE ?) AT TIME ZONE ?", time_zone, time_zone]
|
85
94
|
end
|
@@ -89,7 +98,7 @@ module Groupdate
|
|
89
98
|
|
90
99
|
group = group(Groupdate::OrderHack.new(sanitize_sql_array(query), field, time_zone))
|
91
100
|
if args[2]
|
92
|
-
Series.new(group, field, column, time_zone, args[2])
|
101
|
+
Series.new(group, field, column, time_zone, args[2], week_start)
|
93
102
|
else
|
94
103
|
group
|
95
104
|
end
|
data/lib/groupdate/series.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Groupdate
|
2
2
|
class Series
|
3
3
|
|
4
|
-
def initialize(relation, field, column, time_zone, time_range)
|
4
|
+
def initialize(relation, field, column, time_zone, time_range, week_start)
|
5
5
|
@relation = relation
|
6
6
|
if time_range.is_a?(Range)
|
7
7
|
@relation = relation.where("#{column} BETWEEN ? AND ?", time_range.first, time_range.last)
|
@@ -9,6 +9,7 @@ module Groupdate
|
|
9
9
|
@field = field
|
10
10
|
@time_zone = time_zone
|
11
11
|
@time_range = time_range
|
12
|
+
@week_start = week_start
|
12
13
|
end
|
13
14
|
|
14
15
|
def build_series(count)
|
@@ -19,7 +20,7 @@ module Groupdate
|
|
19
20
|
when "day_of_week", "hour_of_day"
|
20
21
|
lambda{|k| k.to_i }
|
21
22
|
else
|
22
|
-
lambda{|k| (k.is_a?(
|
23
|
+
lambda{|k| (k.is_a?(String) ? utc.parse(k) : k.to_time).utc }
|
23
24
|
end
|
24
25
|
|
25
26
|
count = Hash[count.map do |k, v|
|
@@ -55,8 +56,9 @@ module Groupdate
|
|
55
56
|
when "day"
|
56
57
|
time.beginning_of_day
|
57
58
|
when "week"
|
58
|
-
#
|
59
|
-
(time -
|
59
|
+
# same logic as MySQL group
|
60
|
+
weekday = (time.wday - 1) % 7
|
61
|
+
(time - ((7 - @week_start + weekday) % 7).days).midnight
|
60
62
|
when "month"
|
61
63
|
time.beginning_of_month
|
62
64
|
else # year
|
data/lib/groupdate/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -95,6 +95,42 @@ module TestGroupdate
|
|
95
95
|
assert_result_time :week, "2013-03-17 00:00:00 PDT", "2013-03-17 07:00:00", true
|
96
96
|
end
|
97
97
|
|
98
|
+
# week starting on monday
|
99
|
+
|
100
|
+
def test_week_end_of_week_mon
|
101
|
+
assert_result_time :week, "2013-03-18 00:00:00 UTC", "2013-03-24 23:59:59", false, :start => :mon
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_week_start_of_week_mon
|
105
|
+
assert_result_time :week, "2013-03-25 00:00:00 UTC", "2013-03-25 00:00:00", false, :start => :mon
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_week_end_of_week_with_time_zone_mon
|
109
|
+
assert_result_time :week, "2013-03-11 00:00:00 PDT", "2013-03-18 06:59:59", true, :start => :mon
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_week_start_of_week_with_time_zone_mon
|
113
|
+
assert_result_time :week, "2013-03-18 00:00:00 PDT", "2013-03-18 07:00:00", true, :start => :mon
|
114
|
+
end
|
115
|
+
|
116
|
+
# week starting on saturday
|
117
|
+
|
118
|
+
def test_week_end_of_week_sat
|
119
|
+
assert_result_time :week, "2013-03-16 00:00:00 UTC", "2013-03-22 23:59:59", false, :start => :sat
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_week_start_of_week_sat
|
123
|
+
assert_result_time :week, "2013-03-23 00:00:00 UTC", "2013-03-23 00:00:00", false, :start => :sat
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_week_end_of_week_with_time_zone_sat
|
127
|
+
assert_result_time :week, "2013-03-09 00:00:00 PST", "2013-03-16 06:59:59", true, :start => :sat
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_week_start_of_week_with_time_zone_sat
|
131
|
+
assert_result_time :week, "2013-03-16 00:00:00 PDT", "2013-03-16 07:00:00", true, :start => :sat
|
132
|
+
end
|
133
|
+
|
98
134
|
# month
|
99
135
|
|
100
136
|
def test_month_end_of_month
|
@@ -197,6 +233,22 @@ module TestGroupdate
|
|
197
233
|
assert_zeros :week, "2013-05-01 20:00:00 PDT", ["2013-04-21 00:00:00 PDT", "2013-04-28 00:00:00 PDT", "2013-05-05 00:00:00 PDT"], "2013-04-27 23:59:59 PDT", "2013-05-11 23:59:59 PDT", true
|
198
234
|
end
|
199
235
|
|
236
|
+
def test_zeros_week_mon
|
237
|
+
assert_zeros :week, "2013-05-01 20:00:00 UTC", ["2013-04-22 00:00:00 UTC", "2013-04-29 00:00:00 UTC", "2013-05-06 00:00:00 UTC"], "2013-04-27 23:59:59 UTC", "2013-05-11 23:59:59 UTC", false, :start => :mon
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_zeros_week_time_zone_mon
|
241
|
+
assert_zeros :week, "2013-05-01 20:00:00 PDT", ["2013-04-22 00:00:00 PDT", "2013-04-29 00:00:00 PDT", "2013-05-06 00:00:00 PDT"], "2013-04-27 23:59:59 PDT", "2013-05-11 23:59:59 PDT", true, :start => :mon
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_zeros_week_sat
|
245
|
+
assert_zeros :week, "2013-05-01 20:00:00 UTC", ["2013-04-20 00:00:00 UTC", "2013-04-27 00:00:00 UTC", "2013-05-04 00:00:00 UTC"], "2013-04-26 23:59:59 UTC", "2013-05-10 23:59:59 UTC", false, :start => :sat
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_zeros_week_time_zone_sat
|
249
|
+
assert_zeros :week, "2013-05-01 20:00:00 PDT", ["2013-04-20 00:00:00 PDT", "2013-04-27 00:00:00 PDT", "2013-05-04 00:00:00 PDT"], "2013-04-26 23:59:59 PDT", "2013-05-10 23:59:59 PDT", true, :start => :sat
|
250
|
+
end
|
251
|
+
|
200
252
|
def test_zeros_month
|
201
253
|
assert_zeros :month, "2013-04-16 20:00:00 UTC", ["2013-03-01 00:00:00 UTC", "2013-04-01 00:00:00 UTC", "2013-05-01 00:00:00 UTC"], "2013-03-01 00:00:00 UTC", "2013-05-31 23:59:59 UTC"
|
202
254
|
end
|
@@ -272,23 +324,23 @@ module TestGroupdate
|
|
272
324
|
|
273
325
|
# helpers
|
274
326
|
|
275
|
-
def assert_result_time(method, expected, time_str, time_zone = false)
|
276
|
-
assert_result method, Time.parse(expected), time_str, time_zone
|
327
|
+
def assert_result_time(method, expected, time_str, time_zone = false, options = {})
|
328
|
+
assert_result method, Time.parse(expected), time_str, time_zone, options
|
277
329
|
end
|
278
330
|
|
279
|
-
def assert_result(method, expected, time_str, time_zone = false)
|
331
|
+
def assert_result(method, expected, time_str, time_zone = false, options = {})
|
280
332
|
create_user time_str
|
281
333
|
expected = expected.is_a?(Time) ? time_key(expected) : number_key(expected)
|
282
|
-
assert_equal(ordered_hash({expected => 1}), User.send(:"group_by_#{method}", :created_at, time_zone ? "Pacific Time (US & Canada)" : nil).order(method.to_s).count)
|
334
|
+
assert_equal(ordered_hash({expected => 1}), User.send(:"group_by_#{method}", :created_at, time_zone ? "Pacific Time (US & Canada)" : nil, options).order(method.to_s).count)
|
283
335
|
end
|
284
336
|
|
285
|
-
def assert_zeros(method, created_at, keys, range_start, range_end, time_zone = nil)
|
337
|
+
def assert_zeros(method, created_at, keys, range_start, range_end, time_zone = nil, options = {})
|
286
338
|
create_user created_at
|
287
339
|
expected = {}
|
288
340
|
keys.each_with_index do |key, i|
|
289
341
|
expected[Time.parse(key)] = i == 1 ? 1 : 0
|
290
342
|
end
|
291
|
-
assert_equal(expected, User.send(:"group_by_#{method}", :created_at, time_zone ? "Pacific Time (US & Canada)" : nil, Time.parse(range_start)..Time.parse(range_end)).count)
|
343
|
+
assert_equal(expected, User.send(:"group_by_#{method}", :created_at, time_zone ? "Pacific Time (US & Canada)" : nil, Time.parse(range_start)..Time.parse(range_end), options).count)
|
292
344
|
end
|
293
345
|
|
294
346
|
def ordered_hash(hash)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groupdate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|