forked from ManageIQ/manageiq-schema
-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema_dumper.rb
115 lines (97 loc) · 4.11 KB
/
schema_dumper.rb
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
module ManageIQ
module Schema
module SchemaDumper
METRIC_ROLLUP_TABLE_REGEXP = /(?<METRIC_TYPE>metrics?_?.*)_(?<CHILD_TABLE_NUM>\d\d)$/.freeze
def tables(stream)
super
miq_metric_table_contraints(stream)
miq_metric_views(stream)
triggers(stream)
end
def table(table, stream)
super
add_id_column_comment(table, stream)
track_miq_metric_table_inheritance(table)
end
def add_id_column_comment(table, stream)
pk = @connection.primary_key(table)
pkcol = @connection.columns(table).detect { |c| c.name == pk }
comment = pkcol.comment
return unless comment
stream.puts " change_column_comment #{remove_prefix_and_suffix(table).inspect}, #{pk.inspect}, #{comment.inspect}"
stream.puts
end
# Must be done after all of the table definitions since `metrics_01` is
# dumpped prior to `metrics_base`, etc.
#
def miq_metric_table_contraints(stream)
inherited_metrics_tables.each do |(table, inherit_from)|
match = table.match(METRIC_ROLLUP_TABLE_REGEXP)
child_table = remove_prefix_and_suffix(table).inspect
primary_condition = if inherit_from.include?("rollup")
"capture_interval_name != ? AND EXTRACT(MONTH FROM timestamp) = ?"
else
"capture_interval_name = ? AND EXTRACT(HOUR FROM timestamp) = ?"
end
conditions = [primary_condition, "realtime", match[:CHILD_TABLE_NUM]]
stream.puts " add_miq_metric_table_inheritance #{child_table}, " \
"#{inherit_from.inspect}, " \
":conditions => #{conditions.inspect}"
end
stream.puts
end
def miq_metric_views(stream)
@connection.views.each do |view|
stream.puts " create_miq_metric_view #{view["name"].inspect}"
stream.puts
end
end
def triggers(stream)
@connection.triggers.each do |(direction, table, name, body)|
# Inverse of the case statement in add_trigger_hook
direction_key = direction.downcase.gsub(/\s/, "")
# Formats the SQL we get from the database to do that following:
#
# - Removes the "BEGIN" and "END;" stanzas
# - Chomps the new lines from the beginning (keeps existing indent)
# - Strips whitespace from the end (no need to worry about indent)
# - Indents by four spaces
#
# For formatting, we want to ensure at least some bit of an indent,
# regardless of how the SQL string was originally added.
#
formatted_body = body.gsub(/(BEGIN$|^END;$)/, "")
.reverse.chomp.reverse.rstrip
.indent(4)
stream.puts " add_trigger #{direction_key.inspect}, " \
"#{table.inspect}, " \
"#{name.inspect}, " \
"<<-SQL\n#{formatted_body}\n SQL"
stream.puts
end
end
private
def track_miq_metric_table_inheritance(table)
return unless table.match?(METRIC_ROLLUP_TABLE_REGEXP)
inherit_from = determine_table_parent(table)
inherited_metrics_tables << [table, inherit_from]
end
def inherited_metrics_tables
@inherited_metrics_tables ||= []
end
def determine_table_parent(table_name)
@connection.execute(<<-SQL).first["parent_table"]
SELECT pg_class.relname AS parent_table
FROM pg_catalog.pg_inherits
JOIN pg_class ON pg_class.oid = pg_inherits.inhparent
WHERE inhrelid = '#{table_name}'::regclass
SQL
end
def column_spec_for_primary_key(column)
result = super
result.delete(:default) if column.table_name.match?(METRIC_ROLLUP_TABLE_REGEXP)
result
end
end
end
end