class TailorMade::Query

Constants

CHARTS

Attributes

chart[RW]
dimensions[RW]
measures[RW]
options_for_select[R]
plot_measure[RW]
scope[R]

Public Class Methods

new(attributes={}) click to toggle source
Calls superclass method
# File lib/tailor_made/query.rb, line 23
def initialize(attributes={})
  super
  @dimensions     ||= default_dimensions
  @dimensions       = @dimensions.reject(&:blank?).map(&:to_sym)
  @measures       ||= default_measures
  @measures         = @measures.reject(&:blank?).map(&:to_sym)
  @plot_measure   ||= measures.first

  set_datetime_ranges
end

Public Instance Methods

all() click to toggle source
# File lib/tailor_made/query.rb, line 87
def all
  @scope = build_scope(from, dimensions)
  scope.order(order).select(table_formulas)
end
combination_data(groups, combination) click to toggle source
# File lib/tailor_made/query.rb, line 72
def combination_data(groups, combination)
  # combination.each_with_index.map { |param, index| [groups[index + 1].to_sym , param] }
  scope = from
  combination.each_with_index.each { |param, index|
    scope = scope.where("#{groups[index + 1]} = ?", param)
  }
  plot_dimension = groups[0]
  scope = build_scope(scope, [plot_dimension])
  scope.order(
    { dimension_alias(plot_dimension, scope).to_sym => :asc }
  ).pluck(
    plot_formulas([plot_dimension], scope)
  )
end
from() click to toggle source
# File lib/tailor_made/query.rb, line 34
def from
  fail(NotImplementedError) # required to implement in subclass
end
plot() click to toggle source
# File lib/tailor_made/query.rb, line 60
def plot
  scope = build_scope(from, dimensions)
  result = scope.order(order).pluck(plot_formulas(dimensions, scope))
  return result if dimensions.size < 2
  result.map { |row| row[1...-1] }.uniq.map { |combination|
    {
      name: combination.join("#"),
      data: combination_data(dimension_groups_sorted(dimensions, scope), combination)
    }
  }
end
tabelize(row, column) click to toggle source
# File lib/tailor_made/query.rb, line 101
def tabelize(row, column)
  if self.class.tailor_made_canonical_anchors[column].nil?
    row.send(column)
  else
    if self.class.tailor_made_canonical_anchors[column].respond_to? :call
      self.class.tailor_made_canonical_anchors[column] = self.class.tailor_made_canonical_anchors[column].call
    end
    result = self.class.tailor_made_canonical_anchors[column][row.send(column)]
    result = [row.send(column), result] if result
    result ||= row.send(column)
  end
end
table_columns() click to toggle source
# File lib/tailor_made/query.rb, line 92
def table_columns
  @table_columns ||= begin
    group_values = @scope.group_values.map { |column|
      (column.respond_to? :name) ? group_alias(column) : column
    }
    group_values + measures
  end
end

Private Instance Methods

build_canonical_scope(scope) click to toggle source
# File lib/tailor_made/query.rb, line 128
def build_canonical_scope(scope)
  self.class.tailor_made_canonical_dimensions.each do |dimension|
    next if send(dimension).nil?
    scope = scope.where(
      ':dimension LIKE :pattern',
      dimension: dimension,
      pattern: "%#{send(dimension)}%"
    )
  end
  scope
end
build_datetime_dimension_scope(scope, dimension, dimensions) click to toggle source
# File lib/tailor_made/query.rb, line 149
def build_datetime_dimension_scope(scope, dimension, dimensions)
  starts_at = instance_variable_get("@#{dimension}_starts_at")
  ends_at = instance_variable_get("@#{dimension}_ends_at")
  permit = self.class.tailor_made_measures_datetime_permited[dimension]

  if !starts_at.blank? && !ends_at.blank?
    scope = scope.where(dimension.to_sym => starts_at..ends_at)
  end

  datetime_dimension_periods(dimension, dimensions).each do |datetime_dimension|
    period_type = get_datetime_dimension_period(dimension, datetime_dimension)
    scope = scope.group_by_period(period_type, dimension, permit: permit)
  end
  scope
end
build_datetime_dimensions_scope(scope, dimensions) click to toggle source

Datetime

# File lib/tailor_made/query.rb, line 142
def build_datetime_dimensions_scope(scope, dimensions)
  self.class.tailor_made_datetime_columns.each do |dimension|
    scope = build_datetime_dimension_scope(scope, dimension, dimensions)
  end
  scope
end
build_scope(scope, dimensions) click to toggle source
# File lib/tailor_made/query.rb, line 116
def build_scope(scope, dimensions)
  scope = build_canonical_scope(scope)

  scope = build_datetime_dimensions_scope(scope, dimensions)

  datetime_dimensions = self.class.tailor_made_datetime_dimensions.values().flatten
  unless (dimensions - datetime_dimensions).empty?
    scope = scope.group(dimensions - datetime_dimensions)
  end
  scope
end
datetime_dimension_periods(datetime_dimension, dimensions) click to toggle source
# File lib/tailor_made/query.rb, line 165
def datetime_dimension_periods(datetime_dimension, dimensions)
  dimensions.select { |dimension|
    self.class.tailor_made_datetime_dimensions[datetime_dimension].include?(dimension)
  }
end
default_range_end(period) click to toggle source
# File lib/tailor_made/query.rb, line 247
def default_range_end(period)
  case period
  when :second
    Time.now.utc
  when :minute
    Time.now.utc
  when :hour
    Time.now.utc
  when :day
    Time.now.utc.to_date
  when :week
    Time.now.utc.to_date
  when :month
    Time.now.utc.to_date
  when :quarter
    Time.now.utc.to_date
  when :year
    Time.now.utc.to_date
  when :day_of_week
    Time.now.utc.to_date
  when :hour_of_day
    Time.now.utc.to_date
  when :minute_of_hour
    Time.now.utc.to_date
  when :day_of_month
    Time.now.utc.to_date
  when :month_of_year
    Time.now.utc.to_date
  else
    nil
  end
