Merge pull request #22 from upstartmobile/distinct - reportable - Fork of reportable required by WarVox, from hdm/reportable.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit e84698645f207ecd889c79b76af56188b3456f24
 (DIR) parent 0e804fa4eb8a5092c1e4f0d04094c5828b2c3a93
 (HTM) Author: Martin Kvlr <martin@sauspiel.de>
       Date:   Thu, 10 Jan 2013 01:41:05 -0800
       
       Merge pull request #22 from upstartmobile/distinct
       
       Add :distinct boolean to use DISTINCT counts
       Diffstat:
         M lib/saulabs/reportable/report.rb    |       4 +++-
         M spec/classes/report_spec.rb         |      32 ++++++++++++++++++++++++-------
         M spec/db/schema.rb                   |       1 +
       
       3 files changed, 29 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/lib/saulabs/reportable/report.rb b/lib/saulabs/reportable/report.rb
       @@ -68,6 +68,7 @@ module Saulabs
                @value_column = (options[:value_column] || (@aggregation == :count ? 'id' : name)).to_s
                @options = {
                  :limit      => options[:limit] || 100,
       +          :distinct   => options[:distinct] || false,
                  :conditions => options[:conditions] || [],
                  :grouping   => Grouping.new(options[:grouping] || :day),
                  :live_data  => options[:live_data] || false,
       @@ -118,6 +119,7 @@ module Saulabs
                  @klass.send(@aggregation,
                    @value_column,
                    :conditions => conditions,
       +            :distinct   => options[:distinct],
                    :group      => options[:grouping].to_sql(@date_column),
                    :order      => "#{options[:grouping].to_sql(@date_column)} ASC",
                    :limit      => options[:limit]
       @@ -145,7 +147,7 @@ module Saulabs
                  case context
                    when :initialize
                      options.each_key do |k|
       -                raise ArgumentError.new("Invalid option #{k}!") unless [:limit, :aggregation, :grouping, :date_column, :value_column, :conditions, :live_data, :end_date].include?(k)
       +                raise ArgumentError.new("Invalid option #{k}!") unless [:limit, :aggregation, :grouping, :distinct, :date_column, :value_column, :conditions, :live_data, :end_date].include?(k)
                      end
                      raise ArgumentError.new("Invalid aggregation #{options[:aggregation]}!") if options[:aggregation] && ![:count, :sum, :maximum, :minimum, :average].include?(options[:aggregation])
                      raise ArgumentError.new('The name of the column holding the value to sum has to be specified for aggregation :sum!') if [:sum, :maximum, :minimum, :average].include?(options[:aggregation]) && !options.key?(:value_column)
 (DIR) diff --git a/spec/classes/report_spec.rb b/spec/classes/report_spec.rb
       @@ -21,7 +21,7 @@ describe Saulabs::Reportable::Report do
            it 'should process the data with the report cache' do
              Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
                @report,
       -        { :limit => 100, :grouping => @report.options[:grouping], :conditions => [], :live_data => false, :end_date => false }
       +        { :limit => 100, :grouping => @report.options[:grouping], :conditions => [], :live_data => false, :end_date => false, :distinct => false }
              )
        
              @report.run
       @@ -30,7 +30,7 @@ describe Saulabs::Reportable::Report do
            it 'should process the data with the report cache when custom conditions are given' do
              Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
                @report,
       -        { :limit => 100, :grouping => @report.options[:grouping], :conditions => { :some => :condition }, :live_data => false, :end_date => false }
       +        { :limit => 100, :grouping => @report.options[:grouping], :conditions => { :some => :condition }, :live_data => false, :end_date => false, :distinct => false }
              )
        
              @report.run(:conditions => { :some => :condition })
       @@ -47,7 +47,7 @@ describe Saulabs::Reportable::Report do
              Saulabs::Reportable::Grouping.should_receive(:new).once.with(:month).and_return(grouping)
              Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
                @report,
       -        { :limit => 100, :grouping => grouping, :conditions => [], :live_data => false, :end_date => false }
       +        { :limit => 100, :grouping => grouping, :conditions => [], :live_data => false, :end_date => false, :distinct => false }
              )
        
              @report.run(:grouping => :month)
       @@ -71,10 +71,10 @@ describe Saulabs::Reportable::Report do
              describe "for grouping :#{grouping.to_s}" do
        
                before(:all) do
       -          User.create!(:login => 'test 1', :created_at => Time.now,                    :profile_visits => 2)
       -          User.create!(:login => 'test 2', :created_at => Time.now - 1.send(grouping), :profile_visits => 1)
       -          User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 2)
       -          User.create!(:login => 'test 4', :created_at => Time.now - 3.send(grouping), :profile_visits => 3)
       +          User.create!(:login => 'test 1', :created_at => Time.now,                    :profile_visits => 2, :sub_type => "red")
       +          User.create!(:login => 'test 2', :created_at => Time.now - 1.send(grouping), :profile_visits => 1, :sub_type => "red")
       +          User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 2, :sub_type => "blue")
       +          User.create!(:login => 'test 4', :created_at => Time.now - 3.send(grouping), :profile_visits => 3, :sub_type => "blue")
                end
        
                describe 'optimized querying with contiguously cached data' do
       @@ -299,6 +299,24 @@ describe Saulabs::Reportable::Report do
                      result[6][1].should  == 0.0
                    end
        
       +            it 'should return correct data for aggregation :count with distinct: true' do
       +              @report = Saulabs::Reportable::Report.new(User, :registrations,
       +                :aggregation => :count,
       +                :grouping    => grouping,
       +                :value_column => :sub_type,
       +                :distinct    => true,
       +                :limit       => 10,
       +                :live_data   => live_data
       +              )
       +              result = @report.run.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  == 1.0
       +              result[6][1].should  == 0.0
       +            end
       +
                    it 'should return correct data for aggregation :sum' do
                      @report = Saulabs::Reportable::Report.new(User, :registrations,
                        :aggregation  => :sum,
 (DIR) diff --git a/spec/db/schema.rb b/spec/db/schema.rb
       @@ -4,6 +4,7 @@ ActiveRecord::Schema.define(:version => 1) do
            t.string  :login,          :null => false
            t.integer :profile_visits, :null => false, :default => 0
            t.string  :type,           :null => false, :default => 'User'
       +    t.string  :sub_type
        
            t.timestamps
          end