= Фаза 4: Функции, процедури, тригери = Апликациската логика е имплементирана на ниво на база на податоци со користење на PL/pgSQL функции, процедури и тригери. Во продолжение се издвоени најважните функционалности имплементирани преку процедури и тригери: == 1. Ослободување на откажани билети (Тригер функција) == * '''Назив:''' `trg_fn_release_cancelled_tickets()` * '''Опис:''' Тригер кој се активира автоматски по бришење или откажување на резервација, враќајќи ги билетите повторно во системот како слободни и ажурирајќи го вкупниот број на достапни места. {{{ CREATE OR REPLACE FUNCTION trg_fn_release_cancelled_tickets() RETURNS TRIGGER AS $$ BEGIN -- Враќање на билетите во системот UPDATE events SET available_seats = available_seats + OLD.ticket_count WHERE event_id = OLD.event_id; RETURN OLD; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_release_tickets AFTER DELETE ON reservations FOR EACH ROW EXECUTE FUNCTION trg_fn_release_cancelled_tickets(); }}} == 2. Процес на купување билет (Процедура) == * '''Назив:''' `sp_buy_ticket(int4, int4)` * '''Опис:''' Процедура која ја менаџира трансакцијата за купување билет. Проверува достапност, креира резервација и го поврзува корисникот со генерираниот билет. {{{ CREATE OR REPLACE PROCEDURE public.sp_buy_ticket(IN p_user_id integer, IN p_perf_id integer) LANGUAGE plpgsql AS $procedure$ DECLARE v_ticket_id INT; BEGIN IF NOT EXISTS (SELECT 1 FROM users WHERE user_id = p_user_id) THEN RAISE EXCEPTION 'Корисникот со ID % не постои!', p_user_id; END IF; SELECT ticket_id INTO v_ticket_id FROM ticket WHERE performance_id = p_perf_id AND status = 'available' LIMIT 1; IF v_ticket_id IS NULL THEN RAISE EXCEPTION 'Нема слободни карти!'; END IF; UPDATE ticket SET user_id = p_user_id, status = 'sold' WHERE ticket_id = v_ticket_id; END; $procedure$ ; }}} * '''Пример за повик:''' `CALL public.sp_buy_ticket(1, 105);` == 3. Проверка на достапност (Функција) == * '''Назив:''' `fn_check_availability(int4)` * '''Опис:''' Функција која за даден ID на настан или сектор брзо проверува и го враќа преостанатиот број на слободни места, спречувајќи "overbooking". {{{ CREATE OR REPLACE FUNCTION public.fn_check_availability(p_performance_id integer) RETURNS integer LANGUAGE plpgsql AS $function$ DECLARE v_available_count INT; BEGIN SELECT COUNT(*) INTO v_available_count FROM ticket WHERE performance_id = p_performance_id AND status = 'available'; RETURN v_available_count; END; $function$ ; }}}