class Compendium::Query

Attributes

filters[R]
metrics[R]
name[R]
options[RW]
proc[RW]
report[RW]
results[R]
table_settings[RW]

Public Class Methods

new(*args) click to toggle source
# File lib/compendium/query.rb, line 13
def initialize(*args)
  @report = args.shift if arg_is_report?(args.first)

  raise ArgumentError, "wrong number of arguments (#{args.size + (@report ? 1 : 0)} for 3..4)" unless args.size == 3

  @name, @options, @proc = args
  @metrics = ::Collection[Metric]
  @filters = ::Collection[Proc]
end

Public Instance Methods

add_filter(filter) click to toggle source
# File lib/compendium/query.rb, line 52
def add_filter(filter)
  @filters << filter
end
add_metric(name, proc, options = {}) click to toggle source
# File lib/compendium/query.rb, line 48
def add_metric(name, proc, options = {})
  Compendium::Metric.new(name, self.name, proc, options).tap { |m| @metrics << m }
end
chart(template, *options, &block) click to toggle source

Allow access to the chart object without having to explicitly render it

# File lib/compendium/query.rb, line 65
def chart(template, *options, &block)
  # Access the actual chart object
  Compendium::Presenters::Chart.new(template, self, *options, &block)
end
empty?() click to toggle source

A query is empty if it has no results

# File lib/compendium/query.rb, line 87
def empty?
  results.blank?
end
has_run?()
Alias for: ran?
initialize_clone(*) click to toggle source
Calls superclass method
# File lib/compendium/query.rb, line 23
def initialize_clone(*)
  super
  @metrics = @metrics.clone
  @filters = @filters.clone
end
nil?() click to toggle source

A query is nil if it has no proc

# File lib/compendium/query.rb, line 82
def nil?
  proc.nil?
end
ran?() click to toggle source
# File lib/compendium/query.rb, line 76
def ran?
  !@results.nil?
end
Also aliased as: has_run?
render_chart(template, *options, &block) click to toggle source
# File lib/compendium/query.rb, line 70
def render_chart(template, *options, &block)
  # A query can be rendered regardless of if it has data or not
  # Rendering a chart with no result set builds a chart scaffold which can be updated through AJAX
  chart(template, *options, &block).render
end
render_csv(&block) click to toggle source
# File lib/compendium/query.rb, line 60
def render_csv(&block)
  Compendium::Presenters::CSV.new(self, &block).render unless empty?
end
render_table(template, *options, &block) click to toggle source
# File lib/compendium/query.rb, line 56
def render_table(template, *options, &block)
  Compendium::Presenters::Table.new(template, self, *options, &block).render unless empty?
end
run(params, context = self) click to toggle source
# File lib/compendium/query.rb, line 29
def run(params, context = self)
  if report.is_a?(Class)
    # If running a query directly from a class rather than an instance, the class's query should
    # not be affected/modified, so run the query without a reference back to the report.
    # Otherwise, if the class is subsequently instantiated, the instance will already have results.
    dup.tap{ |q| q.report = nil }.run(params, context)
  else
    collect_results(context, params)
    collect_metrics(context)

    @results
  end
end
url(params = {}) click to toggle source

Get a URL for this query (format: :json set by default)

# File lib/compendium/query.rb, line 44
def url(params = {})
  report.url(params.merge(query: self.name))
end

Private Instance Methods

arg_is_report?(arg) click to toggle source
# File lib/compendium/query.rb, line 148
def arg_is_report?(arg)
  arg.is_a?(Report) || (arg.is_a?(Class) && arg < Report)
end
collect_metrics(context) click to toggle source
# File lib/compendium/query.rb, line 102
def collect_metrics(context)
  metrics.each{ |m| m.run(context, results) } unless results.empty?
end
collect_results(context, *params) click to toggle source
# File lib/compendium/query.rb, line 93
def collect_results(context, *params)
  command = context.instance_exec(*params, &proc) if proc
  command = order_command(command) if options[:order]

  results = fetch_results(command)
  results = filter_results(results, *params) if filters.any?
  @results = ResultSet.new(results) if results
end
execute_command(command) click to toggle source
# File lib/compendium/query.rb, line 138
def execute_command(command)
  return [] if command.nil?
  command = command.to_sql if command.respond_to?(:to_sql)
  execute_query(command)
end
execute_query(command) click to toggle source
# File lib/compendium/query.rb, line 144
def execute_query(command)
  ::ActiveRecord::Base.connection.select_all(command)
end
fetch_results(command) click to toggle source
# File lib/compendium/query.rb, line 106
def fetch_results(command)
  (options.fetch(:collect, nil) == :active_record) ? command : execute_command(command)
end
filter_results(results, params) click to toggle source
# File lib/compendium/query.rb, line 110
def filter_results(results, params)
  return unless results

  if results.respond_to? :with_indifferent_access
    results = results.with_indifferent_access
  else
    results.map! &:with_indifferent_access
  end

  filters.each do |f|
    if f.arity == 2
      results = f.call(results, params)
    else
      results = f.call(results)
    end
  end

  results
end
get_associated_query(query) click to toggle source
# File lib/compendium/query.rb, line 152
def get_associated_query(query)
  query.is_a?(Query) ? query : report.queries[query]
end
order_command(command) click to toggle source
# File lib/compendium/query.rb, line 130
def order_command(command)
  return command unless command.respond_to?(:order)

  command = command.order(options[:order])
  command = command.reverse_order if options.fetch(:reverse, false)
  command
end