|
|
class Rrd::Aggregate < ActiveRecord::Base
belongs_to :domain
@@precision = 1.day
def self.last_update(domain_id)
if last = find(:first, :conditions => ['domain_id=?', domain_id], :order => 'time_from desc')
last.time_from
end
end
# Update the aggregate table with any new data.
def self.update(domain_id)
old_count = count(:conditions => ['domain_id=?', domain_id])
name, day_group_string = case @@precision
when 1.day
["concat( year(created_at), '-', dayofyear(created_at) )", "dayofyear(created_at), year(created_at)"]
when 1.week
["concat( year(created_at), '-', week(created_at), 'w')", "year(created_at), week(created_at)"]
else
raise "Precision value not supported"
end
connection.execute("
insert into #{table_name} (timespan, name, value, domain_id, time_from, type)
select '#{@@precision}', #{name}, count(#{aggregate_table}.id), #{domain_id}, DATE_FORMAT(created_at, '%Y%m%d000000'), '#{self.name.split(":")[-1]}'
from #{aggregate_table}
where #{aggregate_table}.domain_id = #{domain_id} and #{aggregate_table}.created_at >= '#{last_update(domain_id)}'
group by dayofyear(created_at), year(created_at)
")
count(:conditions => ['domain_id=?', domain_id]) - old_count
end
def self.find_with_interpolation(what, args = {})
# automagically add to an options hash for find
# todo: extract this to a plugin
args[:conditions] ||= {}
case args[:conditions]
when Hash
args[:conditions].update( :timespan => @@precision )
when Array # assumes there ARE conditions
if args[:conditions][1].is_a?Hash
args[:conditions][0] << " AND timespan = :rrd_timespan"
args[:conditions][1].update :rrd_timespan => @@precision
else
args[:conditions][0] << " AND timespan = ? "
args[:conditions] << @@precision
end
when String
args[:conditions] = [args[:conditions] + " AND timespan = ? ", @@precision]
else
raise "Cannot determine conditions since conditions is #{args[:conditions].inspect}"
end
results = find(what, args)
return if results.empty?
first_result = results.shift
date = first_result.time_from
ret = [ first_result ]
# fill in any empty days with a zero.
results.each do |result|
missing_days = (result.time_from - date - @@precision) / @@precision
missing_days.to_i.times do |i|
new_date = date + (i + 1) * @@precision
logger.warn "Interpolating #{new_date}"
ret << self.new(:time_from => new_date, :name => "#{new_date.year}-#{new_date.yday}", :value => '0', :timespan => @@precision)
end # times
ret << result
date = result.time_from
end # results
ret
end # def
end
|