Cache results even if conditions are given. - reportable - Fork of reportable required by WarVox, from hdm/reportable.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 3259cb4e113ad36fcd708d896622deb54ae9c608
 (DIR) parent 51b49004e197edbced94eb626c6eed58cc7a4e72
 (HTM) Author: Eric Lindvall <eric@5stops.com>
       Date:   Wed, 23 Dec 2009 16:47:50 +0800
       
       Cache results even if conditions are given.
       
       This adds a column to the migration that will need to be added for this plugin
       to work.
       
       Diffstat:
         M generators/reports_as_sparkline_mi… |       5 ++++-
         M lib/simplabs/reports_as_sparkline/… |       5 ++---
         M lib/simplabs/reports_as_sparkline/… |      23 +++++++++++------------
         M spec/classes/report_cache_spec.rb   |      48 ++++++++-----------------------
         M spec/classes/report_spec.rb         |      11 ++++-------
         M spec/db/schema.rb                   |       9 ++++++---
       
       6 files changed, 39 insertions(+), 62 deletions(-)
       ---
 (DIR) diff --git a/generators/reports_as_sparkline_migration/templates/migration.erb b/generators/reports_as_sparkline_migration/templates/migration.erb
       @@ -6,6 +6,7 @@ class <%= class_name %> < ActiveRecord::Migration
              t.string   :report_name,      :null => false
              t.string   :grouping,         :null => false
              t.string   :aggregation,      :null => false
       +      t.string   :condition,        :null => false
              t.float    :value,            :null => false, :default => 0
              t.datetime :reporting_period, :null => false
        
       @@ -16,13 +17,15 @@ class <%= class_name %> < ActiveRecord::Migration
              :model_name,
              :report_name,
              :grouping,
       -      :aggregation
       +      :aggregation,
       +      :condition
            ], :name => :name_model_grouping_agregation
            add_index :reports_as_sparkline_cache, [
              :model_name,
              :report_name,
              :grouping,
              :aggregation,
       +      :condition,
              :reporting_period
            ], :unique => true, :name => :name_model_grouping_aggregation_period
          end
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/report.rb b/lib/simplabs/reports_as_sparkline/report.rb
       @@ -44,13 +44,12 @@ module Simplabs #:nodoc:
              # ==== Options
              # * <tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>, <tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that <tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
              # * <tt>:limit</tt> - The number of reporting periods to get (see <tt>:grouping</tt>), (defaults to 100)
       -      # * <tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>; only records that match the conditions are reported; <b>Beware that when conditions are specified, caching is disabled!</b>
       +      # * <tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>; only records that match the conditions are reported
              # * <tt>:live_data</tt> - Specifies whether data for the current reporting period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to <tt>false</tt>)</b>
              # * <tt>:end_date</tt> - When specified, the report will only include data for the <tt>:limit</tt> reporting periods until this date.
              def run(options = {})
       -        custom_conditions = options.key?(:conditions)
                options = options_for_run(options)
       -        ReportCache.process(self, options, !custom_conditions) do |begin_at, end_at|
       +        ReportCache.process(self, options) do |begin_at, end_at|
                  read_data(begin_at, end_at, options)
                end
              end
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/report_cache.rb b/lib/simplabs/reports_as_sparkline/report_cache.rb
       @@ -30,21 +30,18 @@ module Simplabs #:nodoc:
                })
              end
        
       -      def self.process(report, options, cache = true, &block) #:nodoc:
       +      def self.process(report, options, &block) #:nodoc:
                raise ArgumentError.new('A block must be given') unless block_given?
                self.transaction do
       -          cached_data = []
       -          if cache
       -            cached_data = read_cached_data(report, options)
       -          end
       +          cached_data = read_cached_data(report, options)
                  new_data = read_new_data(cached_data, options, &block)
       -          prepare_result(new_data, cached_data, report, options, cache)
       +          prepare_result(new_data, cached_data, report, options)
                end
              end
        
              private
        
       -        def self.prepare_result(new_data, cached_data, report, options, cache = true)
       +        def self.prepare_result(new_data, cached_data, report, options)
                  new_data = new_data.map { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] }
                  cached_data.map! { |cached| [ReportingPeriod.new(options[:grouping], cached.reporting_period), cached.value] }
                  current_reporting_period = ReportingPeriod.current(options[:grouping])
       @@ -54,8 +51,8 @@ module Simplabs #:nodoc:
                    if cached = cached_data.find { |cached| reporting_period == cached[0] }
                      result << [cached[0].date_time, cached[1]]
                    else
       -              new_cached = build_cached_data(report, options[:grouping], reporting_period, find_value(new_data, reporting_period))
       -              new_cached.save! if cache
       +              new_cached = build_cached_data(report, options[:grouping], options[:conditions], reporting_period, find_value(new_data, reporting_period))
       +              new_cached.save!
                      result << [reporting_period.date_time, new_cached.value]
                    end
                    reporting_period = reporting_period.next
       @@ -71,12 +68,13 @@ 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, condition, 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,
       +            :condition        => condition.to_s,
                    :reporting_period => reporting_period.date_time,
                    :value            => value
                  )
       @@ -84,11 +82,12 @@ module Simplabs #:nodoc:
        
                def self.read_cached_data(report, options)
                  conditions = [
       -            'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ?',
       +            'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND condition = ?',
                    report.klass.to_s,
                    report.name.to_s,
                    options[:grouping].identifier.to_s,
       -            report.aggregation.to_s
       +            report.aggregation.to_s,
       +            options[:conditions].to_s
                  ]
                  first_reporting_period = get_first_reporting_period(options)
                  last_reporting_period = get_last_reporting_period(options)
 (DIR) diff --git a/spec/classes/report_cache_spec.rb b/spec/classes/report_cache_spec.rb
       @@ -122,11 +122,12 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
            it 'should read existing data from the cache' do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:all).once.with(
                :conditions => [
       -          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND reporting_period >= ?',
       +          'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND condition = ? AND reporting_period >= ?',
                  @report.klass.to_s,
                  @report.name.to_s,
                  @report.options[:grouping].identifier.to_s,
                  @report.aggregation.to_s,
       +          @report.options[:conditions].to_s,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 10).date_time
                ],
                :limit => 10,
       @@ -140,11 +141,12 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              end_date = Time.now
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:all).once.with(
                :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 condition = ? AND reporting_period BETWEEN ? AND ?',
                  @report.klass.to_s,
                  @report.name.to_s,
                  @report.options[:grouping].identifier.to_s,
                  @report.aggregation.to_s,
       +          @report.options[:conditions].to_s,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 9).date_time,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.new(@report.options[:grouping], end_date).date_time
                ],
       @@ -160,11 +162,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 condition = ? AND reporting_period >= ?',
                  @report.klass.to_s,
                  @report.name.to_s,
                  grouping.identifier.to_s,
                  @report.aggregation.to_s,
       +          @report.options[:conditions].to_s,
                  Simplabs::ReportsAsSparkline::ReportingPeriod.first(grouping, 10).date_time
                ],
                :limit => 10,
       @@ -181,25 +184,6 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
                []
              end
            end
       -
       -    describe 'with cache = false' do
       -
       -      it 'should not read any data from cache' do
       -        Simplabs::ReportsAsSparkline::ReportCache.should_not_receive(:find)
       -
       -        Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options, false) {}
       -      end
       -
       -      it 'should yield the first reporting period' do
       -        Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options, false) do |begin_at, end_at|
       -          begin_at.should == Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 10).date_time
       -          end_at.should == nil
       -          []
       -        end
       -      end
       -
       -    end
       -
          end
        
          describe '.prepare_result' do
       @@ -217,6 +201,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).exactly(10).times.with(
                @report,
                @report.options[:grouping],
       +        @report.options[:conditions],
                anything(),
                0.0
              ).and_return(@cached)
       @@ -228,12 +213,14 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).exactly(9).times.with(
                @report,
                @report.options[:grouping],
       +        @report.options[:conditions],
                anything(),
                0.0
              ).and_return(@cached)
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).once.with(
                @report,
                @report.options[:grouping],
       +        @report.options[:conditions],
                @current_reporting_period.previous,
                1.0
              ).and_return(@cached)
       @@ -248,7 +235,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
            end
        
            it 'should return an array of arrays of Dates and Floats' do
       -      result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options, true)
       +      result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options)
        
              result.should be_kind_of(Array)
              result[0].should be_kind_of(Array)
       @@ -259,7 +246,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
            describe 'with :live_data = false' do
        
              before do
       -        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options, true)
       +        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options)
              end
        
              it 'should return an array of length :limit' do
       @@ -276,7 +263,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
        
              before do
                options = @report.options.merge(:live_data => true)
       -        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, options, true)
       +        @result = Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, options)
              end
        
              it 'should return an array of length (:limit + 1)' do
       @@ -288,17 +275,6 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
              end
        
            end
       -
       -    describe 'with cache = false' do
       -
       -      it 'should not save the created Simplabs::ReportsAsSparkline::ReportCache' do
       -        @cached.should_not_receive(:save!)
       -
       -        Simplabs::ReportsAsSparkline::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options, false)
       -      end
       -
       -    end
       -
          end
        
          describe '.find_value' do
 (DIR) diff --git a/spec/classes/report_spec.rb b/spec/classes/report_spec.rb
       @@ -21,18 +21,16 @@ describe Simplabs::ReportsAsSparkline::Report do
            it 'should process the data with the report cache' do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:process).once.with(
                @report,
       -        { :limit => 100, :grouping => @report.options[:grouping], :conditions => [], :live_data => false, :end_date => false },
       -        true
       +        { :limit => 100, :grouping => @report.options[:grouping], :conditions => [], :live_data => false, :end_date => false }
              )
        
              @report.run
            end
        
       -    it 'should process the data with the report cache and specify cache = false when custom conditions are given' do
       +    it 'should process the data with the report cache when custom conditions are given' do
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:process).once.with(
                @report,
       -        { :limit => 100, :grouping => @report.options[:grouping], :conditions => { :some => :condition }, :live_data => false, :end_date => false },
       -        false
       +        { :limit => 100, :grouping => @report.options[:grouping], :conditions => { :some => :condition }, :live_data => false, :end_date => false }
              )
        
              @report.run(:conditions => { :some => :condition })
       @@ -49,8 +47,7 @@ describe Simplabs::ReportsAsSparkline::Report do
              Simplabs::ReportsAsSparkline::Grouping.should_receive(:new).once.with(:month).and_return(grouping)
              Simplabs::ReportsAsSparkline::ReportCache.should_receive(:process).once.with(
                @report,
       -        { :limit => 100, :grouping => grouping, :conditions => [], :live_data => false, :end_date => false },
       -        true
       +        { :limit => 100, :grouping => grouping, :conditions => [], :live_data => false, :end_date => false }
              )
        
              @report.run(:grouping => :month)
 (DIR) diff --git a/spec/db/schema.rb b/spec/db/schema.rb
       @@ -13,6 +13,7 @@ ActiveRecord::Schema.define(:version => 1) do
            t.string   :report_name,      :null => false
            t.string   :grouping,         :null => false
            t.string   :aggregation,      :null => false
       +    t.string   :condition,        :null => false
            t.float    :value,            :null => false, :default => 0
            t.datetime :reporting_period, :null => false
        
       @@ -22,14 +23,16 @@ ActiveRecord::Schema.define(:version => 1) do
            :model_name,
            :report_name,
            :grouping,
       -    :aggregation
       -  ], :name => :name_model_grouping_agregation_run_limit
       +    :aggregation,
       +    :condition
       +  ], :name => :name_model_grouping_agregation
          add_index :reports_as_sparkline_cache, [
            :model_name,
            :report_name,
            :grouping,
            :aggregation,
       +    :condition,
            :reporting_period
       -  ], :unique => true, :name => :name_model_grouping_aggregation_period_run_limit
       +  ], :unique => true, :name => :name_model_grouping_aggregation_period
        
        end