Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixing logic a bit

  • Loading branch information...
commit 4ae81e07d080d4b46e8d1b3bd6f7e33d8bb62283 1 parent 3346c09
@winton authored
View
6 README.markdown
@@ -13,11 +13,11 @@ sudo gem install periodic_template
Create columns
--------------
-For every counter column (X), you should also have a <code>X\_computed\_at</code> datetime column.
+Define period columns using this format: <code>X\_last\_1\_week</code> or <code>X\_last\_6\_hours</code>.
-To define period columns, use this format: <code>X\_last\_1\_week</code> or <code>X\_last\_6\_hours</code>. The name should follow the format of [ActiveSupport's time extensions](http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Numeric/Time.html).
+The name should follow the format of [ActiveSupport's time extensions](http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Numeric/Time.html).
-If you are adding this to a counter that already has a count, you will also need a <code>X\_starting\_value</code> integer column.
+Also add a <code>counter_data</code> varchar column with a length of 2048.
Create configuration
--------------------
View
36 lib/periodic_counter.rb
@@ -26,40 +26,40 @@ def initialize(environment, root)
if columns
columns.each do |column|
if counters.include?(column)
+ # Find period columns
period = columns.select do |col|
col =~ /^#{column}/ &&
col != column &&
- !col.include?('computed_at') &&
- !col.include?('starting_value')
+ !col.include?('_data')
end
- select_columns = [ 'id', column, "#{column}_computed_at", "#{column}_starting_value" ] + period
- select_columns &= columns
+ # Grab all records
+ select_columns = [ 'id', column, "#{column}_data" ]
+ select_columns += period
records = ActiveRecord::Base.connection.select_all <<-SQL
SELECT #{select_columns.join(', ')}
FROM #{table}
SQL
records.each do |record|
id = record.delete('id')
- computed_at = ActiveRecord::ConnectionAdapters::Column.string_to_time(
- record.delete("#{column}_computed_at")
- )
+ data = YAML::load(record["#{column}_data"] || '') || {}
+ computed_at = data['computed_at'] || Time.now.utc
count = record.delete(column).to_i
- time_since_compute = Time.now.utc - computed_at.utc
- if record.keys.include?("#{column}_starting_value")
- unless record["#{column}_starting_value"]
- record["#{column}_starting_value"] = count
- end
- starting_value = record["#{column}_starting_value"].to_i
- end
- starting_value ||= 0
+ time_since_compute = Time.now.utc - computed_at
+ # Set period counters
period.each do |col|
- period_count = record[col].to_i
duration = column_to_period_integer(col)
+ starting_value = data[col].to_i
if (time_since_compute - duration) >= 0
- record[col] = count - period_count - starting_value
+ record[col] = count - starting_value
+ data[col] = count
+ else
+ data[col] ||= count
end
end
- set = record.collect { |col, value| "#{col} = #{value}" }
+ # Update record
+ data['computed_at'] = Time.now.utc
+ record["#{column}_data"] = "'#{YAML::dump(data)}'"
+ set = record.collect { |col, value| "#{col} = #{value || 0}" }
ActiveRecord::Base.connection.update <<-SQL
UPDATE #{table}
SET #{set.join(', ')}
View
6 ...db/migrate/001_counters_without_starting_value.rb → spec/db/migrate/001_counters.rb
@@ -1,12 +1,10 @@
-class CountersWithoutStartingValue < ActiveRecord::Migration
+class Counters < ActiveRecord::Migration
def self.up
create_table :counters do |t|
t.integer :counter
- t.datetime :counter_computed_at
t.integer :counter_last_day
t.integer :counter_last_2_days
- t.integer :counter_last_week
- t.integer :counter_last_2_weeks
+ t.string :counter_data, :limit => 2048
end
end
View
17 spec/db/migrate/002_counters_with_starting_value.rb
@@ -1,17 +0,0 @@
-class CountersWithStartingValue < ActiveRecord::Migration
- def self.up
- drop_table :counters
- create_table :counters do |t|
- t.integer :counter
- t.integer :counter_starting_value
- t.datetime :counter_computed_at
- t.integer :counter_last_day
- t.integer :counter_last_2_days
- t.integer :counter_last_week
- t.integer :counter_last_2_weeks
- end
- end
-
- def self.down
- end
-end
View
150 spec/periodic_counter_spec.rb
@@ -1,98 +1,66 @@
require 'spec_helper'
describe PeriodicCounter do
- describe "without starting value" do
-
- before(:each) do
- $db.migrate(1)
- $db.migrate(0)
- $db.migrate(1)
- create_counter
- end
-
- it "should add to counter_last_day" do
- stub_time(Time.now + 1.day)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 1
- Counter.last.counter_last_week.should == 1
- Counter.last.counter_last_2_weeks.should == 1
- end
-
- it "should add to counter_last_2_days" do
- stub_time(Time.now + 2.days)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 2
- Counter.last.counter_last_week.should == 1
- Counter.last.counter_last_2_weeks.should == 1
- end
-
- it "should add to counter_last_week" do
- stub_time(Time.now + 1.week)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 2
- Counter.last.counter_last_week.should == 2
- Counter.last.counter_last_2_weeks.should == 1
- end
-
- it "should add to counter_last_2_weeks" do
- stub_time(Time.now + 2.weeks)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 2
- Counter.last.counter_last_week.should == 2
- Counter.last.counter_last_2_weeks.should == 2
- end
+
+ before(:all) do
+ $db.migrate(1)
+ $db.migrate(0)
+ $db.migrate(1)
+ create_counter
+ end
+
+ it "should not do anything but set up data" do
+ start
+ attributes = Counter.last.attributes
+ data = attributes.delete('counter_data')
+ data.delete('computed_at').to_s.should == Time.now.utc.to_s
+ data.should == {
+ "counter_last_day"=>1,
+ "counter_last_2_days"=>1
+ }
+ attributes.should == {
+ "id"=>1,
+ "counter"=>1,
+ "counter_last_day"=>0,
+ "counter_last_2_days"=>0
+ }
+ end
+
+ it "should add to counter_last_day" do
+ Counter.last.update_attribute :counter, 2
+ stub_time(Time.now + 1.day)
+ start
+ attributes = Counter.last.attributes
+ data = attributes.delete('counter_data')
+ data.delete('computed_at').to_s.should == Time.now.utc.to_s
+ data.should == {
+ "counter_last_day"=>2,
+ "counter_last_2_days"=>1
+ }
+ attributes.should == {
+ "id"=>1,
+ "counter"=>2,
+ "counter_last_day"=>1,
+ "counter_last_2_days"=>0
+ }
end
- describe "with starting value" do
-
- before(:each) do
- $db.migrate(2)
- $db.migrate(0)
- $db.migrate(2)
- Counter.reset_column_information
- create_counter
- start
- Counter.last.update_attribute :counter, 6
- end
-
- it "should add to counter_last_day" do
- stub_time(Time.now + 1.day)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 1
- Counter.last.counter_last_week.should == 1
- Counter.last.counter_last_2_weeks.should == 1
- end
-
- it "should add to counter_last_2_days" do
- stub_time(Time.now + 2.days)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 2
- Counter.last.counter_last_week.should == 1
- Counter.last.counter_last_2_weeks.should == 1
- end
-
- it "should add to counter_last_week" do
- stub_time(Time.now + 1.week)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 2
- Counter.last.counter_last_week.should == 2
- Counter.last.counter_last_2_weeks.should == 1
- end
-
- it "should add to counter_last_2_weeks" do
- stub_time(Time.now + 2.weeks)
- start
- Counter.last.counter_last_day.should == 2
- Counter.last.counter_last_2_days.should == 2
- Counter.last.counter_last_week.should == 2
- Counter.last.counter_last_2_weeks.should == 2
- end
+ it "should add to counter_last_2_days" do
+ Counter.last.update_attribute :counter, 3
+ stub_time(Time.now + 3.days)
+ start
+ attributes = Counter.last.attributes
+ data = attributes.delete('counter_data')
+ data.delete('computed_at').to_s.should == Time.now.utc.to_s
+ data.should == {
+ "counter_last_day"=>3,
+ "counter_last_2_days"=>3
+ }
+ attributes.should == {
+ "id"=>1,
+ "counter"=>3,
+ "counter_last_day"=>1,
+ "counter_last_2_days"=>2
+ }
end
end
View
10 spec/spec_helper.rb
@@ -11,14 +11,7 @@
$db.establish_connection
def create_counter
- Counter.create(
- :counter => 3,
- :counter_computed_at => Time.now,
- :counter_last_day => 1,
- :counter_last_2_days => 1,
- :counter_last_week => 1,
- :counter_last_2_weeks => 1
- )
+ Counter.create(:counter => 1)
end
def start
@@ -30,4 +23,5 @@ def stub_time(time)
end
class Counter < ActiveRecord::Base
+ serialize :counter_data
end
Please sign in to comment.
Something went wrong with that request. Please try again.