Module: ArAggregateByInterval::Utils

Extended by:
Utils
Included in:
Utils
Defined in:
lib/ar_aggregate_by_interval/utils.rb

Constant Summary collapse

DATE_ITERATOR_METHOD_MAP =
{
  'monthly' => 'each_month_until',
  'weekly' => 'each_week_until',
  'daily' => 'each_day_until'
}

Instance Method Summary collapse

Instance Method Details

#ar_to_hash(ar_result, mapping) ⇒ Object



43
44
45
46
47
48
# File 'lib/ar_aggregate_by_interval/utils.rb', line 43

def ar_to_hash(ar_result, mapping)
  ar_result.to_a.inject({}) do |memo, ar_obj|
    mapping.each { |key, val| memo.merge!(ar_obj.send(key) => ar_obj.send(val)) }
    memo
  end
end

#args_to_hash(sum_or_count, daily_weekly_monthly, *args) ⇒ Object

support legacy arguments (as opposed to direct hash) can do: ArModel.count_weekly(:group_by_col, :from, :to, :return_dates_bool) ArModel.count_weekly(:from, :to, :return_dates_bool) # defaults to :created_at or ArModel.sum_weekly(:group_by_col, :aggregate_col, :from, :to, :return_dates_bool)



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ar_aggregate_by_interval/utils.rb', line 18

def args_to_hash(sum_or_count, daily_weekly_monthly, *args)
  group_by_column, aggregate_column, from, to, return_dates = args

  group_by_column ||= 'created_at'
  return_dates ||= false

  if sum_or_count == 'count'
    if aggregate_column.present? && (aggregate_column.is_a?(Date) || aggregate_column.is_a?(Time))
      return_dates = to
      to = from
      from = aggregate_column
      aggregate_column = nil
    end
  elsif sum_or_count != 'count' && aggregate_column.nil? || !(aggregate_column.is_a?(String) || aggregate_column.is_a?(Symbol))
    raise "aggregate_column cant be nil with #{sum_or_count}"
  end

  return {
    group_by_column: group_by_column,
    from: from,
    to: to,
    aggregate_column: aggregate_column
  }.delete_if { |k, v| v.nil? }
end

#db_vendorObject



84
85
86
87
88
# File 'lib/ar_aggregate_by_interval/utils.rb', line 84

def db_vendor
  @db_vendor ||=
    ActiveRecord::Base.connection_config.try(:symbolize_keys).try(:[], :adapter) ||
    ENV['DATABASE_URL']
end

#interval_inflector(interval, beg_or_end) ⇒ Object

converts args like: [weekly, beginning] to beginning_of_week



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ar_aggregate_by_interval/utils.rb', line 91

def interval_inflector(interval, beg_or_end)
  raise "beginning or end, not #{beg_or_end}" unless beg_or_end.match(/\A(beginning|end)\z/)

  time_interval = {
    'monthly' => 'month',
    'weekly' => 'week',
    'daily' => 'day'
  }[interval] || raise("unknown interval #{interval}")

  "#{beg_or_end}_of_#{time_interval}"
end

#ruby_strftime_mapObject



50
51
52
53
54
55
56
57
# File 'lib/ar_aggregate_by_interval/utils.rb', line 50

def ruby_strftime_map
  @ruby_strftime_map ||= {
    'monthly' => '%Y-%m',
    # sqlite doesn't support ISO weeks
    'weekly' => Utils.db_vendor.match(/sqlite/i) ? '%Y-%U' : '%G-%V',
    'daily' => '%F'
  }
end

#select_for_grouping_column(grouping_col) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ar_aggregate_by_interval/utils.rb', line 59

def select_for_grouping_column(grouping_col)
  case db_vendor
  when /mysql/i
    {
      'monthly' => "date_format(#{grouping_col}, '%Y-%m')",
      'weekly' => "date_format(#{grouping_col}, '%x-%v')",
      'daily' => "date(#{grouping_col})"
    }
  when /postgres/i
    {
      'monthly' => "to_char(#{grouping_col}, 'YYYY-MM')",
      'weekly' => "to_char(#{grouping_col}, 'IYYY-IW')",
      'daily' => "date(#{grouping_col})"
    }
  when /sqlite/i
    {
      'monthly' => "strftime('%Y-%m', #{grouping_col})",
      'weekly' => "strftime('%Y-%W', #{grouping_col})", # sqlite doesn't support ISO weeks
      'daily' => "date(#{grouping_col})"
    }
  else
    raise "unknown database vendor #{db_vendor}"
  end
end

#to_f_or_i_or_s(v) ⇒ Object



103
104
105
# File 'lib/ar_aggregate_by_interval/utils.rb', line 103

def to_f_or_i_or_s(v)
  ((float = Float(v)) && (float % 1.0 == 0) ? float.to_i : float) rescue v
end