included run limit in cache identifier (closes #3) - reportable - Fork of reportable required by WarVox, from hdm/reportable.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 063ae7ebfb466b15d8fdb0347f9c4eaeff7775b2
 (DIR) parent a8fd0e703fd9b424cc69125c89722d85664bb5da
 (HTM) Author: Marco Otte-Witte <marco.otte-witte@simplabs.com>
       Date:   Wed, 29 Apr 2009 15:00:55 +0200
       
       included run limit in cache identifier (closes #3)
       
       Diffstat:
         M generators/reports_as_sparkline_mi… |      15 +++++++++------
         M lib/simplabs/reports_as_sparkline/… |      52 ++++++++++---------------------
         M spec/classes/report_cache_spec.rb   |      48 +++++++++++++++----------------
         M spec/classes/report_spec.rb         |      22 ++++++++++++++++++++++
         M spec/db/schema.rb                   |      11 +++++++----
       
       5 files changed, 77 insertions(+), 71 deletions(-)
       ---
 (DIR) diff --git a/generators/reports_as_sparkline_migration/templates/migration.erb b/generators/reports_as_sparkline_migration/templates/migration.erb
       @@ -8,6 +8,7 @@ class <%= class_name %> < ActiveRecord::Migration
              t.string   :aggregation,      :null => false
              t.float    :value,            :null => false, :default => 0
              t.datetime :reporting_period, :null => false
       +      t.integer  :run_limit,        :null => false
        
              t.timestamps
            end
       @@ -16,20 +17,22 @@ class <%= class_name %> < ActiveRecord::Migration
              :model_name,
              :report_name,
              :grouping,
       -      :aggregation
       -    ], :name => :name_model_grouping_agregation
       +      :aggregation,
       +      :run_limit
       +    ], :name => :name_model_grouping_agregation_run_limit
            add_index :reports_as_sparkline_cache, [
              :model_name,
              :report_name,
              :grouping,
              :aggregation,
       -      :reporting_period
       -    ], :unique => true, :name => :name_model_grouping_aggregation_period
       +      :reporting_period,
       +      :run_limit
       +    ], :unique => true, :name => :name_model_grouping_aggregation_period_run_limit
          end
        
          def self.down
       -    remove_index :reports_as_sparkline_cache, :name => :name_model_grouping_agregation
       -    remove_index :reports_as_sparkline_cache, :name => :name_model_grouping_aggregation_period
       +    remove_index :reports_as_sparkline_cache, :name => :name_model_grouping_agregation_run_limit
       +    remove_index :reports_as_sparkline_cache, :name => :name_model_grouping_aggregation_period_run_limit
        
            drop_table :reports_as_sparkline_cache
          end
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/report_cache.rb b/lib/simplabs/reports_as_sparkline/report_cache.rb
       @@ -12,61 +12,39 @@ module Simplabs #:nodoc:
                  cached_data = []
                  first_reporting_period = ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date])
                  last_reporting_period = options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]) : nil
       +
                  if cache
                    cached_data = find_cached_data(report, options, first_reporting_period, last_reporting_period)
                    first_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.first.reporting_period)
                    last_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period)
                  end
       -          new_after_cache_data = if !options[:live_data] && last_cached_reporting_period == ReportingPeriod.new(options[:grouping]).previous
       +
       +          new_data = if !options[:live_data] && last_cached_reporting_period == ReportingPeriod.new(options[:grouping]).previous
                    []
                  else
                    end_date = options[:live_data] ? nil : last_reporting_period && last_reporting_period.date_time
                    yield((last_cached_reporting_period.next rescue first_reporting_period).date_time, end_date)
                  end
       -          new_before_cache_data = if cached_data.empty? || first_cached_reporting_period.date_time == first_reporting_period.date_time
       -            []
       -          else
       -            yield(first_reporting_period.date_time, first_cached_reporting_period.date_time)
       -          end
       -          prepare_result(new_before_cache_data, new_after_cache_data, cached_data, report, options, cache)
       +
       +          prepare_result(new_data, cached_data, report, options, cache)
                end
              end
        
              private
        
       -        def self.prepare_result(new_before_cache_data, new_after_cache_data, cached_data, report, options, cache = true)
       -          cache_map_proc = lambda { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] }
       -
       -          new_after_cache_data = new_after_cache_data.map &cache_map_proc
       -          new_before_cache_data = new_before_cache_data.map &cache_map_proc
       +        def self.prepare_result(new_data, cached_data, report, options, cache = true)
       +          new_data = new_data.map { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] }
                  result = cached_data.map { |cached| [cached.reporting_period, cached.value] }
       -
       -          first_reporting_period = ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date])
                  last_reporting_period = ReportingPeriod.new(options[:grouping], options[:end_date])
       -          first_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.first.reporting_period)
       -          last_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period)
       -
       -          if first_cached_reporting_period
       -            reporting_period = first_reporting_period
       -            while reporting_period < first_cached_reporting_period
       -              cached = build_cached_data(report, options[:grouping], reporting_period, find_value(new_before_cache_data, reporting_period))
       -              cached.save! if cache
       -              result.insert(0, [reporting_period.date_time, cached.value])
       -              reporting_period = reporting_period.next
       -            end
       -          end
       -
       -          reporting_period = cached_data.empty? ? first_reporting_period : last_cached_reporting_period.next
       -
       +          reporting_period = cached_data.empty? ? ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date]) : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period).next
                  while reporting_period < last_reporting_period
       -            cached = build_cached_data(report, options[:grouping], reporting_period, find_value(new_after_cache_data, reporting_period))
       +            cached = build_cached_data(report, options[:grouping], options[:limit], reporting_period, find_value(new_data, reporting_period))
                    cached.save! if cache
                    result << [reporting_period.date_time, cached.value]
                    reporting_period = reporting_period.next
                  end
       -
                  if options[:live_data]
       -            result << [last_reporting_period.date_time, find_value(new_after_cache_data, last_reporting_period)]
       +            result << [last_reporting_period.date_time, find_value(new_data, last_reporting_period)]
                  end
                  result
                end
       @@ -76,24 +54,26 @@ module Simplabs #:nodoc:
                  data ? data[1] : 0.0
                end
        
       -        def self.build_cached_data(report, grouping, reporting_period, value)
       +        def self.build_cached_data(report, grouping, limit, reporting_period, value)
                  self.new(
                    :model_name       => report.klass.to_s,
                    :report_name      => report.name.to_s,
                    :grouping         => grouping.identifier.to_s,
                    :aggregation      => report.aggregation.to_s,
                    :reporting_period => reporting_period.date_time,
       -            :value            => value
       +            :value            => value,
       +            :run_limit        => limit
                  )
                end
        
                def self.find_cached_data(report, options, first_reporting_period, last_reporting_period)
                  conditions = [
       -            'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ?',
       +            'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ?',
                    report.klass.to_s,
                    report.name.to_s,
                    options[:grouping].identifier.to_s,
       -            report.aggregation.to_s
       +            report.aggregation.to_s,
       +            options[:limit]
                  ]
                  if last_reporting_period
                    conditions.first << ' AND reporting_period BETWEEN ? AND ?'
 (DIR) diff --git a/spec/classes/report_cache_spec.rb b/spec/classes/report_cache_spec.rb
       @@ -37,7 +37,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
                }.should raise_error(YieldMatchException)
              end
        
       -      it 'should yield the reporting period after the last one in the cache, and before the first one in the cache if data was read from cache' do
       +      it 'should yield the reporting period after the last one in the cache if data was read from cache' do
                reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(
                  @report.options[:grouping],
                  Time.now - 3.send(@report.options[:grouping].identifier)
       @@ -46,15 +46,11 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
                cached.stub!(:reporting_period).and_return(reporting_period.date_time)
                Simplabs::ReportsAsSparkline::ReportCache.stub!(:find).and_return([cached])
        
       -        expected_dates = [[reporting_period.next.date_time, nil], [reporting_period.offset(-7).date_time, reporting_period.date_time]]
       -        yield_count = 0
                Simplabs::ReportsAsSparkline::ReportCache.process(@report, @options) do |begin_at, end_at|
       -          [begin_at, end_at].should == expected_dates[yield_count]
       -          yield_count += 1
       +          begin_at.should == reporting_period.next.date_time
       +          end_at.should   == nil
                  []
                end
       -
       -        yield_count.should == 2
              end
        
            end
       @@ -76,7 +72,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
                }.should raise_error(YieldMatchException)
              end
        
       -      it 'should yield the reporting period after the last one in the cache, and before the first one in the cache if data was read from cache' do
       +      it 'should yield the reporting period after the last one in the cache if data was read from cache' do
                reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(
                  @report.options[:grouping],
                  Time.now - 3.send(@report.options[:grouping].identifier)
       @@ -85,15 +81,11 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
                cached.stub!(:reporting_period).and_return(reporting_period.date_time)
                Simplabs::ReportsAsSparkline::ReportCache.stub!(:find).and_return([cached])
        
       -        expected_dates = [[reporting_period.next.date_time, nil], [reporting_period.offset(-7).date_time, reporting_period.date_time]]
       -        yield_count = 0
                Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options) do |begin_at, end_at|
       -          [begin_at, end_at].should == expected_dates[yield_count]
       -          yield_count += 1
       +          begin_at.should == reporting_period.next.date_time
       +          end_at.should == nil
                  []
                end
       -
       -        yield_count.should == 2
              end
        
            end
       @@ -102,11 +94,12 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:find).once.with(
                :all,
                :conditions => [
       -          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND reporting_period >= ?',
       +          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ? AND reporting_period >= ?',
                  @report.klass.to_s,
                  @report.name.to_s,
                  @report.options[:grouping].identifier.to_s,
                  @report.aggregation.to_s,
       +          10,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 10).date_time
                ],
                :limit => 10,
       @@ -121,11 +114,12 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:find).once.with(
                :all,
                :conditions => [
       -          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND reporting_period BETWEEN ? AND ?',
       +          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ? AND reporting_period BETWEEN ? AND ?',
                  @report.klass.to_s,
                  @report.name.to_s,
                  @report.options[:grouping].identifier.to_s,
                  @report.aggregation.to_s,
       +          10,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 10).date_time,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.new(@report.options[:grouping], end_date).date_time
                ],
       @@ -141,11 +135,12 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:find).once.with(
                :all,
                :conditions => [
       -          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND reporting_period >= ?',
       +          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ? AND reporting_period >= ?',
                  @report.klass.to_s,
                  @report.name.to_s,
                  grouping.identifier.to_s,
                  @report.aggregation.to_s,
       +          10,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.first(grouping, 10).date_time
                ],
                :limit => 10,
       @@ -187,7 +182,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
        
            before do
              @current_reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(@report.options[:grouping])
       -      @new_after_cache_data = [[@current_reporting_period.previous.date_time, 1.0]]
       +      @new_data = [[@current_reporting_period.previous.date_time, 1.0]]
              Simplabs::ReportsAsSparkline::ReportingPeriod.stub!(:from_db_string).and_return(@current_reporting_period.previous)
              @cached = Simplabs::ReportsAsSparkline::ReportCache.new
              @cached.stub!(:save!)
       @@ -198,38 +193,41 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).exactly(10).times.with(
                @report,
                @report.options[:grouping],
       +        10,
                anything(),
                0.0
              ).and_return(@cached)
        
       -      Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], [], [], @report, @report.options)
       +      Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], [], @report, @report.options)
            end
        
            it 'should create a new Simplabs::ReportsAsSparkline::ReportCache with the correct value if new data has been read' do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).exactly(9).times.with(
                @report,
                @report.options[:grouping],
       +        10,
                anything(),
                0.0
              ).and_return(@cached)
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).once.with(
                @report,
                @report.options[:grouping],
       +        10,
                @current_reporting_period.previous,
                1.0
              ).and_return(@cached)
        
       -      Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], @new_after_cache_data, [], @report, @report.options)
       +      Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options)
            end
        
            it 'should save the created Simplabs::ReportsAsSparkline::ReportCache' do
              @cached.should_receive(:save!).once
        
       -      Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], @new_after_cache_data, [], @report, @report.options)
       +      Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options)
            end
        
            it 'should return an array of arrays of Dates and Floats' do
       -      result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], @new_after_cache_data, [], @report, @report.options, true)
       +      result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options, true)
        
              result.should be_kind_of(Array)
              result[0].should be_kind_of(Array)
       @@ -240,7 +238,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
            describe 'with :live_data = false' do
        
              before do
       -        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], @new_after_cache_data, [], @report, @report.options, true)
       +        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options, true)
              end
        
              it 'should return an array of length :limit' do
       @@ -257,7 +255,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
        
              before do
                options = @report.options.merge(:live_data => true)
       -        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], @new_after_cache_data, [], @report, options, true)
       +        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, options, true)
              end
        
              it 'should return an array of length (:limit + 1)' do
       @@ -275,7 +273,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              it 'should not save the created Simplabs::ReportsAsSparkline::ReportCache' do
                @cached.should_not_receive(:save!)
        
       -        Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, [], @new_after_cache_data, [], @report, @report.options, false)
       +        Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options, false)
              end
        
            end
 (DIR) diff --git a/spec/classes/report_spec.rb b/spec/classes/report_spec.rb
       @@ -228,6 +228,28 @@ describe Simplabs::ReportsAsSparkline::Report do
                      result[6][1].should  == 0.0
                    end
        
       +            it 'should return correct results when run twice with different limits' do
       +              @report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations,
       +                :aggregation => :count,
       +                :grouping    => grouping,
       +                :limit       => 10,
       +                :live_data   => live_data
       +              )
       +              result = @report.run(:limit => 2).to_a
       +
       +              result[2][1].should == 1.0 if live_data
       +              result[1][1].should  == 1.0
       +              result[0][1].should  == 0.0
       +
       +              result = @report.run(:limit => 10).to_a
       +
       +              result[10][1].should == 1.0 if live_data
       +              result[9][1].should  == 1.0
       +              result[8][1].should  == 0.0
       +              result[7][1].should  == 2.0
       +              result[6][1].should  == 0.0
       +            end
       +
                  end
        
                  after(:all) do
 (DIR) diff --git a/spec/db/schema.rb b/spec/db/schema.rb
       @@ -15,6 +15,7 @@ ActiveRecord::Schema.define(:version => 1) do
            t.string   :aggregation,      :null => false
            t.float    :value,            :null => false, :default => 0
            t.datetime :reporting_period, :null => false
       +    t.integer  :run_limit,        :null => false
        
            t.timestamps
          end
       @@ -22,14 +23,16 @@ ActiveRecord::Schema.define(:version => 1) do
            :model_name,
            :report_name,
            :grouping,
       -    :aggregation
       -  ], :name => :name_model_grouping_agregation
       +    :aggregation,
       +    :run_limit
       +  ], :name => :name_model_grouping_agregation_run_limit
          add_index :reports_as_sparkline_cache, [
            :model_name,
            :report_name,
            :grouping,
            :aggregation,
       -    :reporting_period
       -  ], :unique => true, :name => :name_model_grouping_aggregation_period
       +    :reporting_period,
       +    :run_limit
       +  ], :unique => true, :name => :name_model_grouping_aggregation_period_run_limit
        
        end