diff --git a/lib/report/result.rb b/lib/report/result.rb index 5b34fc3a48..97ee2773a1 100644 --- a/lib/report/result.rb +++ b/lib/report/result.rb @@ -31,6 +31,24 @@ class Report::Result fields[key] end + ## + # Override if you want to influence the result grouping. + # + # @return A value for grouping or nil if the given field should + # not be considered for grouping. + def map_group_by_value(key, value) + value + end + + ## + # This method is called when this result is requested as #grouped_by something + # just before the result is returned. + # + # @param data This result's grouped data. + def group_by_data_ready(data) + # good to know! + end + def grouped_by(fields, type, important_fields = []) @grouped_by ||= {} list = begin @@ -40,8 +58,12 @@ class Report::Result data = group_by do |entry| # index for group is a hash # i.e. { :foo => 10, :bar => 20 } <= this is just the KEY!!!! - fields.inject({}) { |hash, key| hash.merge key => entry.fields[key] } + fields.inject({}) do |hash, key| + val = map_group_by_value(key, entry.fields[key]) + hash.merge key => val + end end + group_by_data_ready(data) # map group back to array, all fields with same key get grouped into one list data.keys.map { |f| engine::Result.new data[f], f, type, important_fields } end diff --git a/lib/report/sql_statement.rb b/lib/report/sql_statement.rb index 5062937c35..07e98d3b11 100644 --- a/lib/report/sql_statement.rb +++ b/lib/report/sql_statement.rb @@ -175,7 +175,7 @@ class Report::SqlStatement return(@select || default_select) if fields.empty? (@select ||= []).tap do @sql = nil - fields.each do |f| + fields.reject {|f| never_select.include? f}.each do |f| case f when Array if f.size == 2 and f.first.respond_to? :table_name then select field_name_for(f) @@ -193,6 +193,22 @@ class Report::SqlStatement end end + def unselect(*fields) + @sql = nil + @select = @select.reject do |field| + fields.find { |f| f == field } + end + end + + def never_select(*fields) + (@never_select ||= []).tap do + unless fields.empty? + @never_select += fields + unselect *fields + end + end + end + ## # Return the names which have been bound through select statements # @return [Array] All fields for select part @@ -210,7 +226,7 @@ class Report::SqlStatement def group_by(*fields) @sql = nil unless fields.empty? (@group_by ||= []).tap do - fields.each do |e| + fields.reject {|f| never_group_by.include? f}.each do |e| if e.is_a? Array and (e.size != 2 or !e.first.respond_to? :table_name) group_by(*e) else @@ -221,6 +237,22 @@ class Report::SqlStatement end end + def group_not_by(*fields) + @sql = nil + @group_by = @group_by.reject do |field| + fields.find { |f| f == field } + end + end + + def never_group_by(*fields) + (@never_group_by ||= []).tap do + unless fields.empty? + @never_group_by += fields + group_not_by *fields + end + end + end + ## # @return [TrueClass, FalseClass] Whether or not to add a group by part. def group_by?