event-counter 0.0.1 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c824074d24fd8d6d102c55c7cd81c4026e3cdd0
4
- data.tar.gz: 906bf98133f1f082d6a3f1c1d4831c64f7974ea3
3
+ metadata.gz: 9ed77b0f7b2996138e3c7125f506022dbfb1b4f6
4
+ data.tar.gz: 703501bc075661a7ef2584740ec9163450a591ed
5
5
  SHA512:
6
- metadata.gz: 8db9c66d38029ccf99b8fa828f5936a1dc8ea84412822d7fc1037b4a2d4979988f429e4b2a96379d23e821b4ad08e792409f617b7ac1eb28f71f429341a608fc
7
- data.tar.gz: a4085a8f4901cd3854b50ff56791c17bcd345d4269845e4ab5523a3bc35c65ced9bd88e6702ac2c0e2c77f8882edc73afdc5a244fa5f8a2bb927866b0f4c1678
6
+ metadata.gz: d71bb461d356f61d8c0afd1718886e0e2be6b507ea1e0994e95b25c2370495921a14167d75a4e702730a8dac9ce5a5daeb2fc759c553e0f9a6265a68fdf2b4a0
7
+ data.tar.gz: aa7d2d7006bee6837fc7fd8440fa11f5e38148e7e478024f1a25f10285cbe3808c5558d0c5e1ab0c7ad8731371545021460293155339851b2e51cb976b759559
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /doc/
8
8
  /log
9
9
  /pkg/
