Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Version 0.1.3

Support for last_monday, last_tuesday, etc
  • Loading branch information...
commit ee192d5c41d823b3a9d9d48159332f316882d9c5 1 parent d302ec1
@winton authored
View
12 README.markdown
@@ -13,13 +13,17 @@ sudo gem install periodic_counter
Create columns
--------------
-You should already have a counter column defined that is being incremented by something (let's call the column X).
+You should already have a counter column (let's call it X) that is being incremented by some external process.
-Define period columns using this format: <code>X\_last\_week</code> or <code>X\_last\_6\_hours</code>.
+Add an <code>X_data</code> varchar column with a length of 2048.
-The period name should follow the format of [ActiveSupport's time extensions](http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Numeric/Time.html).
+Add your periodic counters (all integers):
-Also add an <code>X_data</code> varchar column with a length of 2048.
+* <code>X\_last\_week</code>
+* <code>X\_last\_6\_hours</code>
+* <code>X\_last_sunday</code>
+
+Currently only days of the week and [ActiveSupport's time extensions](http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Numeric/Time.html) are supported for text after <code>X_last</code>. If no digit is present, "1" is assumed.
Create configuration
--------------------
View
50 lib/periodic_counter.rb
@@ -3,6 +3,8 @@
class PeriodicCounter
+ WEEKDAYS = %w(sunday monday tuesday wednesday thursday friday saturday)
+
def initialize(environment, root)
@db, @log, @mail = ActiveWrapper.setup(
:base => root,
@@ -29,8 +31,7 @@ def initialize(environment, root)
# Find period columns
period = columns.select do |col|
col =~ /^#{column}/ &&
- col != column &&
- !col.include?('_data')
+ col =~ /_last_/
end
# Grab all records
select_columns = [ 'id', column, "#{column}_data" ]
@@ -45,25 +46,34 @@ def initialize(environment, root)
count = record.delete(column).to_i
# Set period counters
period.each do |col|
- computed_at = data["#{col}_at"] || Time.now.utc
- duration = column_to_period_integer(col)
- time_since_compute = Time.now.utc - computed_at
- last_day =
- if col.include?('day')
- self.class.today
- elsif col.include?('week')
- self.class.last_monday
- elsif col.include?('month')
- self.class.first_of_the_month
+ if WEEKDAYS.include?(weekday = col.split('_last_')[1])
+ data["#{col}_before_today"] ||= 0
+ if self.class.weekday(weekday)
+ record[col] = count - data["#{col}_before_today"]
+ else
+ data["#{col}_before_today"] = count
end
- if (time_since_compute - duration) >= 0
- data[col] = count
- data["#{col}_at"] = last_day
else
- data[col] ||= count
- data["#{col}_at"] ||= last_day
+ computed_at = data["#{col}_at"] || Time.now.utc
+ duration = column_to_period_integer(col)
+ time_since_compute = Time.now.utc - computed_at
+ last_day =
+ if col.include?('day')
+ self.class.today
+ elsif col.include?('week')
+ self.class.last_monday
+ elsif col.include?('month')
+ self.class.first_of_the_month
+ end
+ if (time_since_compute - duration) >= 0
+ data[col] = count
+ data["#{col}_at"] = last_day
+ else
+ data[col] ||= count
+ data["#{col}_at"] ||= last_day
+ end
+ record[col] = count - data[col].to_i
end
- record[col] = count - data[col].to_i
end
# Update record
record["#{column}_data"] = "'#{YAML::dump(data)}'"
@@ -108,5 +118,9 @@ def last_monday(now=Time.now.utc.to_date)
def today(now=Time.now.utc.to_date)
Date.new(now.year, now.month, now.day).to_time(:utc)
end
+
+ def weekday(day)
+ Time.now.utc.to_date.wday == WEEKDAYS.index(day)
+ end
end
end
View
2  require.rb
@@ -18,7 +18,7 @@
name 'periodic_counter'
homepage "http://github.com/winton/#{name}"
summary "Maintains period fields on any counter column in your database"
- version '0.1.2'
+ version '0.1.3'
end
bin { require 'lib/periodic_counter' }
View
3  spec/db/migrate/001_counters.rb
@@ -4,6 +4,9 @@ def self.up
t.integer :counter
t.integer :counter_last_day
t.integer :counter_last_2_days
+ t.integer :counter_last_monday
+ t.integer :counter_last_tuesday
+ t.integer :counter_last_wednesday
t.string :counter_data, :limit => 2048
end
end
View
53 spec/periodic_counter_spec.rb
@@ -6,10 +6,11 @@
$db.migrate(1)
$db.migrate(0)
$db.migrate(1)
+ stub_time(PeriodicCounter.last_monday)
create_counter
end
- it "should not do anything but set up data" do
+ it "should set up data and increment last_monday (today)" do
start
attributes = Counter.last.attributes
data = attributes.delete('counter_data')
@@ -17,17 +18,23 @@
data.delete('counter_last_2_days_at').to_s.should == PeriodicCounter.today.to_s
data.should == {
"counter_last_day"=>1,
- "counter_last_2_days"=>1
+ "counter_last_2_days"=>1,
+ "counter_last_monday_before_today"=>0,
+ "counter_last_tuesday_before_today"=>1,
+ "counter_last_wednesday_before_today"=>1
}
attributes.should == {
"id"=>1,
"counter"=>1,
"counter_last_day"=>0,
- "counter_last_2_days"=>0
+ "counter_last_2_days"=>0,
+ "counter_last_monday"=>1,
+ "counter_last_tuesday"=>0,
+ "counter_last_wednesday"=>0
}
end
- it "should add to both counters on increment" do
+ it "should add to last_day, last_2_days, and last_monday counters on increment" do
Counter.last.update_attribute :counter, 2
start
attributes = Counter.last.attributes
@@ -36,19 +43,25 @@
data.delete('counter_last_2_days_at').to_s.should == PeriodicCounter.today.to_s
data.should == {
"counter_last_day"=>1,
- "counter_last_2_days"=>1
+ "counter_last_2_days"=>1,
+ "counter_last_monday_before_today"=>0,
+ "counter_last_tuesday_before_today"=>2,
+ "counter_last_wednesday_before_today"=>2
}
attributes.should == {
"id"=>1,
"counter"=>2,
"counter_last_day"=>1,
- "counter_last_2_days"=>1
+ "counter_last_2_days"=>1,
+ "counter_last_monday"=>2,
+ "counter_last_tuesday"=>0,
+ "counter_last_wednesday"=>0
}
end
- it "should reset counter_last_day" do
+ it "should reset counter_last_day and increment last_tuesday" do
Counter.last.update_attribute :counter, 3
- stub_time(Time.now + 1.day)
+ stub_time(Time.now + 1.day) # Tuesday
start
attributes = Counter.last.attributes
data = attributes.delete('counter_data')
@@ -56,19 +69,25 @@
data.delete('counter_last_2_days_at').to_s.should == (PeriodicCounter.today - 1.day).to_s
data.should == {
"counter_last_day"=>3,
- "counter_last_2_days"=>1
+ "counter_last_2_days"=>1,
+ "counter_last_monday_before_today"=>3,
+ "counter_last_tuesday_before_today"=>2,
+ "counter_last_wednesday_before_today"=>3
}
attributes.should == {
"id"=>1,
"counter"=>3,
"counter_last_day"=>0,
- "counter_last_2_days"=>2
+ "counter_last_2_days"=>2,
+ "counter_last_monday"=>2,
+ "counter_last_tuesday"=>1,
+ "counter_last_wednesday"=>0
}
end
- it "should reset counter_last_2_days" do
+ it "should reset last_2_days and not touch last_wednesday" do
Counter.last.update_attribute :counter, 4
- stub_time(Time.now + 2.days)
+ stub_time(Time.now + 2.days) # Thursday
start
attributes = Counter.last.attributes
data = attributes.delete('counter_data')
@@ -76,13 +95,19 @@
data.delete('counter_last_2_days_at').to_s.should == PeriodicCounter.today.to_s
data.should == {
"counter_last_day"=>4,
- "counter_last_2_days"=>4
+ "counter_last_2_days"=>4,
+ "counter_last_monday_before_today"=>4,
+ "counter_last_tuesday_before_today"=>4,
+ "counter_last_wednesday_before_today"=>4
}
attributes.should == {
"id"=>1,
"counter"=>4,
"counter_last_day"=>0,
- "counter_last_2_days"=>0
+ "counter_last_2_days"=>0,
+ "counter_last_monday"=>2,
+ "counter_last_tuesday"=>1,
+ "counter_last_wednesday"=>0
}
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.