/
postgresql_adapter_spec.rb
159 lines (133 loc) · 6.06 KB
/
postgresql_adapter_spec.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
require 'spec_helper'
require 'polymorphic_constraints/connection_adapters/postgresql_adapter'
describe PolymorphicConstraints::ConnectionAdapters::PostgreSQLAdapter do
class PostgresqlTestAdapter
include Support::AdapterHelper
include PolymorphicConstraints::ConnectionAdapters::PostgreSQLAdapter
end
subject { PostgresqlTestAdapter.new }
it { is_expected.to respond_to(:supports_polymorphic_constraints?) }
it { is_expected.to respond_to(:add_polymorphic_constraints) }
it { is_expected.to respond_to(:remove_polymorphic_constraints) }
describe 'add constraints' do
it 'defaults to active_record_descendants search strategy' do
expect(subject.add_polymorphic_constraints(:imageable, :pictures)).to eql([drop_triggers_sql,
upsert_triggers_sql,
delete_triggers_sql])
end
it 'returns expected add constraints sql with polymorphic model options' do
expect(subject.add_polymorphic_constraints(:imageable, :pictures,
polymorphic_models: [:employee])).to eql([drop_triggers_sql,
upsert_triggers_sql_only_employee,
delete_triggers_sql_only_employee])
end
end
describe 'remove constraints' do
it 'returns expected drop trigger sql' do
expect(subject.remove_polymorphic_constraints(:imageable)).to eql(drop_triggers_sql)
end
end
let(:upsert_triggers_sql) do
subject.strip_non_essential_spaces(%{
CREATE FUNCTION check_imageable_upsert_integrity() RETURNS TRIGGER AS '
BEGIN
IF NEW.imageable_type = ''Employee'' AND
EXISTS (SELECT id FROM employees WHERE id = NEW.imageable_id) THEN
RETURN NEW;
ELSEIF NEW.imageable_type = ''Product'' AND
EXISTS (SELECT id FROM products WHERE id = NEW.imageable_id) THEN
RETURN NEW;
ELSE
RAISE EXCEPTION ''Polymorphic record not found.
No % model with id %.'', NEW.imageable_type, NEW.imageable_id;
RETURN NULL;
END IF;
END'
LANGUAGE plpgsql;
CREATE TRIGGER check_imageable_upsert_integrity_trigger
BEFORE INSERT OR UPDATE ON pictures
FOR EACH ROW EXECUTE PROCEDURE check_imageable_upsert_integrity();
})
end
let(:delete_triggers_sql) do
subject.strip_non_essential_spaces(%{
CREATE FUNCTION check_imageable_delete_integrity()
RETURNS TRIGGER AS '
BEGIN
IF TG_TABLE_NAME = ''employees'' AND
EXISTS (SELECT id FROM pictures
WHERE imageable_type = ''Employee'' AND imageable_id = OLD.id) THEN
RAISE EXCEPTION ''Polymorphic reference exists.
There are records in pictures that refer to the table % with id %.
You must delete those records of table pictures first.'', TG_TABLE_NAME, OLD.id;
RETURN NULL;
ELSEIF TG_TABLE_NAME = ''products'' AND
EXISTS (SELECT id FROM pictures
WHERE imageable_type = ''Product'' AND imageable_id = OLD.id) THEN
RAISE EXCEPTION ''Polymorphic reference exists.
There are records in pictures that refer to the table % with id %.
You must delete those records of table pictures first.'', TG_TABLE_NAME, OLD.id;
RETURN NULL;
ELSE
RETURN OLD;
END IF;
END'
LANGUAGE plpgsql;
CREATE TRIGGER check_imageable_employees_delete_integrity_trigger
BEFORE DELETE ON employees
FOR EACH ROW EXECUTE PROCEDURE check_imageable_delete_integrity();
CREATE TRIGGER check_imageable_products_delete_integrity_trigger
BEFORE DELETE ON products
FOR EACH ROW EXECUTE PROCEDURE check_imageable_delete_integrity();
})
end
let(:upsert_triggers_sql_only_employee) do
subject.strip_non_essential_spaces(%{
CREATE FUNCTION check_imageable_upsert_integrity() RETURNS TRIGGER AS '
BEGIN
IF NEW.imageable_type = ''Employee'' AND
EXISTS (SELECT id FROM employees WHERE id = NEW.imageable_id) THEN
RETURN NEW;
ELSE
RAISE EXCEPTION ''Polymorphic record not found.
No % model with id %.'', NEW.imageable_type, NEW.imageable_id;
RETURN NULL;
END IF;
END'
LANGUAGE plpgsql;
CREATE TRIGGER check_imageable_upsert_integrity_trigger
BEFORE INSERT OR UPDATE ON pictures
FOR EACH ROW EXECUTE PROCEDURE check_imageable_upsert_integrity();
})
end
let(:delete_triggers_sql_only_employee) do
subject.strip_non_essential_spaces(%{
CREATE FUNCTION check_imageable_delete_integrity()
RETURNS TRIGGER AS '
BEGIN
IF TG_TABLE_NAME = ''employees'' AND
EXISTS (SELECT id FROM pictures
WHERE imageable_type = ''Employee'' AND imageable_id = OLD.id) THEN
RAISE EXCEPTION ''Polymorphic reference exists.
There are records in pictures that refer to the table % with id %.
You must delete those records of table pictures first.'', TG_TABLE_NAME, OLD.id;
RETURN NULL;
ELSE
RETURN OLD;
END IF;
END'
LANGUAGE plpgsql;
CREATE TRIGGER check_imageable_employees_delete_integrity_trigger
BEFORE DELETE ON employees
FOR EACH ROW EXECUTE PROCEDURE check_imageable_delete_integrity();
})
end
let(:drop_triggers_sql) do
subject.strip_non_essential_spaces(%{
DROP FUNCTION IF EXISTS check_imageable_upsert_integrity()
CASCADE;
DROP FUNCTION IF EXISTS check_imageable_delete_integrity()
CASCADE;
})
end
end