groupdate 1.0.2 → 1.0.3
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 +12 -4
- data/CHANGELOG.md +5 -0
- data/lib/groupdate/scopes.rb +60 -89
- data/lib/groupdate/series.rb +1 -1
- data/lib/groupdate/version.rb +1 -1
- data/lib/groupdate.rb +1 -1
- data/test/test_helper.rb +8 -0
- metadata +45 -45
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MGY4OTc0MzM2NTNlMjVlOWM1ZjhlNzczN2FjZmNjZjkyZDI4M2Y5Yg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OGE0ZDVhNmNjNDNjYWI4ZmFlNGY4MTYzNTc5M2VjNDRlMWI4MjUwYQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NmI0MDM0MzEyOWFjMjYyNjk4N2VhNTE4Y2M5MzRlMzM5NTYyODc4OTA5M2Zh
|
10
|
+
ZTRkM2RiYjY0ODZkM2IyOGQxMzU4NTA4MTNiOGNjNWRlMjUyZWQ2MDNhYWQw
|
11
|
+
ZDlkOGVkYjZiOGE4MTE5MDBiYzUxZmQxYjQ3NjBiYmNjYWJkZjQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
OWVmMTM2YmU1Y2IyY2ZmOGY5MWEzOTAxYjQ5NGIwNTVkOWM1Y2Q4NDZiOGVi
|
14
|
+
ODQ5MWZkZGM5ZDkzODU2ODlmZDk2MGU2NGMyOTFkZDRlZDU5ZDM4MmJkM2Q1
|
15
|
+
NTIyZjE0MzM4NzkzYzVmYWIzNzk0MWI1YjE2NTVlNzY4NWUxNGI=
|
data/CHANGELOG.md
CHANGED
data/lib/groupdate/scopes.rb
CHANGED
@@ -4,105 +4,76 @@ require "active_record"
|
|
4
4
|
|
5
5
|
module Groupdate
|
6
6
|
module Scopes
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
time_fields = %w(second minute hour day week month year)
|
8
|
+
number_fields = %w(day_of_week hour_of_day)
|
9
|
+
(time_fields + number_fields).each do |field|
|
10
|
+
define_method :"group_by_#{field}" do |*args|
|
11
|
+
args = args.dup
|
12
|
+
options = args[-1].is_a?(Hash) ? args.pop : {}
|
13
|
+
column = connection.quote_table_name(args[0])
|
14
|
+
time_zone = args[1] || Time.zone || "Etc/UTC"
|
15
|
+
if time_zone.is_a?(ActiveSupport::TimeZone) or time_zone = ActiveSupport::TimeZone[time_zone]
|
16
|
+
time_zone = time_zone.tzinfo.name
|
17
|
+
else
|
18
|
+
raise "Unrecognized time zone"
|
17
19
|
end
|
18
|
-
alias_method_chain :inherited, :groupdate
|
19
|
-
end
|
20
|
-
|
21
|
-
# Existing subclasses pick up the model extension as well
|
22
|
-
self.descendants.each do |kls|
|
23
|
-
kls.send(:include, ClassMethods) if kls.superclass == ActiveRecord::Base
|
24
|
-
end
|
25
|
-
end
|
26
20
|
|
27
|
-
|
28
|
-
|
21
|
+
# for week
|
22
|
+
week_start = [:mon, :tue, :wed, :thu, :fri, :sat, :sun].index((options[:start] || :sun).to_sym)
|
23
|
+
if field == "week" and !week_start
|
24
|
+
raise "Unrecognized :start option"
|
25
|
+
end
|
29
26
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
time_zone = args[1] || Time.zone || "Etc/UTC"
|
42
|
-
if time_zone.is_a?(ActiveSupport::TimeZone) or time_zone = ActiveSupport::TimeZone[time_zone]
|
43
|
-
time_zone = time_zone.tzinfo.name
|
27
|
+
query =
|
28
|
+
case connection.adapter_name
|
29
|
+
when "MySQL", "Mysql2"
|
30
|
+
case field
|
31
|
+
when "day_of_week" # Sunday = 0, Monday = 1, etc
|
32
|
+
# use CONCAT for consistent return type (String)
|
33
|
+
["DAYOFWEEK(CONVERT_TZ(#{column}, '+00:00', ?)) - 1", time_zone]
|
34
|
+
when "hour_of_day"
|
35
|
+
["EXTRACT(HOUR from CONVERT_TZ(#{column}, '+00:00', ?))", time_zone]
|
36
|
+
when "week"
|
37
|
+
["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]
|
44
38
|
else
|
45
|
-
|
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
|
-
|
54
|
-
query =
|
55
|
-
case connection.adapter_name
|
56
|
-
when "MySQL", "Mysql2"
|
39
|
+
format =
|
57
40
|
case field
|
58
|
-
when "
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
when "minute"
|
71
|
-
"%Y-%m-%d %H:%i:00"
|
72
|
-
when "hour"
|
73
|
-
"%Y-%m-%d %H:00:00"
|
74
|
-
when "day"
|
75
|
-
"%Y-%m-%d 00:00:00"
|
76
|
-
when "month"
|
77
|
-
"%Y-%m-01 00:00:00"
|
78
|
-
else # year
|
79
|
-
"%Y-01-01 00:00:00"
|
80
|
-
end
|
81
|
-
|
82
|
-
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(#{column}, '+00:00', ?), '#{format}'), ?, '+00:00')", time_zone, time_zone]
|
41
|
+
when "second"
|
42
|
+
"%Y-%m-%d %H:%i:%S"
|
43
|
+
when "minute"
|
44
|
+
"%Y-%m-%d %H:%i:00"
|
45
|
+
when "hour"
|
46
|
+
"%Y-%m-%d %H:00:00"
|
47
|
+
when "day"
|
48
|
+
"%Y-%m-%d 00:00:00"
|
49
|
+
when "month"
|
50
|
+
"%Y-%m-01 00:00:00"
|
51
|
+
else # year
|
52
|
+
"%Y-01-01 00:00:00"
|
83
53
|
end
|
84
|
-
when "PostgreSQL"
|
85
|
-
case field
|
86
|
-
when "day_of_week"
|
87
|
-
["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ?)::integer", time_zone]
|
88
|
-
when "hour_of_day"
|
89
|
-
["EXTRACT(HOUR from #{column}::timestamptz AT TIME ZONE ?)::integer", time_zone]
|
90
|
-
when "week" # start on Sunday, not PostgreSQL default Monday
|
91
|
-
["(DATE_TRUNC('#{field}', (#{column}::timestamptz - INTERVAL '#{week_start} day') AT TIME ZONE ?) + INTERVAL '#{week_start} day') AT TIME ZONE ?", time_zone, time_zone]
|
92
|
-
else
|
93
|
-
["DATE_TRUNC('#{field}', #{column}::timestamptz AT TIME ZONE ?) AT TIME ZONE ?", time_zone, time_zone]
|
94
|
-
end
|
95
|
-
else
|
96
|
-
raise "Connection adapter not supported: #{connection.adapter_name}"
|
97
|
-
end
|
98
54
|
|
99
|
-
|
100
|
-
|
101
|
-
|
55
|
+
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(#{column}, '+00:00', ?), '#{format}'), ?, '+00:00')", time_zone, time_zone]
|
56
|
+
end
|
57
|
+
when "PostgreSQL", "PostGIS"
|
58
|
+
case field
|
59
|
+
when "day_of_week"
|
60
|
+
["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ?)::integer", time_zone]
|
61
|
+
when "hour_of_day"
|
62
|
+
["EXTRACT(HOUR from #{column}::timestamptz AT TIME ZONE ?)::integer", time_zone]
|
63
|
+
when "week" # start on Sunday, not PostgreSQL default Monday
|
64
|
+
["(DATE_TRUNC('#{field}', (#{column}::timestamptz - INTERVAL '#{week_start} day') AT TIME ZONE ?) + INTERVAL '#{week_start} day') AT TIME ZONE ?", time_zone, time_zone]
|
102
65
|
else
|
103
|
-
|
66
|
+
["DATE_TRUNC('#{field}', #{column}::timestamptz AT TIME ZONE ?) AT TIME ZONE ?", time_zone, time_zone]
|
104
67
|
end
|
68
|
+
else
|
69
|
+
raise "Connection adapter not supported: #{connection.adapter_name}"
|
105
70
|
end
|
71
|
+
|
72
|
+
group = group(Groupdate::OrderHack.new(sanitize_sql_array(query), field, time_zone))
|
73
|
+
if args[2]
|
74
|
+
Series.new(group, field, column, time_zone, args[2], week_start)
|
75
|
+
else
|
76
|
+
group
|
106
77
|
end
|
107
78
|
end
|
108
79
|
end
|
data/lib/groupdate/series.rb
CHANGED
data/lib/groupdate/version.rb
CHANGED
data/lib/groupdate.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -299,6 +299,14 @@ module TestGroupdate
|
|
299
299
|
assert_equal(expected, User.where("id = 0").group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")..Time.parse("2013-05-01 23:59:59 UTC")).count)
|
300
300
|
end
|
301
301
|
|
302
|
+
def test_zeros_datetime
|
303
|
+
create_user "2013-05-01 00:00:00 UTC"
|
304
|
+
expected = {
|
305
|
+
Time.parse("2013-05-01 00:00:00 UTC") => 1
|
306
|
+
}
|
307
|
+
assert_equal(expected, User.group_by_day(:created_at, Time.zone, DateTime.parse("2013-05-01 00:00:00 UTC")..DateTime.parse("2013-05-01 00:00:00 UTC")).count)
|
308
|
+
end
|
309
|
+
|
302
310
|
# misc
|
303
311
|
|
304
312
|
def test_order_day
|
metadata
CHANGED
@@ -1,99 +1,99 @@
|
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06
|
11
|
+
date: 2013-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
|
-
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 3.0.0
|
20
|
-
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
23
21
|
requirements:
|
24
|
-
- -
|
22
|
+
- - ">="
|
25
23
|
- !ruby/object:Gem::Version
|
26
24
|
version: 3.0.0
|
25
|
+
prerelease: false
|
26
|
+
type: :runtime
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
|
-
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.3'
|
34
|
-
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
37
35
|
requirements:
|
38
|
-
- - ~>
|
36
|
+
- - "~>"
|
39
37
|
- !ruby/object:Gem::Version
|
40
38
|
version: '1.3'
|
39
|
+
prerelease: false
|
40
|
+
type: :development
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
44
49
|
requirements:
|
45
|
-
- -
|
50
|
+
- - ">="
|
46
51
|
- !ruby/object:Gem::Version
|
47
52
|
version: '0'
|
48
|
-
type: :development
|
49
53
|
prerelease: false
|
54
|
+
type: :development
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
50
57
|
version_requirements: !ruby/object:Gem::Requirement
|
51
58
|
requirements:
|
52
|
-
- -
|
59
|
+
- - ">="
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: minitest
|
57
62
|
requirement: !ruby/object:Gem::Requirement
|
58
63
|
requirements:
|
59
|
-
- -
|
64
|
+
- - ">="
|
60
65
|
- !ruby/object:Gem::Version
|
61
66
|
version: '0'
|
62
|
-
type: :development
|
63
67
|
prerelease: false
|
68
|
+
type: :development
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activerecord-jdbcpostgresql-adapter
|
64
71
|
version_requirements: !ruby/object:Gem::Requirement
|
65
72
|
requirements:
|
66
|
-
- -
|
73
|
+
- - ">="
|
67
74
|
- !ruby/object:Gem::Version
|
68
75
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: pg
|
71
76
|
requirement: !ruby/object:Gem::Requirement
|
72
77
|
requirements:
|
73
|
-
- -
|
78
|
+
- - ">="
|
74
79
|
- !ruby/object:Gem::Version
|
75
80
|
version: '0'
|
76
|
-
type: :development
|
77
81
|
prerelease: false
|
82
|
+
type: :development
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activerecord-jdbcmysql-adapter
|
78
85
|
version_requirements: !ruby/object:Gem::Requirement
|
79
86
|
requirements:
|
80
|
-
- -
|
87
|
+
- - ">="
|
81
88
|
- !ruby/object:Gem::Version
|
82
89
|
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: mysql2
|
85
90
|
requirement: !ruby/object:Gem::Requirement
|
86
91
|
requirements:
|
87
|
-
- -
|
92
|
+
- - ">="
|
88
93
|
- !ruby/object:Gem::Version
|
89
94
|
version: '0'
|
90
|
-
type: :development
|
91
95
|
prerelease: false
|
92
|
-
|
93
|
-
requirements:
|
94
|
-
- - '>='
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
96
|
+
type: :development
|
97
97
|
description: The simplest way to group temporal data
|
98
98
|
email:
|
99
99
|
- acekane1@gmail.com
|
@@ -101,8 +101,8 @@ executables: []
|
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
|
-
- .gitignore
|
105
|
-
- .travis.yml
|
104
|
+
- ".gitignore"
|
105
|
+
- ".travis.yml"
|
106
106
|
- CHANGELOG.md
|
107
107
|
- Gemfile
|
108
108
|
- LICENSE.txt
|
@@ -121,24 +121,24 @@ homepage: ''
|
|
121
121
|
licenses:
|
122
122
|
- MIT
|
123
123
|
metadata: {}
|
124
|
-
post_install_message:
|
124
|
+
post_install_message:
|
125
125
|
rdoc_options: []
|
126
126
|
require_paths:
|
127
127
|
- lib
|
128
128
|
required_ruby_version: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- -
|
130
|
+
- - ">="
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: '0'
|
133
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
|
-
- -
|
135
|
+
- - ">="
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
|
-
rubyforge_project:
|
140
|
-
rubygems_version: 2.0.
|
141
|
-
signing_key:
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 2.0.3
|
141
|
+
signing_key:
|
142
142
|
specification_version: 4
|
143
143
|
summary: The simplest way to group temporal data
|
144
144
|
test_files:
|