end
default_range_start(period) click to toggle source
# File lib/tailor_made/query.rb, line 214
def default_range_start(period)
  case period
  when :second
    Time.now.utc.to_date.beginning_of_day
  when :minute
    Time.now.utc.to_date.beginning_of_day
  when :hour
    Time.now.utc.to_date.beginning_of_day
  when :day
    Time.now.utc.to_date.beginning_of_week
  when :week
    Time.now.utc.to_date.beginning_of_month
  when :month
    Time.now.utc.to_date.beginning_of_year
  when :quarter
    Time.now.utc.to_date.beginning_of_year
  when :year
    Time.now.utc.to_date.beginning_of_year - 5.years
  when :day_of_week
    Time.now.utc.to_date.beginning_of_week
  when :hour_of_day
    Time.now.utc.to_date.beginning_of_day
  when :minute_of_hour
    Time.now.utc.to_date.beginning_of_day
  when :day_of_month
    Time.now.utc.to_date.beginning_of_month
  when :month_of_year
    Time.now.utc.to_date.beginning_of_year
  else
    nil
  end
end
dimension_alias(dimension, scope) click to toggle source
# File lib/tailor_made/query.rb, line 294
def dimension_alias(dimension, scope)
  group = find_group(dimension, scope.group_values)
  if group.respond_to? :name
    group_alias(group)
  else
    group
  end
end
dimension_groups_sorted(dimensions, scope) click to toggle source
# File lib/tailor_made/query.rb, line 313
def dimension_groups_sorted(dimensions, scope)
  dimensions.map do |dimension|
    find_group(dimension, scope.group_values)
  end
end
dimensions_formulas(groups) click to toggle source
# File lib/tailor_made/query.rb, line 303
def dimensions_formulas(groups)
  groups.map { |group|
    if group.respond_to? :name
      "#{group} AS #{group_alias(group)}"
    else
      group
    end
  }
end
find_group(dimension, groups) click to toggle source
# File lib/tailor_made/query.rb, line 335
def find_group(dimension, groups)
  groups.find {|group|
    dimension == group ||
      (
        group.respond_to?(:name) &&
        dimension == group.name.to_sym
      )
  }
end
get_datetime_dimension_period(dimension, datetime_dimension) click to toggle source
# File lib/tailor_made/query.rb, line 171
def get_datetime_dimension_period(dimension, datetime_dimension)
  datetime_dimension.to_s.reverse.chomp((dimension.to_s + "_").reverse).reverse.to_sym
end
group_alias(group) click to toggle source
# File lib/tailor_made/query.rb, line 289
def group_alias(group)
  aliaz = "#{group.relation.name}.#{group.name}"
  scope.connection.table_alias_for(aliaz)
end
measure_formulas(measures) click to toggle source
# File lib/tailor_made/query.rb, line 329
def measure_formulas(measures)
  measures.map { |measure|
    [self.class.tailor_made_measure_formula[measure], measure].join(" AS ")
  }
end
order(scope = @scope) click to toggle source

Order and selects

# File lib/tailor_made/query.rb, line 282
def order(scope = @scope)
  col = scope.group_values.map { |column|
    (column.respond_to? :name) ? group_alias(column) : column
  }.first
  { col.to_sym => :asc }
end
plot_formulas(dimensions, scope) click to toggle source
# File lib/tailor_made/query.rb, line 319
def plot_formulas(dimensions, scope)
  groups = dimension_groups_sorted(dimensions, scope)
  (dimensions_formulas(groups) + measure_formulas([plot_measure.to_sym]))
end
set_datetime_default(dimension) click to toggle source
# File lib/tailor_made/query.rb, line 201
def set_datetime_default(dimension)
  starts_at_options = datetime_dimension_periods(dimension, dimensions).map do |period|
    default_range_start(dimension)
  end

  ends_at_options = datetime_dimension_periods(dimension, dimensions).map do |period|
    default_range_start(dimension)
  end

  instance_variable_set("@#{dimension}_starts_at", starts_at_options.min)
  instance_variable_set("@#{dimension}_ends_at", ends_at_options.max)
end
set_datetime_range(dimension) click to toggle source
# File lib/tailor_made/query.rb, line 181
def set_datetime_range(dimension)
  starts_at = "@#{dimension}_starts_at"
  ends_at = "@#{dimension}_ends_at"

  instance_variable_set(
    starts_at,
    Date.parse(instance_variable_get(starts_at))
  ) unless instance_variable_get(starts_at).blank?

  instance_variable_set(
    ends_at,
    Date.parse(instance_variable_get(ends_at))
  ) unless instance_variable_get(ends_at).blank?

  return unless instance_variable_get(starts_at).blank?
  return unless instance_variable_get(ends_at).blank?
  return if datetime_dimension_periods(dimension, dimensions).empty?
  set_datetime_default(dimension)
end
set_datetime_ranges() click to toggle source
# File lib/tailor_made/query.rb, line 175
def set_datetime_ranges
  self.class.tailor_made_datetime_columns.each do |dimension|
    set_datetime_range(dimension)
  end
end
table_formulas() click to toggle source
# File lib/tailor_made/query.rb, line 324
def table_formulas
  groups = dimension_groups_sorted(dimensions, scope)
  (dimensions_formulas(groups) + measure_formulas(measures))
end