| 1 | == Употреба на тригери во апликацијата |
| 2 | |
| 3 | Во овој дел ќе прикажам каде и како ги комбинирав тригерите со функции, кои ми донесоа многу пофлексибилна нивна употреба и попрофесионален дизајн на базата. |
| 4 | |
| 5 | === 1. Валидирање на дали Report објектот е соодветен за креирање на !AcademicReport |
| 6 | |
| 7 | {{{ |
| 8 | CREATE OR REPLACE FUNCTION validate_academic_report() |
| 9 | RETURNS TRIGGER AS $$ |
| 10 | BEGIN |
| 11 | IF NOT EXISTS (SELECT 1 FROM Report WHERE report_id = NEW.report_id AND report_type = 'Academic') |
| 12 | THEN |
| 13 | RAISE EXCEPTION 'Report with ID % is not of type Academic!', NEW.report_id; |
| 14 | END IF; |
| 15 | |
| 16 | RETURN NEW; |
| 17 | END; |
| 18 | $$ LANGUAGE plpgsql; |
| 19 | CREATE TRIGGER trg_check_academic_report_correctness |
| 20 | BEFORE INSERT ON AcademicReport |
| 21 | FOR EACH ROW |
| 22 | EXECUTE FUNCTION validate_academic_report(); |
| 23 | }}} |
| 24 | |
| 25 | === 2. Валидирање на дали Person објектот е доволно возрасен за дадена институција која е поврзана со неговиот !AcademicReport |
| 26 | |
| 27 | {{{ |
| 28 | --function to check if the age is correct so the person can go or went in the right age at the type of school2 |
| 29 | CREATE OR REPLACE FUNCTION validate_academic_age_for_institution() |
| 30 | RETURNS TRIGGER AS $$ |
| 31 | DECLARE |
| 32 | institution_type institution_type; |
| 33 | person_birth_date DATE; |
| 34 | report_date DATE; |
| 35 | person_age INT; |
| 36 | pers_id INT; |
| 37 | BEGIN |
| 38 | SELECT type INTO institution_type |
| 39 | FROM Institution |
| 40 | WHERE institution_id = NEW.institution_id; |
| 41 | |
| 42 | SELECT p.date_of_birth, r.created_at |
| 43 | INTO person_birth_date, report_date |
| 44 | FROM Report r |
| 45 | JOIN Person p ON r.person_id = p.person_id |
| 46 | WHERE r.report_id = NEW.report_id; |
| 47 | |
| 48 | SELECT r.person_id INTO pers_id |
| 49 | FROM Report r |
| 50 | WHERE r.report_id = NEW.report_id; |
| 51 | |
| 52 | person_age := DATE_PART('year', age(report_date, person_birth_date)); |
| 53 | |
| 54 | IF institution_type = 'Primary School' AND (person_age < 5 OR person_age > 16) THEN |
| 55 | RAISE EXCEPTION 'Person with ID % is not within valid age range for Primary School (actual: %)', pers_id, person_age; |
| 56 | ELSIF institution_type = 'High School' AND (person_age < 14 OR person_age > 19) THEN |
| 57 | RAISE EXCEPTION 'Person with ID % is not within valid age range for High School (actual: %)', pers_id, person_age; |
| 58 | END IF; |
| 59 | |
| 60 | RETURN NEW; |
| 61 | END; |
| 62 | $$ LANGUAGE plpgsql; |
| 63 | |
| 64 | CREATE TRIGGER trg_validate_academic_report_person_age |
| 65 | BEFORE INSERT ON AcademicReport |
| 66 | FOR EACH ROW |
| 67 | EXECUTE FUNCTION validate_academic_age_for_institution(); |
| 68 | }}} |
| 69 | |
| 70 | === 3. Тригер кој осигурува дека !AcademicReport не може да е креиран за Person објекти кои се назначени како преминати |
| 71 | |
| 72 | {{{ |
| 73 | CREATE OR REPLACE FUNCTION prevent_academic_reports_after_death() |
| 74 | RETURNS TRIGGER AS $$ |
| 75 | DECLARE |
| 76 | death_date DATE; |
| 77 | is_dead BOOLEAN; |
| 78 | type_check VARCHAR; |
| 79 | BEGIN |
| 80 | SELECT date_of_death, is_alive INTO death_date, is_dead FROM Person WHERE person_id = NEW.person_id; |
| 81 | IF NEW.report_type = 'Academic' THEN |
| 82 | IF is_dead = false AND death_date IS NOT NULL AND NEW.created_at > death_date THEN |
| 83 | RAISE EXCEPTION |
| 84 | 'Cannot create academic report for deceased person (death: %, report date: %)', |
| 85 | death_date, NEW.created_at; |
| 86 | END IF; |
| 87 | END IF; |
| 88 | RETURN NEW; |
| 89 | END; |
| 90 | $$ LANGUAGE plpgsql; |
| 91 | CREATE TRIGGER trg_prevent_academic_report_after_death |
| 92 | BEFORE INSERT ON Report |
| 93 | FOR EACH ROW |
| 94 | EXECUTE FUNCTION prevent_academic_reports_after_death(); |
| 95 | }}} |
| 96 | |
| 97 | === 4. |