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
128
129
130
131
132
133
134
135
136
137
|
# 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
def cached_alerts
return @cached_alerts if defined? @cached_alerts
@cached_alerts = []
end
def reload
@cached_alerts = []
super
end
# @return Log4r::Logger
def logger
Log4r::Logger.new self.class.to_s
end
end
end
|