10
+ /spec/fixtures/*.sql
10
11
  /spec/reports/
11
12
  /tmp/
12
13
  *.bundle
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+
7
+ gemfile:
8
+ - gemfiles/pg_ar_30.gemfile
9
+ - gemfiles/pg_ar_31.gemfile
10
+ - gemfiles/pg_ar_32.gemfile
11
+ - gemfiles/pg_ar_40.gemfile
12
+
13
+ script: RUN_ALL=true rspec spec
14
+
15
+ services:
16
+ - postgresql
17
+
18
+ before_script:
19
+ - psql -c 'create database event_counter_test;' -U postgres
data/Appraisals ADDED
@@ -0,0 +1,11 @@
1
+ %w(3.0 3.1 3.2 4.0 4.1).each do |ar_version|
2
+ %w(pg).each do |db_type|
3
+ appraise "#{db_type}-ar-#{ar_version.split('.').first(2).join}" do
4
+ gem 'activerecord', "~> #{ar_version}"
5
+ gem 'activesupport', "~> #{ar_version}"
6
+ gem 'database_cleaner'
7
+ gem 'pg'
8
+ gem 'rspec'
9
+ end
10
+ end
11
+ end
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # EventCounter Changelog
2
+
3
+ 0.1.0 (2014-10-12)
4
+
5
+ * Added time zones support
6
+ * Improved specs
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ gem 'appraisal'
6
+ gem 'rspec'
7
+ gem 'database_cleaner'
data/README.md CHANGED
@@ -1,10 +1,8 @@
1
- EventCounter
2
- ===============
1
+ # EventCounter
3
2
 
4
3
  EventCounter is a database based event counter with throttling per time intervals.
5
4
 
6
- Usage
7
- -----
5
+ ## Usage
8
6
 
9
7
  Let's define counters in model
10
8
 
@@ -23,66 +21,105 @@ Let's count...
23
21
  article = Article.create!
24
22
 
25
23
  article.up!(:views)
26
- # creates counter (if it doesn't exist) with value 1 and on Time.now() rounded to 5 minutes, e.x.:
27
- #=> #<EventCounter id: 1, name: "views", value: 1, countable_id: 1, countable_type: "Article", created_at: "2014-10-16 23:20:00">
24
+ # => #<EventCounter id: 1, name: "views", value: 1, countable_id: 1,
25
+ # countable_type: "Article", created_at: "2014-10-16 23:20:00">
26
+ # creates counter (if it doesn't exist) with value 1 and on Time.now() rounded
27
+ # to 5 minutes, e.x.:
28
28
 
29
29
  # at once
30
30
  article.up!(:views, 3)
31
- #=> #<EventCounter id: 1, name: "views", value: 4, countable_id: 1, countable_type: "Article", created_at: "2014-10-16 23:20:00">
32
- # it will update counter (if the other exists in that interval) with value 3 and on Time.now() rounded to 5 minutes
31
+ # => #<EventCounter id: 1, name: "views", value: 4, countable_id: 1,
32
+ # countable_type: "Article", created_at: "2014-10-16 23:20:00">
33
+ # Updates counter (if the other exists in that interval) with value 3 and
34
+ # on Time.now() rounded to 5 minutes
33
35
 
34
36
  # later
35
37
  article.up!(:views, 5)
36
- #=> #<EventCounter id: 2, name: "views", value: 5, countable_id: 1, countable_type: "Article", created_at: "2014-10-16 23:25:00">
38
+ # => #<EventCounter id: 2, name: "views", value: 5, countable_id: 1,
39
+ # countable_type: "Article", created_at: "2014-10-16 23:25:00">
37
40
  article.down!(:views, 2)
38
- #=> #<EventCounter id: 2, name: "views", value: 3, countable_id: 1, countable_type: "Article", created_at: "2014-10-16 23:25:00">
41
+ # => #<EventCounter id: 2, name: "views", value: 3, countable_id: 1,
42
+ # countable_type: "Article", created_at: "2014-10-16 23:25:00">
39
43
 
40
44
  # anytime or in a background job
41
- article.up!(:views, 7, on_time: 10.minutes.ago)
42
- #=> #<EventCounter id: 3, name: "views", value: 7, countable_id: 1, countable_type: "Article", created_at: "2014-10-16 23:15:00">
45
+ article.up!(:views, 7, on_time: 10.minutes.ago.in_time_zone)
46
+ # => #<EventCounter id: 3, name: "views", value: 7, countable_id: 1,
47
+ # countable_type: "Article", created_at: "2014-10-16 23:15:00">
43
48
 
44
49
  # we have not got? let's fix it
45
- article.up!(:views, 9, on_time: 10.minutes.ago, force: true)
46
- #=> #<EventCounter id: 3, name: "views", value: 9, countable_id: 1, countable_type: "Article", created_at: "2014-10-16 23:15:00">
50
+ article.up!(:views, 9, on_time: 10.minutes.ago.in_time_zone, force: true)
51
+ # => #<EventCounter id: 3, name: "views", value: 9, countable_id: 1,
52
+ # countable_type: "Article", created_at: "2014-10-16 23:15:00">
47
53
  ```
48
54
 
49
55
  Let's get some statistics for our charts...
50
56
 
51
57
  ```ruby
52
58
  article.data_for(:views)
53
- #=> [[2014-10-16 23:15:00 +0400, 9], [2014-10-16 23:20:00 +0400, 4], [2014-10-16 23:25:00 +0400, 3]]
59
+ # => [
60
+ # [Thu, 16 Oct 2014 23:15:00 MSK +04:00, 9],
61
+ # [Thu, 16 Oct 2014 23:20:00 MSK +04:00, 4],
62
+ # [Thu, 16 Oct 2014 23:25:00 MSK +04:00, 3]
63
+ # ]
54
64
 
55
65
  article.data_for(:views, interval: 10.minutes)
56
- #=> [[2014-10-16 23:10:00 +0400, 9], [2014-10-16 23:20:00 +0400, 7]]
57
-
58
- range = Time.mktime(2014, 10, 16, 23, 0)..Time.mktime(2014, 10, 16, 23, 10)
66
+ # => [
67
+ # [Thu, 16 Oct 2014 23:10:00 MSK +04:00, 9],
68
+ # [Thu, 16 Oct 2014 23:20:00 MSK +04:00, 7]
69
+ # ]
70
+
71
+ # with range
72
+ range_start = Time.mktime(2014, 10, 16, 23, 0).in_time_zone
73
+ range_end = Time.mktime(2014, 10, 16, 23, 10).in_time_zone
74
+ range = range_start..range_end
59
75
  article.data_for(:views, interval: 10.minutes, range: range)
60
- #=> [[2014-10-16 23:00:00 +0400, 0], [2014-10-16 23:10:00 +0400, 9]]
76
+ #=> [
77
+ # [Thu, 16 Oct 2014 23:00:00 MSK +04:00, 0]
78
+ # [Thu, 16 Oct 2014 23:10:00 MSK +04:00, 9]
79
+ # ]
80
+
81
+ # for different time zone (although we have no data for that time)
82
+ range_start = Time.mktime(2014, 10, 16, 23, 0).in_time_zone('UTC')
83
+ range_end = Time.mktime(2014, 10, 16, 23, 10).in_time_zone('UTC')
84
+ range = range_start..range_end
85
+ article.data_for(:views, interval: 10.minutes, range: range, tz: 'UTC')
86
+ #=> [
87
+ # [Thu, 16 Oct 2014 23:00:00 UTC +00:00, 0]
88
+ # [Thu, 16 Oct 2014 23:10:00 UTC +00:00, 0]
89
+ # ]
61
90
 
62
91
  article.data_for(:views, interval: :day)
63
- #=> [[2014-10-16 00:00:00 +0400, 16]]
92
+ # => [Thu, 16 Oct 2014 00:00:00 MSK +04:00, 16]
64
93
 
65
94
  article.data_for(:views, interval: :day, raw: true)
66
- #=> [{"created_at" => "2014-10-16 00:00:00+04", "value" => "16"}]
67
- # raw result will make difference in performance on a big data
95
+ #=> [{"created_at" => "2014-10-16 00:00:00", "value" => "16"}]
96
+ # The raw result will make difference in performance on a big data.
97
+ # The returned time is in the requested time zone. By default, a normalization
98
+ # looks as `Time.zone.parse(i['created_at']), i['value'].to_i ]`
68
99
 
69
100
  # class wide
70
- range = Time.mktime(2014, 10, 15)..Time.mktime(2014, 10, 16)
101
+ range_start = Time.mktime(2014, 10, 15).in_time_zone
102
+ range_end = Time.mktime(2014, 10, 16).in_time_zone
103
+ range = range_start..range_end
71
104
  Article.data_for(:views, interval: :day, range: range)
72
- #=> [[2014-10-15 00:00:00 +0400, 0], [2014-10-16 00:00:00 +0400, 16]]
105
+ # => [
106
+ # [Thu, 15 Oct 2014 00:00:00 MSK +04:00, 0]
107
+ # [Thu, 16 Oct 2014 00:00:00 MSK +04:00, 16]
108
+ # ]
73
109
  ```
74
110
 
75
- Limitations
76
- -----------
111
+ ## Limitations
77
112
 
78
113
  - It works *ONLY* with *PostgreSQL* at the moment.
79
114
  - ActiveRecord 3+
115
+ - ActiveSupport 3+
80
116
  - It's polymorphic association.
117
+ - It uses ActiveSupport::TimeWithZone to return user friendly statistics.
118
+ So, you have to operate with dates with time zones.
81
119
  - Use it in production with caution because it's early release.
82
120
 
83
121
 
84
- Installation
85
- --------------
122
+ ## Installation
86
123
 
87
124
  Add gem to Gemfile
88
125
 
@@ -18,12 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(/^(test|spec|features)\//)
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'activerecord', '~> 3'
21
+ spec.add_dependency 'activerecord', '>= 3'
22
+ spec.add_dependency 'activesupport', '>= 3'
22
23
  spec.add_dependency 'pg', '~> 0'
23
-
24
- spec.add_development_dependency 'bundler', '~> 1.7'
25
- spec.add_development_dependency 'database_cleaner', '~> 0'
26
- spec.add_development_dependency 'rspec', '~> 3'
27
- spec.add_development_dependency 'fabrication', '~> 0'
28
- spec.add_development_dependency 'rake', '~> 10.0'
29
24
  end
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rspec"
7
+ gem "database_cleaner"
8
+ gem "activerecord", "~> 3.0"
9
+ gem "activesupport", "~> 3.0"
10
+ gem "pg"
11
+
12
+ gemspec :path => "../"
@@ -0,0 +1,60 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ event-counter (0.1.0)
5
+ activerecord (>= 3)
6
+ activesupport (>= 3)
7
+ pg (~> 0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (3.2.19)
13
+ activesupport (= 3.2.19)
14
+ builder (~> 3.0.0)
15
+ activerecord (3.2.19)
16
+ activemodel (= 3.2.19)
17
+ activesupport (= 3.2.19)
18
+ arel (~> 3.0.2)
19
+ tzinfo (~> 0.3.29)
20
+ activesupport (3.2.19)
21
+ i18n (~> 0.6, >= 0.6.4)
22
+ multi_json (~> 1.0)
23
+ appraisal (1.0.2)
24
+ bundler
25
+ rake
26
+ thor (>= 0.14.0)
27
+ arel (3.0.3)
28
+ builder (3.0.4)
29
+ database_cleaner (1.3.0)
30
+ diff-lcs (1.2.5)
31
+ i18n (0.6.11)
32
+ multi_json (1.10.1)
33
+ pg (0.17.1)
34
+ rake (10.3.2)
35
+ rspec (3.1.0)
36
+ rspec-core (~> 3.1.0)
37
+ rspec-expectations (~> 3.1.0)
38
+ rspec-mocks (~> 3.1.0)
39
+ rspec-core (3.1.7)
40
+ rspec-support (~> 3.1.0)
41
+ rspec-expectations (3.1.2)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.1.0)
44
+ rspec-mocks (3.1.3)
45
+ rspec-support (~> 3.1.0)
46
+ rspec-support (3.1.2)
47
+ thor (0.19.1)
48
+ tzinfo (0.3.41)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ activerecord (~> 3.0)
55
+ activesupport (~> 3.0)
56
+ appraisal
57
+ database_cleaner
58
+ event-counter!
59
+ pg
60
+ rspec
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rspec"
7
+ gem "database_cleaner"
8
+ gem "activerecord", "~> 3.1"
9
+ gem "activesupport", "~> 3.1"
10
+ gem "pg"
11
+
12
+ gemspec :path => "../"
@@ -0,0 +1,60 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ event-counter (0.1.0)
5
+ activerecord (>= 3)
6
+ activesupport (>= 3)
7
+ pg (~> 0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (3.2.19)
13
+ activesupport (= 3.2.19)
14
+ builder (~> 3.0.0)
15
+ activerecord (3.2.19)
16
+ activemodel (= 3.2.19)
17
+ activesupport (= 3.2.19)
18
+ arel (~> 3.0.2)
19
+ tzinfo (~> 0.3.29)
20
+ activesupport (3.2.19)
21
+ i18n (~> 0.6, >= 0.6.4)
22
+ multi_json (~> 1.0)
23
+ appraisal (1.0.2)
24
+ bundler
25
+ rake
26
+ thor (>= 0.14.0)
27
+ arel (3.0.3)
28
+ builder (3.0.4)
29
+ database_cleaner (1.3.0)
30
+ diff-lcs (1.2.5)
31
+ i18n (0.6.11)
32
+ multi_json (1.10.1)
33
+ pg (0.17.1)
34
+ rake (10.3.2)
35
+ rspec (3.1.0)
36
+ rspec-core (~> 3.1.0)
37
+ rspec-expectations (~> 3.1.0)
38
+ rspec-mocks (~> 3.1.0)
39
+ rspec-core (3.1.7)
40
+ rspec-support (~> 3.1.0)
41
+ rspec-expectations (3.1.2)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.1.0)
44
+ rspec-mocks (3.1.3)
45
+ rspec-support (~> 3.1.0)
46
+ rspec-support (3.1.2)
47
+ thor (0.19.1)
48
+ tzinfo (0.3.41)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ activerecord (~> 3.1)
55
+ activesupport (~> 3.1)
56
+ appraisal
57
+ database_cleaner
58
+ event-counter!
59
+ pg
60
+ rspec
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rspec"
7
+ gem "database_cleaner"
8
+ gem "activerecord", "~> 3.2"
9
+ gem "activesupport", "~> 3.2"
10
+ gem "pg"
11
+
12
+ gemspec :path => "../"
@@ -0,0 +1,60 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ event-counter (0.1.0)
5
+ activerecord (>= 3)
6
+ activesupport (>= 3)
7
+ pg (~> 0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (3.2.19)
13
+ activesupport (= 3.2.19)
14
+ builder (~> 3.0.0)
15
+ activerecord (3.2.19)
16
+ activemodel (= 3.2.19)
17
+ activesupport (= 3.2.19)
18
+ arel (~> 3.0.2)
19
+ tzinfo (~> 0.3.29)
20
+ activesupport (3.2.19)
21
+ i18n (~> 0.6, >= 0.6.4)
22
+ multi_json (~> 1.0)
23
+ appraisal (1.0.2)
24
+ bundler
25
+ rake
26
+ thor (>= 0.14.0)
27
+ arel (3.0.3)
28
+ builder (3.0.4)
29
+ database_cleaner (1.3.0)
30
+ diff-lcs (1.2.5)
31
+ i18n (0.6.11)
32
+ multi_json (1.10.1)
33
+ pg (0.17.1)
34
+ rake (10.3.2)
35
+ rspec (3.1.0)
36
+ rspec-core (~> 3.1.0)
37
+ rspec-expectations (~> 3.1.0)
38
+ rspec-mocks (~> 3.1.0)
39
+ rspec-core (3.1.7)
40
+ rspec-support (~> 3.1.0)
41
+ rspec-expectations (3.1.2)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.1.0)
44
+ rspec-mocks (3.1.3)
45
+ rspec-support (~> 3.1.0)
46
+ rspec-support (3.1.2)
47
+ thor (0.19.1)
48
+ tzinfo (0.3.41)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ activerecord (~> 3.2)
55
+ activesupport (~> 3.2)
56
+ appraisal
57
+ database_cleaner
58
+ event-counter!
59
+ pg
60
+ rspec