935
by wagrant
userdb: Large changes: |
1 |
-- WARNING: This will eat babies. And your offerings, enrolments and groups.
|
2 |
||
3 |
-- This will require plpgsql support in the database. This can be achieved with
|
|
4 |
-- 'createlang plpgsql ivle'.
|
|
5 |
||
6 |
-- Here we split semesters out into a separate table, and give them and
|
|
7 |
-- enrolments an active flag. Triggers are used to ensure that we don't
|
|
8 |
-- have active enrolments in an inactive semester.
|
|
9 |
-- We also introduce the concept of project sets, which link groups to
|
|
10 |
-- projects.
|
|
11 |
||
12 |
||
13 |
BEGIN; |
|
14 |
||
15 |
'Comment this line out to acknowledge the warnings.'
|
|
16 |
||
17 |
DELETE FROM project; |
|
18 |
DELETE FROM group_member; |
|
19 |
DELETE FROM group_invitation; |
|
20 |
DELETE FROM project_group; |
|
21 |
DELETE FROM enrolment; |
|
22 |
DELETE FROM offering; |
|
23 |
||
24 |
CREATE TABLE semester ( |
|
25 |
semesterid SERIAL PRIMARY KEY NOT NULL, |
|
26 |
year CHAR(4) NOT NULL, |
|
27 |
semester CHAR(1) NOT NULL, |
|
28 |
active BOOL NOT NULL, |
|
29 |
UNIQUE (year, semester) |
|
30 |
);
|
|
31 |
||
32 |
CREATE TABLE project_set ( |
|
33 |
projectsetid SERIAL PRIMARY KEY NOT NULL, |
|
34 |
offeringid INTEGER REFERENCES offering (offeringid) NOT NULL, |
|
35 |
max_students_per_group INTEGER NOT NULL DEFAULT 4 |
|
36 |
);
|
|
37 |
||
38 |
ALTER TABLE offering DROP COLUMN year; |
|
39 |
ALTER TABLE offering DROP COLUMN semester; |
|
40 |
ALTER TABLE offering DROP COLUMN max_groups_per_student; |
|
41 |
ALTER TABLE offering DROP COLUMN max_students_per_group; |
|
42 |
ALTER TABLE offering ADD COLUMN semesterid |
|
43 |
INTEGER REFERENCES semester (semesterid) NOT NULL; |
|
44 |
ALTER TABLE offering ADD CONSTRAINT offering_subject_key |
|
45 |
UNIQUE (subject, semesterid); |
|
46 |
||
47 |
ALTER TABLE project DROP COLUMN offeringid; |
|
48 |
ALTER TABLE project ADD COLUMN projectsetid |
|
49 |
INTEGER REFERENCES project_set (projectsetid) NOT NULL; |
|
50 |
||
51 |
ALTER TABLE project_group DROP COLUMN offeringid; |
|
52 |
ALTER TABLE project_group ADD COLUMN projectsetid |
|
53 |
INTEGER REFERENCES project_set (projectsetid) NOT NULL; |
|
54 |
ALTER TABLE project_group ADD CONSTRAINT project_group_projectsetid_key |
|
55 |
UNIQUE (projectsetid, groupnm); |
|
56 |
||
57 |
||
58 |
ALTER TABLE group_member DROP COLUMN projectid; |
|
59 |
||
60 |
ALTER TABLE enrolment ADD COLUMN active BOOL NOT NULL DEFAULT true; |
|
61 |
||
62 |
-- Triggers
|
|
63 |
||
64 |
CREATE OR REPLACE FUNCTION deactivate_semester_enrolments_update() |
|
65 |
RETURNS trigger AS ' |
|
66 |
BEGIN
|
|
67 |
IF OLD.active = true AND NEW.active = false THEN
|
|
68 |
UPDATE enrolment SET active=false WHERE offeringid IN (
|
|
69 |
SELECT offeringid FROM offering WHERE offering.semesterid = NEW.semesterid);
|
|
70 |
END IF;
|
|
71 |
RETURN NULL;
|
|
72 |
END;
|
|
73 |
' LANGUAGE 'plpgsql'; |
|
74 |
||
75 |
CREATE OR REPLACE FUNCTION check_group_namespacing_insertupdate() |
|
76 |
RETURNS trigger AS ' |
|
77 |
DECLARE
|
|
78 |
oid INTEGER;
|
|
79 |
BEGIN
|
|
80 |
SELECT offeringid INTO oid FROM project_set WHERE project_set.projectsetid = NEW.projectsetid;
|
|
81 |
PERFORM 1 FROM project_group, project_set WHERE project_group.projectsetid = project_set.projectsetid AND project_group.groupnm = NEW.groupnm;
|
|
82 |
IF found THEN
|
|
83 |
RAISE EXCEPTION ''a project group named % already exists in offering ID %'', NEW.groupnm, oid;
|
|
84 |
END IF;
|
|
85 |
RETURN NEW;
|
|
86 |
END;
|
|
87 |
' LANGUAGE 'plpgsql'; |
|
88 |
||
89 |
CREATE OR REPLACE FUNCTION confirm_active_semester_insertupdate() |
|
90 |
RETURNS trigger AS ' |
|
91 |
DECLARE
|
|
92 |
active BOOL;
|
|
93 |
BEGIN
|
|
94 |
SELECT semester.active INTO active FROM offering, semester WHERE offeringid=NEW.offeringid AND semester.semesterid = offering.semesterid;
|
|
95 |
IF NOT active AND NEW.active = true THEN
|
|
96 |
RAISE EXCEPTION ''cannot have active enrolment for % in offering %, as the semester is inactive'', NEW.loginid, NEW.offeringid;
|
|
97 |
END IF;
|
|
98 |
RETURN NEW;
|
|
99 |
END;
|
|
100 |
' LANGUAGE 'plpgsql'; |
|
101 |
||
102 |
CREATE TRIGGER deactivate_semester_enrolments |
|
103 |
AFTER UPDATE ON semester |
|
104 |
FOR EACH ROW EXECUTE PROCEDURE deactivate_semester_enrolments_update(); |
|
105 |
||
106 |
CREATE TRIGGER check_group_namespacing |
|
107 |
BEFORE INSERT OR UPDATE ON project_group |
|
108 |
FOR EACH ROW EXECUTE PROCEDURE check_group_namespacing_insertupdate(); |
|
109 |
||
110 |
CREATE TRIGGER confirm_active_semester |
|
111 |
BEFORE INSERT OR UPDATE ON enrolment |
|
112 |
FOR EACH ROW EXECUTE PROCEDURE confirm_active_semester_insertupdate(); |
|
113 |
||
114 |
COMMIT; |