module RubyReportable::Report
Attributes
data_source[RW]
filters[RW]
records_returned[RW]
Public Instance Methods
_convert_for_sort(value)
click to toggle source
# File lib/ruby_reportable/report.rb, line 174 def _convert_for_sort(value) case value.class when NilClass value.to_s when Date, DateTime, Time value when Array value.map {|sub| _convert_for_sort(sub)} else value.to_s end end
_data(sandbox, options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 143 def _data(sandbox, options = {}) _filter(@filters, sandbox, options) end
_filter(filters, original_sandbox, options)
click to toggle source
# File lib/ruby_reportable/report.rb, line 117 def _filter(filters, original_sandbox, options) # sort filters by priority then apply to sandbox filters.sort_by do |filter_name, filter| filter[:priority] end.inject(original_sandbox) do |sandbox, (filter_name, filter)| # find input for given filter sandbox[:input] = options[:input][filter[:key]] if options[:input].is_a?(Hash) if filter[:valid].nil? || sandbox.instance_eval(&filter[:valid]) if filter[:logic].nil? sandbox else sandbox.build(:source, filter[:logic]) end else sandbox end end end
_finalize(sandbox, options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 147 def _finalize(sandbox, options = {}) if @finalize.nil? sandbox else sandbox[:inputs] = options[:input] || {} sandbox.build(:source, @finalize) end end
_group(group, data, options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 197 def _group(group, data, options = {}) # Run through elements in data which are ordered # from the previous call to #_sort via #run # # Since the elements are already sorted, as we pop # them into their grouping they will remain sorted as # intended # if group.to_s.empty? {:results => data} else group = [group] unless group.is_a?(Array) group.map!(&:to_s) # the last group critieria should contain an array # so lets pop it off for special use last_group = group.pop data.inject({}) do |hash, element| # grab a local reference to the hash ref = hash # run through initial groupings to grab local ref # and default them to {} group.map do |grouping| key = element[grouping] ref[key] ||= {} ref = ref[key] end # handle our last grouping key = element[last_group] ref[key] ||= [] ref[key] << element hash end end end
_output(source_data, options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 156 def _output(source_data, options = {}) # build sandbox for building outputs sandbox = RubyReportable::Sandbox.new(:meta => @meta, :inputs => options[:input] || {}, @data_source[:as] => nil) source_data.inject([]) do |rows, element| # fill sandbox with data element sandbox[@data_source[:as]] = element # grab outputs rows << @outputs.inject({}) do |row, output| row[output.name] = sandbox.instance_eval(&output.logic) row end rows end end
_sort(sort, data, options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 187 def _sort(sort, data, options = {}) if sort.to_s.empty? data else sort = [sort] unless sort.is_a?(Array) data.sort_by {|element| sort.map {|column| _convert_for_sort(element[column]) }} end end
_source(options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 138 def _source(options = {}) # build sandbox for getting the data RubyReportable::Sandbox.new(:meta => @meta, :source => @data_source[:logic], :inputs => options[:input] || {}, :input => nil) end
allow_group(string = nil)
click to toggle source
# File lib/ruby_reportable/report.rb, line 59 def allow_group(string = nil) if string.nil? @allow_group else @allow_group = string end end
allow_sort(string = nil)
click to toggle source
# File lib/ruby_reportable/report.rb, line 67 def allow_sort(string = nil) if string.nil? @allow_sort else @allow_sort = string end end
benchmark(name) { || ... }
click to toggle source
# File lib/ruby_reportable/report.rb, line 26 def benchmark(name) benchmarks[name] ||= 0.0 @result = nil time = Benchmark.realtime do @result = yield end benchmarks[name] += time @result end
benchmarks()
click to toggle source
:sandbox, :filters, :finalize, :output, :group, :sort
# File lib/ruby_reportable/report.rb, line 22 def benchmarks @benchmarks ||= {} end
category(string = nil)
click to toggle source
# File lib/ruby_reportable/report.rb, line 75 def category(string = nil) if string.nil? @category else @category = string end end
clear()
click to toggle source
# File lib/ruby_reportable/report.rb, line 8 def clear @outputs = [] @filters = {} @data_source = nil @report = self.to_s @category = 'Reports' @allow_group = true @allow_sort = true @meta = {} @benchmarks = {} @records_returned = 0 end
filter(name, &block)
click to toggle source
# File lib/ruby_reportable/report.rb, line 88 def filter(name, &block) @filters[name] = RubyReportable::Filter.new(name) @filters[name].instance_eval(&block) end
finalize(&block)
click to toggle source
# File lib/ruby_reportable/report.rb, line 93 def finalize(&block) @finalize = block end
meta(key, value = nil, &block)
click to toggle source
# File lib/ruby_reportable/report.rb, line 39 def meta(key, value = nil, &block) if block_given? @meta[key] = block else if value.nil? @meta[key] else @meta[key] = value end end end
output(name, options = {}, &block)
click to toggle source
# File lib/ruby_reportable/report.rb, line 97 def output(name, options = {}, &block) @outputs << RubyReportable::Output.new(name, options, block) end
outputs(hidden = false)
click to toggle source
methods you shouldn't use inside the blocks
# File lib/ruby_reportable/report.rb, line 105 def outputs(hidden = false) if hidden @outputs else @outputs.select {|output| output[:hidden] != true} end end
report(string = nil)
click to toggle source
# File lib/ruby_reportable/report.rb, line 51 def report(string = nil) if string.nil? @report else @report = string end end
run(options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 237 def run(options = {}) options = {:input => {}}.merge(options) # initial sandbox sandbox = benchmark(:sandbox) do _source(options) end # apply filters to source filtered_sandbox = benchmark(:filters) do _data(sandbox, options) end # finalize raw data from source source_data = benchmark(:finalize) do _finalize(filtered_sandbox, options).source end # {:default => [{outputs => values}] data = benchmark(:output) do _output(source_data, options) end # now that we have all of our data go ahead and cache the size records_returned = data.size # sort the data first cause that makes sense you know sorted = benchmark(:sort) do _sort(options[:sort], data, options) end # transform into {group => {group => [outputs => values]}} # level of grouping depends on how many groups are passed in benchmark(:group) do _group(options[:group], sorted, options) end end
source(&block)
click to toggle source
# File lib/ruby_reportable/report.rb, line 83 def source(&block) @data_source = RubyReportable::Source.new @data_source.instance_eval(&block) end
useable_filters(scope)
click to toggle source
# File lib/ruby_reportable/report.rb, line 113 def useable_filters(scope) @filters.values.select {|filter| !filter[:input].nil? && (filter[:use].nil? || filter[:use].call(scope))}.sort_by {|filter| filter[:priority].to_i} end
valid?(options = {})
click to toggle source
# File lib/ruby_reportable/report.rb, line 275 def valid?(options = {}) options = {:input => {}}.merge(options) errors = [] # initial sandbox sandbox = _source(options) # add in inputs sandbox[:inputs] = options[:input] validity = @filters.map do |filter_name, filter| # find input for given filter sandbox[:input] = options[:input][filter[:key]] if options[:input].is_a?(Hash) filter_validity = filter[:valid].nil? || sandbox.instance_eval(&filter[:valid]) if filter_validity == false # Ignore an empty filter unless it's required if !sandbox[:input].to_s.blank? errors << "#{filter_name} is invalid." false else if sandbox[:input].to_s.blank? && !filter[:require].blank? errors << "#{filter_name} is required." false else true end end elsif filter_validity == true if sandbox[:input].to_s.blank? && !filter[:require].blank? errors << "#{filter_name} is required." false else true end elsif !filter_validity.nil? && !filter_validity[:status].nil? && filter_validity[:status] == false # Ignore an empty filter unless it's required or the error is forced. if !sandbox[:input].to_s.blank? || filter_validity[:force_error] == true errors << filter_validity[:errors] false else if sandbox[:input].to_s.blank? && !filter[:require].blank? errors << "#{filter_name} is required." false else true end end end end return {:status => !validity.include?(false), :errors => errors} end