# encoding: UTF-8 require 'mauve/datamapper' require 'mauve/alert' require 'log4r' module Mauve class AlertHistory include DataMapper::Resource property :alert_id, Integer, :key => true property :history_id, Integer, :key => true belongs_to :alert belongs_to :history after :destroy, :remove_unreferenced_histories def self.migrate! # # This copies the alert IDs from the old History table to the new AlertHistories thing, but only if there are no AertHistories # and some Histories # if AlertHistory.last.nil? and not History.last.nil? # # This is horrid. FIXME! # history_schema = '"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "type" VARCHAR(50) DEFAULT \'unknown\' NOT NULL, "event" TEXT DEFAULT \'Nothing set\' NOT NULL, "created_at" TIMESTAMP NOT NULL' history_cols = 'id, type, event, created_at' ## # Now adjust the Histories table to remove its alert_id col # ["BEGIN TRANSACTION;", "INSERT INTO mauve_alert_histories (alert_id, history_id) SELECT alert_id, id FROM mauve_histories;", "CREATE TEMPORARY TABLE mauve_histories_backup( #{history_schema} );", "INSERT INTO mauve_histories_backup SELECT #{history_cols} FROM mauve_histories;", "DROP TABLE mauve_histories;", "CREATE TABLE mauve_histories( #{history_schema} );", "INSERT INTO mauve_histories SELECT #{history_cols} FROM mauve_histories_backup;", "DROP TABLE mauve_histories_backup;", "COMMIT;"].each do |statement| repository(:default).adapter.execute(statement) end end end private def remove_unreferenced_histories self.history.destroy unless self.history.alerts.count > 0 end end class History include DataMapper::Resource # so .first always returns the most recent update default_scope(:default).update(:order => [:created_at.desc, :id.desc]) # # If these properties change.. then the migration above will break horribly. FIXME. # property :id, Serial property :type, String, :required => true, :default => "unknown", :lazy => false property :event, Text, :required => true, :default => "Nothing set", :lazy => false property :created_at, Time, :required => true has n, :alerts, :through => :alerthistory before :valid?, :set_created_at before :save, :do_sanitize_html protected # # This cleans the HTML before saving. # def do_sanitize_html html_permitted_in = [:event] attributes.each do |key, val| next if html_permitted_in.include?(key) next unless val.is_a?(String) attribute_set(key, Alert.remove_html(val)) end html_permitted_in.each do |key| val = attribute_get(key) next unless val.is_a?(String) attribute_set(key, Alert.clean_html(val)) end end def set_created_at(context = :default) self.created_at = Time.now unless self.created_at.is_a?(Time) end public # # Blasted datamapper not eager-loading my model. # def add_to_cached_alerts(a) @cached_alerts ||= [] if a.is_a?(Array) and a.all?{|m| m.is_a?(Alert)} @cached_alerts += a elsif a.is_a?(Alert) @cached_alerts << a else raise ArgumentError, "#{a.inspect} not an Alert" end end def alerts @cached_alerts ||= super end def reload @cached_alerts = nil super end def logger Log4r::Logger.new self.class.to_s end end end