Class: Lookout::ComparableQuery::Comparison

Inherits:
Object
  • Object
show all
Defined in:
app/queries/concerns/lookout/comparable_query.rb

Defined Under Namespace

Classes: ComparisonResult

Instance Method Summary collapse

Constructor Details

#initialize(query) ⇒ Comparison

Returns a new instance of Comparison.



12
13
14
15
16
17
18
# File 'app/queries/concerns/lookout/comparable_query.rb', line 12

def initialize(query)
  @query = query
  @params = @query.params.deep_dup
  @compare = @query.class.call(comparison_params)
  @model = @query.all.klass
  @query_class = @query.class
end

Instance Method Details

#average(column_name) ⇒ Object



28
29
30
31
32
33
34
35
# File 'app/queries/concerns/lookout/comparable_query.rb', line 28

def average(column_name)
  @operation = :average
  @column = column_name

  perform_calculations(:average, column_name)

  self
end

#compare_rangeObject



100
101
102
103
104
105
106
# File 'app/queries/concerns/lookout/comparable_query.rb', line 100

def compare_range
  @compare_range ||= begin
                       og_range = range
                       [og_range[0] - (og_range[1] - og_range[0]), og_range[0]]
                     end

end

#count(column_name = :id) ⇒ Object



20
21
22
23
24
25
26
# File 'app/queries/concerns/lookout/comparable_query.rb', line 20

def count(column_name = :id)
  @operation = :count
  @column = column_name
  perform_calculations(:count, column_name)

  self
end

#perform_calculation(q, operation, column_name) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/queries/concerns/lookout/comparable_query.rb', line 42

def perform_calculation(q, operation, column_name)
  operation = operation.to_s.downcase
  # If #count is used with #distinct (i.e. `relation.distinct.count`) it is
  # considered distinct.
  distinct = q.send(:distinct_value)

  if operation == "count"
    column_name ||= q.send(:select_for_count)
    if column_name == :all
      if !distinct
        distinct = q.send(:distinct_select?, :select_for_count) if q.group_values.empty?
      elsif q.send(:group_values).any? || q.send(:select_values).empty? && q.order_values.empty?
        column_name = q.primary_key
      end
    elsif q.all.send(:distinct_select?, column_name)
      distinct = nil
    end
  end

  if q.group_values.any?
    raise "use a subquery"
  else
    execute_simple_calculation(q, operation, column_name, distinct)
  end
end

#perform_calculations(operation, column_name) ⇒ Object



37
38
39
40
# File 'app/queries/concerns/lookout/comparable_query.rb', line 37

def perform_calculations(operation, column_name)
  @query = perform_calculation(@query, operation, column_name)
  @compare = perform_calculation(@compare, operation, column_name)
end

#rangeObject



108
109
110
# File 'app/queries/concerns/lookout/comparable_query.rb', line 108

def range
  @range ||= @query.send(:range)
end

#resultObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/queries/concerns/lookout/comparable_query.rb', line 68

def result
  type = @query_class.cast_type(@column)

  if Lookout::DatabaseAdapter.sqlite?
    # SQLite: Use scalar subselects to avoid selecting bare CTE names
    sql = "SELECT (#{@query.to_sql}) AS current, (#{@compare.to_sql}) AS compare"
    row = @model.find_by_sql(sql).first
    if row
      current = @query_class.cast_value(type, row["current"].to_s)
      compare = @query_class.cast_value(type, row["compare"].to_s)
    else
      current = @query_class.cast_value(type, '0')
      compare = @query_class.cast_value(type, '0')
    end
  else
    result = @model.with(
      current: @query.to_sql,
      compare: @compare.to_sql
    ).select("current, compare").from("current, compare")[0]

    if result
      current = @query_class.cast_value(type, result.current[1...-1])
      compare = @query_class.cast_value(type, result.compare[1...-1])
    else
      current = @query_class.cast_value(type, '0')
      compare = @query_class.cast_value(type, '0')
    end
  end

  @result = ComparisonResult.new((current), (compare))
end