FunctionsProceduresTriggers: 03_databaseTriggers.sql

File 03_databaseTriggers.sql, 8.4 KB (added by 231184, 9 days ago)

databaseTriggers

Line 
1-- =====================================================
2-- TRIGGERS FOR REZERVO PROJECT
3-- =====================================================
4
5
6-- =====================================================
7-- 1. Trigger: Automatically set created_at on appointment
8-- =====================================================
9
10-- CREATE OR REPLACE FUNCTION trg_set_appointment_created_at()
11-- RETURNS TRIGGER
12-- LANGUAGE plpgsql
13-- AS $$
14-- BEGIN
15-- IF NEW.created_at IS NULL THEN
16-- NEW.created_at := CURRENT_TIMESTAMP;
17-- END IF;
18--
19-- RETURN NEW;
20-- END;
21-- $$;
22
23-- DROP TRIGGER IF EXISTS set_appointment_created_at ON appointment;
24--
25-- CREATE TRIGGER set_appointment_created_at
26-- BEFORE INSERT ON appointment
27-- FOR EACH ROW
28-- EXECUTE FUNCTION trg_set_appointment_created_at();
29
30
31
32-- =====================================================
33-- 2. Trigger: Prevent booking unavailable slot
34-- =====================================================
35
36CREATE OR REPLACE FUNCTION trg_prevent_unavailable_slot_booking()
37 RETURNS TRIGGER
38 LANGUAGE plpgsql
39AS $$
40BEGIN
41 IF NEW.status <> 'cancelled' THEN
42 IF NOT EXISTS (
43 SELECT 1
44 FROM time_slot
45 WHERE slot_id = NEW.slot_id
46 AND is_available = TRUE
47 ) THEN
48 RAISE EXCEPTION 'Slot % is not available for booking', NEW.slot_id;
49 END IF;
50 END IF;
51
52 RETURN NEW;
53END;
54$$;
55
56DROP TRIGGER IF EXISTS prevent_unavailable_slot_booking ON appointment;
57
58CREATE TRIGGER prevent_unavailable_slot_booking
59 BEFORE INSERT ON appointment
60 FOR EACH ROW
61EXECUTE FUNCTION trg_prevent_unavailable_slot_booking();
62
63
64
65-- =====================================================
66-- 3. Trigger: Prevent double booking of same slot
67-- =====================================================
68
69CREATE OR REPLACE FUNCTION trg_prevent_double_booking()
70 RETURNS TRIGGER
71 LANGUAGE plpgsql
72AS $$
73BEGIN
74 IF NEW.status <> 'cancelled' THEN
75 IF EXISTS (
76 SELECT 1
77 FROM appointment a
78 WHERE a.slot_id = NEW.slot_id
79 AND a.status <> 'cancelled'
80 AND (
81 TG_OP = 'INSERT'
82 OR a.appointment_id <> NEW.appointment_id
83 )
84 ) THEN
85 RAISE EXCEPTION 'Slot % is already booked', NEW.slot_id;
86 END IF;
87 END IF;
88
89 RETURN NEW;
90END;
91$$;
92
93DROP TRIGGER IF EXISTS prevent_double_booking ON appointment;
94
95CREATE TRIGGER prevent_double_booking
96 BEFORE INSERT OR UPDATE OF slot_id, status ON appointment
97 FOR EACH ROW
98EXECUTE FUNCTION trg_prevent_double_booking();
99
100
101
102-- =====================================================
103-- 4. Trigger: Mark slot as unavailable after appointment insert
104-- =====================================================
105
106CREATE OR REPLACE FUNCTION trg_mark_slot_unavailable_after_booking()
107 RETURNS TRIGGER
108 LANGUAGE plpgsql
109AS $$
110BEGIN
111 IF NEW.status <> 'cancelled' THEN
112 UPDATE time_slot
113 SET is_available = FALSE
114 WHERE slot_id = NEW.slot_id;
115 END IF;
116
117 RETURN NEW;
118END;
119$$;
120
121DROP TRIGGER IF EXISTS mark_slot_unavailable_after_booking ON appointment;
122
123CREATE TRIGGER mark_slot_unavailable_after_booking
124 AFTER INSERT ON appointment
125 FOR EACH ROW
126EXECUTE FUNCTION trg_mark_slot_unavailable_after_booking();
127
128
129
130-- =====================================================
131-- 5. Trigger: Free slot when appointment is cancelled
132-- =====================================================
133
134CREATE OR REPLACE FUNCTION trg_free_slot_after_cancellation()
135 RETURNS TRIGGER
136 LANGUAGE plpgsql
137AS $$
138BEGIN
139 IF OLD.status <> 'cancelled'
140 AND NEW.status = 'cancelled' THEN
141
142 UPDATE time_slot
143 SET is_available = TRUE
144 WHERE slot_id = OLD.slot_id;
145 END IF;
146
147 RETURN NEW;
148END;
149$$;
150
151DROP TRIGGER IF EXISTS free_slot_after_cancellation ON appointment;
152
153CREATE TRIGGER free_slot_after_cancellation
154 AFTER UPDATE OF status ON appointment
155 FOR EACH ROW
156EXECUTE FUNCTION trg_free_slot_after_cancellation();
157
158
159
160-- =====================================================
161-- 6. Trigger: Validate review rating
162-- =====================================================
163
164-- CREATE OR REPLACE FUNCTION trg_validate_review_rating()
165-- RETURNS TRIGGER
166-- LANGUAGE plpgsql
167-- AS $$
168-- BEGIN
169-- IF NEW.rating < 1 OR NEW.rating > 5 THEN
170-- RAISE EXCEPTION 'Rating must be between 1 and 5';
171-- END IF;
172--
173-- RETURN NEW;
174-- END;
175-- $$;
176--
177-- DROP TRIGGER IF EXISTS validate_review_rating ON review;
178--
179-- CREATE TRIGGER validate_review_rating
180-- BEFORE INSERT OR UPDATE OF rating ON review
181-- FOR EACH ROW
182-- EXECUTE FUNCTION trg_validate_review_rating();
183
184
185
186-- =====================================================
187-- 7. Trigger: Prevent duplicate review for same appointment
188-- =====================================================
189
190CREATE OR REPLACE FUNCTION trg_prevent_duplicate_review()
191 RETURNS TRIGGER
192 LANGUAGE plpgsql
193AS $$
194BEGIN
195 IF EXISTS (
196 SELECT 1
197 FROM review r
198 WHERE r.appointment_id = NEW.appointment_id
199 AND (
200 TG_OP = 'INSERT'
201 OR r.review_id <> NEW.review_id
202 )
203 ) THEN
204 RAISE EXCEPTION 'Appointment % already has a review', NEW.appointment_id;
205 END IF;
206
207 RETURN NEW;
208END;
209$$;
210
211DROP TRIGGER IF EXISTS prevent_duplicate_review ON review;
212
213CREATE TRIGGER prevent_duplicate_review
214 BEFORE INSERT OR UPDATE OF appointment_id ON review
215 FOR EACH ROW
216EXECUTE FUNCTION trg_prevent_duplicate_review();
217
218
219
220-- =====================================================
221-- 8. Trigger: Automatically set review created_at
222-- =====================================================
223
224-- CREATE OR REPLACE FUNCTION trg_set_review_created_at()
225-- RETURNS TRIGGER
226-- LANGUAGE plpgsql
227-- AS $$
228-- BEGIN
229-- IF NEW.created_at IS NULL THEN
230-- NEW.created_at := CURRENT_TIMESTAMP;
231-- END IF;
232--
233-- RETURN NEW;
234-- END;
235-- $$;
236--
237-- DROP TRIGGER IF EXISTS set_review_created_at ON review;
238--
239-- CREATE TRIGGER set_review_created_at
240-- BEFORE INSERT ON review
241-- FOR EACH ROW
242-- EXECUTE FUNCTION trg_set_review_created_at();
243
244
245
246-- =====================================================
247-- 9. Trigger: Validate new slot in reschedule request
248-- =====================================================
249
250-- CREATE OR REPLACE FUNCTION trg_validate_reschedule_new_slot()
251-- RETURNS TRIGGER
252-- LANGUAGE plpgsql
253-- AS $$
254-- BEGIN
255-- IF NEW.status = 'pending' THEN
256-- IF NOT EXISTS (
257-- SELECT 1
258-- FROM time_slot
259-- WHERE slot_id = NEW.new_slot_id
260-- AND is_available = TRUE
261-- ) THEN
262-- RAISE EXCEPTION 'New slot % is not available for rescheduling', NEW.new_slot_id;
263-- END IF;
264-- END IF;
265--
266-- RETURN NEW;
267-- END;
268-- $$;
269--
270-- DROP TRIGGER IF EXISTS validate_reschedule_new_slot ON reschedule_request;
271--
272-- CREATE TRIGGER validate_reschedule_new_slot
273-- BEFORE INSERT OR UPDATE OF new_slot_id, status ON reschedule_request
274-- FOR EACH ROW
275-- EXECUTE FUNCTION trg_validate_reschedule_new_slot();
276
277
278
279-- =====================================================
280-- 10. Trigger: Automatically set reschedule request created_at
281-- =====================================================
282
283-- CREATE OR REPLACE FUNCTION trg_set_reschedule_created_at()
284-- RETURNS TRIGGER
285-- LANGUAGE plpgsql
286-- AS $$
287-- BEGIN
288-- IF NEW.created_at IS NULL THEN
289-- NEW.created_at := CURRENT_TIMESTAMP;
290-- END IF;
291--
292-- RETURN NEW;
293-- END;
294-- $$;
295--
296-- DROP TRIGGER IF EXISTS set_reschedule_created_at ON reschedule_request;
297--
298-- CREATE TRIGGER set_reschedule_created_at
299-- BEFORE INSERT ON reschedule_request
300-- FOR EACH ROW
301-- EXECUTE FUNCTION trg_set_reschedule_created_at();
302
303
304
305-- =====================================================
306-- 11. Trigger: Validate cancellation created_at
307-- =====================================================
308
309-- CREATE OR REPLACE FUNCTION trg_set_cancellation_created_at()
310-- RETURNS TRIGGER
311-- LANGUAGE plpgsql
312-- AS $$
313-- BEGIN
314-- IF NEW.created_at IS NULL THEN
315-- NEW.created_at := CURRENT_TIMESTAMP;
316-- END IF;
317--
318-- RETURN NEW;
319-- END;
320-- $$;
321--
322-- DROP TRIGGER IF EXISTS set_cancellation_created_at ON cancellation;
323--
324-- CREATE TRIGGER set_cancellation_created_at
325-- BEFORE INSERT ON cancellation
326-- FOR EACH ROW
327-- EXECUTE FUNCTION trg_set_cancellation_created_at();