| Version 6 (modified by , 9 days ago) ( diff ) |
|---|
Функции, процедури и тригери
Функции
Функција за креирање на review од страна на корисник за курс.
create or replace function complete_quiz_attempt(
p_enrollment_id int,
p_quiz_id int,
p_answers jsonb -- [{question_id, answer_option_id}]
)
returns bigint
language plpgsql as
$$
declare
v_attempt_id bigint;
v_attempt_num int;
v_total_points int;
v_earned_points int;
v_score int;
v_passed boolean;
v_passing_score numeric;
begin
-- check answer count matches question count
if (select count(*) from jsonb_array_elements(p_answers)) !=
(select count(*) from quiz_question where quiz_id = p_quiz_id)
then
raise exception 'Answer count does not match question count for quiz %', p_quiz_id;
end if;
-- check all questions belong to the quiz
if exists (select 1
from jsonb_array_elements(p_answers) a
where not exists (select 1
from quiz_question
where id = (a ->> 'question_id')::bigint
and quiz_id = p_quiz_id)) then
raise exception 'One or more questions do not belong to quiz %', p_quiz_id;
end if;
-- check all answer options belong to their respective questions
if exists (select 1
from jsonb_array_elements(p_answers) a
where not exists (select 1
from quiz_answer_option
where id = (a ->> 'answer_option_id')::bigint
and quiz_question_id = (a ->> 'question_id')::bigint)) then
raise exception 'One or more answer options do not belong to their question';
end if;
select coalesce(max(attempt_number), 0) + 1
into v_attempt_num
from quiz_attempt
where enrollment_id = p_enrollment_id
and quiz_id = p_quiz_id;
select coalesce(sum(points), 0)
into v_total_points
from quiz_question
where quiz_id = p_quiz_id;
select coalesce(sum(qq.points), 0)
into v_earned_points
from jsonb_array_elements(p_answers) a
join quiz_question qq on qq.id = (a ->> 'question_id')::bigint
join quiz_answer_option qao on qao.id = (a ->> 'answer_option_id')::bigint
where qao.correct = true;
select passing_score
into v_passing_score
from quiz
where id = p_quiz_id;
v_score := case
when v_total_points > 0
then ((v_earned_points::numeric / v_total_points) * 100)::int
else 0 end;
v_passed := v_score >= v_passing_score;
insert into quiz_attempt (attempt_number, completed_at, status, score, total_points, earned_points, passed, quiz_id,
enrollment_id)
values (v_attempt_num, now(),
case when v_passed then 'PASSED' else 'FAILED' end,
v_score, v_total_points, v_earned_points, v_passed,
p_quiz_id, p_enrollment_id)
returning id into v_attempt_id;
insert into quiz_attempt_answer (correct, quiz_question_id, quiz_attempt_id)
select qao.correct,
(a ->> 'question_id')::bigint,
v_attempt_id
from jsonb_array_elements(p_answers) a
join quiz_answer_option qao on qao.id = (a ->> 'answer_option_id')::bigint;
insert into quiz_attempt_answer_selected_options (quiz_attempt_answer_id, quiz_answer_option_id)
select qaa.id, (a ->> 'answer_option_id')::bigint
from jsonb_array_elements(p_answers) a
join quiz_attempt_answer qaa
on qaa.quiz_attempt_id = v_attempt_id
and qaa.quiz_question_id = (a ->> 'question_id')::bigint;
return v_attempt_id;
end;
$$;
Процедури
Процедура за испраќање на мејлови за потсетување за онлајн состанок со експерт.
create or replace procedure send_all_emails()
as
$$
declare
email_to_send meeting_email_reminder;
begin
for email_to_send in
select * from meeting_email_reminder where sent = false and scheduled_at <= now()
loop
perform pg_notify('send_email', email_to_send.id::text);
update meeting_email_reminder set sent = true where id = email_to_send.id;
end loop;
end;
$$
language plpgsql;
Тригери
Тригер за поставување на предходната верзија од курсот како неактивна при креирање на нова верзија.
create or replace function mark_course_version_as_inactive()
returns trigger
as $$
begin
update course_version
set active = false
where course_id = NEW.course_id;
return NEW;
end;
$$ language plpgsql;
create trigger mark_course_version_as_inactive_trigger
before insert on course_version
for each row
execute function mark_course_version_as_inactive();
Note:
See TracWiki
for help on using the wiki.
