Class: PgMorph::Polymorphic
- Inherits:
-
Object
- Object
- PgMorph::Polymorphic
show all
- Includes:
- Naming
- Defined in:
- lib/pg_morph/polymorphic.rb
Constant Summary
collapse
- BASE_TABLE_SUFIX =
:base
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Naming
#before_insert_fun_name, #before_insert_trigger_name, #column_name_id, #column_name_type, #proxy_table, #type
Constructor Details
#initialize(parent_table, child_table, options) ⇒ Polymorphic
Returns a new instance of Polymorphic.
9
10
11
12
13
14
15
16
|
# File 'lib/pg_morph/polymorphic.rb', line 9
def initialize(parent_table, child_table, options)
@parent_table = parent_table
@child_table = child_table
@column_name = options[:column]
@base_table = options[:base_table] || :"#{parent_table}_#{BASE_TABLE_SUFIX}"
raise PgMorph::Exception.new("Column not specified") unless @column_name
end
|
Instance Attribute Details
#base_table ⇒ Object
Returns the value of attribute base_table.
7
8
9
|
# File 'lib/pg_morph/polymorphic.rb', line 7
def base_table
@base_table
end
|
#child_table ⇒ Object
Returns the value of attribute child_table.
7
8
9
|
# File 'lib/pg_morph/polymorphic.rb', line 7
def child_table
@child_table
end
|
#column_name ⇒ Object
Returns the value of attribute column_name.
7
8
9
|
# File 'lib/pg_morph/polymorphic.rb', line 7
def column_name
@column_name
end
|
#parent_table ⇒ Object
Returns the value of attribute parent_table.
7
8
9
|
# File 'lib/pg_morph/polymorphic.rb', line 7
def parent_table
@parent_table
end
|
Instance Method Details
#can_rename_to_base_table? ⇒ Boolean
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/pg_morph/polymorphic.rb', line 25
def can_rename_to_base_table?
return true unless ActiveRecord::Base.connection.table_exists? base_table
parent_table_set = ActiveRecord::Base.connection.columns(parent_table).
map{|column| column.as_json.except('null')}
base_table_set = ActiveRecord::Base.connection.columns(base_table).
map{|column| column.as_json.except('null')}
return false if parent_table_set == base_table_set
raise PgMorph::Exception.new('table name mismatch!')
end
|
#create_base_table_view_sql ⇒ Object
37
38
39
40
41
|
# File 'lib/pg_morph/polymorphic.rb', line 37
def create_base_table_view_sql
%Q{
CREATE OR REPLACE VIEW #{parent_table} AS SELECT * FROM #{base_table};
}
end
|
#create_before_insert_trigger_fun_sql ⇒ Object
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/pg_morph/polymorphic.rb', line 53
def create_before_insert_trigger_fun_sql
before_insert_trigger_content do
%Q{
IF NEW.id IS NULL THEN
NEW.id := nextval('#{parent_table}_id_seq');
END IF;
#{create_trigger_body.strip}
}
end
end
|
#create_before_insert_trigger_sql ⇒ Object
64
65
66
67
68
69
|
# File 'lib/pg_morph/polymorphic.rb', line 64
def create_before_insert_trigger_sql
fun_name = before_insert_fun_name
trigger_name = before_insert_trigger_name
create_trigger_sql(parent_table, trigger_name, fun_name, 'INSTEAD OF INSERT')
end
|
#create_proxy_table_sql ⇒ Object
43
44
45
46
47
48
49
50
51
|
# File 'lib/pg_morph/polymorphic.rb', line 43
def create_proxy_table_sql
%Q{
CREATE TABLE #{proxy_table} (
CHECK (#{column_name_type} = '#{type}'),
PRIMARY KEY (id),
FOREIGN KEY (#{column_name_id}) REFERENCES #{child_table}(id)
) INHERITS (#{base_table});
}
end
|
#remove_base_table_view_sql ⇒ Object
99
100
101
102
103
104
105
|
# File 'lib/pg_morph/polymorphic.rb', line 99
def remove_base_table_view_sql
if check_more_partitions.present?
''
else
%Q{ DROP VIEW #{parent_table}; }
end
end
|
#remove_before_insert_trigger_sql ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
|
# File 'lib/pg_morph/polymorphic.rb', line 71
def remove_before_insert_trigger_sql
trigger_name = before_insert_trigger_name
fun_name = before_insert_fun_name
cleared = check_more_partitions
if cleared.present?
update_before_insert_trigger_sql(cleared)
else
drop_trigger_and_fun_sql(trigger_name, parent_table, fun_name)
end
end
|
#remove_proxy_table ⇒ Object
90
91
92
93
94
95
96
97
|
# File 'lib/pg_morph/polymorphic.rb', line 90
def remove_proxy_table
table_empty = ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM #{parent_table}_#{child_table}").to_i.zero?
if table_empty
%Q{ DROP TABLE IF EXISTS #{proxy_table}; }
else
raise PG::Error.new("Partition table #{proxy_table} contains data.\nRemove them before if you want to drop that table.\n")
end
end
|
#rename_base_table_back_sql ⇒ Object
107
108
109
110
111
112
113
|
# File 'lib/pg_morph/polymorphic.rb', line 107
def rename_base_table_back_sql
if check_more_partitions.present?
''
else
%Q{ ALTER TABLE #{base_table} RENAME TO #{parent_table}; }
end
end
|
#rename_base_table_sql ⇒ Object
18
19
20
21
22
23
|
# File 'lib/pg_morph/polymorphic.rb', line 18
def rename_base_table_sql
return '' unless can_rename_to_base_table?
%Q{
ALTER TABLE #{parent_table} RENAME TO #{base_table};
}
end
|
#update_before_insert_trigger_sql(cleared) ⇒ Object
83
84
85
86
87
88
|
# File 'lib/pg_morph/polymorphic.rb', line 83
def update_before_insert_trigger_sql(cleared)
cleared[0][0].sub!('ELSIF', 'IF')
before_insert_trigger_content do
cleared.map { |m| m[0] }.join('').strip
end
end
|