headcount 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ # Version 0.7.0 - 2012-04-06
4
+
5
+ * Added seeding support and ability to get a headcount for any given time
6
+
7
+ # Version 0.6.0 - 2012-04-06
8
+
9
+ * What was added?
10
+
3
11
  # Version 0.5.0 - 2012-04-06
4
12
 
5
13
  * Added timestamping
data/README.md CHANGED
@@ -25,7 +25,7 @@ Configure Headcount through a rails initializer. Here's an example:
25
25
  # config/initializers/headcount.rb
26
26
  Headcount.configure do |config|
27
27
  config.path = 'db/headcount.json' # default
28
- config.timestamp = '' # default (YYYY-MM-DD HH:MM:SS)
28
+ config.timestamp = '%Y-%m-%d %H:%M:%S' # default (YYYY-MM-DD HH:MM:SS)
29
29
 
30
30
  # by default Headcount will use the underlying table name for the key
31
31
  count User # :users key implied
@@ -58,6 +58,23 @@ If you'd like to have the results written to disk instead just use the bang vers
58
58
  Headcount.count! # will append the results to the output file
59
59
  ```
60
60
 
61
+ ## Seeding
62
+
63
+ If you have a history of data that you'd like to generate headcounts you can give the `seed` method a try.
64
+
65
+ **Notice** For seeding to work your queries must respond to `where` and the underlying table must have a `created_at` column. If resulting historical query is invalid, the headcount will just fall back to the original query.
66
+
67
+ ```
68
+ Headcount.seed(2.years.ago, 1.day) # preview the historical headcounts
69
+ ```
70
+
71
+ If you're happy with the data, simply call the bang version to write it to disk:
72
+
73
+ ```
74
+ Headcount.seed!(2.years.ago, 1.day) # WARNING: this will overwrite any existing data
75
+ ```
76
+
77
+
61
78
  ## Scheduling
62
79
 
63
80
  Your options are open as far as scheduling goes. If you like [crontab](http://crontab.org/), use crontab. If you prefer [clockwork](https://github.com/tomykaira/clockwork), use clockwork.
@@ -2,11 +2,14 @@ require 'headcount/support'
2
2
  require 'headcount/registry'
3
3
  require 'headcount/persistence'
4
4
  require 'headcount/configuration'
5
+ require 'headcount/history'
5
6
  require 'headcount/railtie' if defined?(Rails)
6
7
 
7
8
  module Headcount
8
9
  @@registry = Headcount::Registry.new
9
-
10
+
11
+ include Headcount::History
12
+
10
13
  class << self
11
14
  def register(key, query)
12
15
  key.to_sym.tap do |key|
@@ -17,15 +20,23 @@ module Headcount
17
20
  def find(key)
18
21
  @@registry[key.to_sym]
19
22
  end
20
-
21
- def count(key = nil)
22
- if key
23
+
24
+ # this method is getting a little messy -- need to clean it up
25
+ # arg can either be a symbol or a time instance
26
+ def count(arg = nil)
27
+ if arg.is_a?(Symbol)
28
+ key = arg
23
29
  count_for(key)
24
30
  else
25
31
  {}.tap do |headcount|
26
- headcount[:timestamp] = Headcount::Support.timestamp_for(DateTime.now)
32
+ now = DateTime.now
33
+ time = arg || now
34
+ headcount[:timestamp] = Headcount::Support.timestamp_for(time)
27
35
 
28
36
  @@registry.each do |key, query| # using map would return an array here
37
+ query = query_for_time(query, time) unless time == now
38
+ query = yield query if block_given? # can alter the query at execution
39
+
29
40
  headcount[key] = query.count
30
41
  end
31
42
  end
@@ -33,7 +44,9 @@ module Headcount
33
44
  end
34
45
 
35
46
  def count!
36
- persist(count)
47
+ count.tap do |headcount|
48
+ persist(headcount)
49
+ end
37
50
  end
38
51
 
39
52
  def reset
@@ -0,0 +1,37 @@
1
+ module Headcount
2
+ module History
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def seed(start, interval)
7
+ time = start
8
+ now = DateTime.now
9
+ headcounts = []
10
+
11
+ while time < now
12
+ headcounts << Headcount.count(time)
13
+ time += interval
14
+ end
15
+
16
+ headcounts
17
+ end
18
+
19
+ def seed!(start, interval)
20
+ seed(start, interval).tap do |headcounts|
21
+ persist(headcounts, {:reset => true})
22
+ end
23
+ end
24
+
25
+ private
26
+ def query_for_time(query, time)
27
+ begin
28
+ query.where('created_at <= ?', time).tap do |modified_query|
29
+ modified_query.count # will trigger an error immediately so we can handle it below
30
+ end
31
+ rescue
32
+ query # just return the original query
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -3,8 +3,9 @@ require 'headcount/persistence/file'
3
3
  module Headcount
4
4
  class << self
5
5
  private
6
- def persist(headcount)
7
- persistence_handler.save(count)
6
+ def persist(headcounts, options = {})
7
+ headcounts = Array.wrap(headcounts)
8
+ persistence_handler.save(headcounts, options)
8
9
  end
9
10
  end
10
11
  end
@@ -6,9 +6,13 @@ module Headcount
6
6
  @format = format
7
7
  end
8
8
 
9
- def save(headcount)
9
+ def save(headcounts, options = {})
10
+ ::File.delete(@path) if ::File.exists?(@path) if options[:reset]
11
+
10
12
  ::File.open(@path, 'a') do |file|
11
- file.puts headcount.to_json
13
+ headcounts.each do |headcount|
14
+ file.puts headcount.to_json
15
+ end
12
16
  end
13
17
  end
14
18
  end
@@ -1,3 +1,3 @@
1
1
  module Headcount
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: headcount
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.6.0
5
+ version: 0.7.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ryan Mohr
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-04-06 00:00:00 Z
13
+ date: 2012-04-07 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -101,6 +101,7 @@ extra_rdoc_files: []
101
101
  files:
102
102
  - lib/headcount/configuration.rb
103
103
  - lib/headcount/exceptions.rb
104
+ - lib/headcount/history.rb
104
105
  - lib/headcount/persistence/file.rb
105
106
  - lib/headcount/persistence.rb
106
107
  - lib/headcount/railtie.rb