1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
67
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# encoding: UTF-8
require 'mauve/datamapper'
require 'mauve/alert'
require 'log4r'
module Mauve
# This is the look-up table for Alerts and History to allow one History to
# have many Alerts and vice-versa
#
#
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
# This is a horid migration to allow a move from an older version of Mauve
# without this table.
#
#
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, "user" VARCHAR(50) DEFAULT NULL, "created_at" TIMESTAMP NOT NULL'
history_cols = 'id, type, event, user, 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
# This just removes histories that this AlertHistory used to refer to, if
# they have no other alerts associated with them
#
#
def remove_unreferenced_histories
self.history.destroy unless self.history.alerts.count > 0
end
end
# This class keeps a history for Mauve. One History can relate to zero or
# more Alerts, allowing notes to be added.
#
#
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 :user, String
property :created_at, EpochTime, :required => true
has n, :alerts, :through => :alerthistory
before :valid?, :do_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
# Update the created_at time on the object
#
def do_set_created_at(context = :default)
self.created_at = Time.now if self.new?
end
public
# @return Log4r::Logger
def logger
Log4r::Logger.new self.class.to_s
end
end
end
|