3
CREATE OR REPLACE FUNCTION valid_url_name(name text) RETURNS boolean AS
6
RETURN name ~ E'^[a-z0-9][a-z0-9_\+\.\-]*$';
10
CREATE OR REPLACE FUNCTION valid_login_name(name text) RETURNS boolean AS
13
RETURN name ~ E'^[a-z0-9][a-z0-9@_\+\.\-]*$';
15
$$ LANGUAGE 'plpgsql';
17
CREATE SEQUENCE login_unixid_seq MINVALUE 1000 MAXVALUE 29999 START WITH 5000;
20
loginid SERIAL PRIMARY KEY NOT NULL,
21
login VARCHAR UNIQUE NOT NULL CHECK (valid_login_name(login)),
23
state VARCHAR NOT NULL CHECK (state in ('no_agreement', 'pending',
24
'enabled', 'disabled'))
25
DEFAULT 'no_agreement',
26
admin BOOLEAN NOT NULL DEFAULT false,
27
unixid INT UNIQUE DEFAULT nextval('login_unixid_seq') NOT NULL,
28
nick VARCHAR NOT NULL,
34
fullname VARCHAR NOT NULL,
35
studentid VARCHAR, -- may be null
40
CREATE TABLE subject (
41
subjectid SERIAL PRIMARY KEY NOT NULL,
42
subj_code VARCHAR UNIQUE NOT NULL,
43
subj_name VARCHAR NOT NULL,
44
subj_short_name VARCHAR UNIQUE NOT NULL CHECK (valid_url_name(subj_short_name))
47
CREATE TABLE semester (
48
semesterid SERIAL PRIMARY KEY NOT NULL,
49
year CHAR(4) NOT NULL CHECK (valid_url_name(year)),
50
semester CHAR(1) NOT NULL CHECK (valid_url_name(semester)),
51
state TEXT NOT NULL CHECK (state IN ('disabled', 'past',
52
'current', 'future')) DEFAULT 'current',
53
UNIQUE (year, semester)
56
CREATE TABLE offering (
57
offeringid SERIAL PRIMARY KEY NOT NULL,
58
subject INT4 REFERENCES subject (subjectid) NOT NULL,
59
semesterid INTEGER REFERENCES semester (semesterid) NOT NULL,
62
show_worksheet_marks BOOLEAN NOT NULL DEFAULT false,
63
worksheet_cutoff TIMESTAMP,
64
groups_student_permissions VARCHAR NOT NULL DEFAULT 'none',
65
CHECK (groups_student_permissions in ('none', 'invite', 'create')),
66
UNIQUE (subject, semesterid)
70
CREATE TABLE project_set (
71
projectsetid SERIAL PRIMARY KEY NOT NULL,
72
offeringid INTEGER REFERENCES offering (offeringid) NOT NULL,
73
max_students_per_group INTEGER
76
CREATE TABLE project (
77
projectid SERIAL PRIMARY KEY NOT NULL,
78
short_name TEXT NOT NULL CHECK (valid_url_name(short_name)),
82
projectsetid INTEGER REFERENCES project_set (projectsetid) NOT NULL,
83
deadline TIMESTAMP NOT NULL
86
CREATE OR REPLACE FUNCTION check_project_namespacing_insertupdate()
91
IF TG_OP = ''UPDATE'' THEN
92
IF NEW.projectsetid = OLD.projectsetid AND NEW.short_name = OLD.short_name THEN
96
SELECT offeringid INTO oid FROM project_set WHERE project_set.projectsetid = NEW.projectsetid;
97
PERFORM 1 FROM project, project_set
98
WHERE project_set.offeringid = oid AND
99
project.projectsetid = project_set.projectsetid AND
100
project.short_name = NEW.short_name;
102
RAISE EXCEPTION ''a project named % already exists in offering ID %'', NEW.short_name, oid;
106
' LANGUAGE 'plpgsql';
108
CREATE TRIGGER check_project_namespacing
109
BEFORE INSERT OR UPDATE ON project
110
FOR EACH ROW EXECUTE PROCEDURE check_project_namespacing_insertupdate();
112
CREATE TABLE project_group (
113
groupnm VARCHAR NOT NULL CHECK (valid_url_name(groupnm)),
114
groupid SERIAL PRIMARY KEY NOT NULL,
115
projectsetid INTEGER REFERENCES project_set (projectsetid) NOT NULL,
117
createdby INT4 REFERENCES login (loginid) NOT NULL,
118
epoch TIMESTAMP NOT NULL,
119
UNIQUE (projectsetid, groupnm)
122
CREATE OR REPLACE FUNCTION check_group_namespacing_insertupdate()
127
SELECT offeringid INTO oid FROM project_set WHERE project_set.projectsetid = NEW.projectsetid;
128
PERFORM 1 FROM project_group, project_set WHERE project_set.offeringid = oid AND project_group.projectsetid = project_set.projectsetid AND project_group.groupnm = NEW.groupnm;
130
RAISE EXCEPTION ''a project group named % already exists in offering ID %'', NEW.groupnm, oid;
134
' LANGUAGE 'plpgsql';
136
CREATE TRIGGER check_group_namespacing
137
BEFORE INSERT OR UPDATE ON project_group
138
FOR EACH ROW EXECUTE PROCEDURE check_group_namespacing_insertupdate();
140
CREATE TABLE group_invitation (
141
loginid INT4 REFERENCES login (loginid) NOT NULL,
142
groupid INT4 REFERENCES project_group (groupid) NOT NULL,
143
inviter INT4 REFERENCES login (loginid) NOT NULL,
144
invited TIMESTAMP NOT NULL,
146
UNIQUE (loginid,groupid)
149
CREATE TABLE group_member (
150
loginid INT4 REFERENCES login (loginid),
151
groupid INT4 REFERENCES project_group (groupid),
152
PRIMARY KEY (loginid,groupid)
1
-- We need a users database to do authorization, manage groups, &c
6
DROP TABLE group_members;
11
login varchar(80) PRIMARY KEY, -- login id
16
groupid varchar(18) PRIMARY KEY, -- group name Y^4-S^9-G^3
17
nick varchar(80), -- group nickname
18
subject varchar(9), -- subject code
19
year varchar(4) -- when
22
CREATE TABLE group_members (
23
login varchar(80) REFERENCES users (login),
24
groupid varchar(18) REFERENCES groups (groupid)
155
27
CREATE TABLE enrolment (
156
loginid INT4 REFERENCES login (loginid),
157
offeringid INT4 REFERENCES offering (offeringid),
158
role TEXT NOT NULL CHECK (role IN ('student', 'tutor',
159
'lecturer')) DEFAULT 'student',
161
special_result VARCHAR,
163
special_supp_result VARCHAR,
165
active BOOL NOT NULL DEFAULT true,
166
PRIMARY KEY (loginid,offeringid)
169
CREATE TABLE assessed (
170
assessedid SERIAL PRIMARY KEY NOT NULL,
171
loginid INT4 REFERENCES login (loginid),
172
groupid INT4 REFERENCES project_group (groupid),
173
projectid INT4 REFERENCES project (projectid) NOT NULL,
174
-- exactly one of loginid and groupid must be non-null
175
CHECK ((loginid IS NOT NULL AND groupid IS NULL)
176
OR (loginid IS NULL AND groupid IS NOT NULL))
179
CREATE UNIQUE INDEX assessed_loginid_key ON assessed(loginid, projectid) WHERE loginid IS NOT NULL;
180
CREATE UNIQUE INDEX assessed_groupid_key ON assessed(groupid, projectid) WHERE groupid IS NOT NULL;
182
CREATE TABLE project_extension (
183
extensionid SERIAL PRIMARY KEY,
184
assessedid INT4 REFERENCES assessed (assessedid) NOT NULL,
185
deadline TIMESTAMP NOT NULL,
186
approver INT4 REFERENCES login (loginid) NOT NULL,
190
CREATE TABLE project_submission (
191
submissionid SERIAL PRIMARY KEY,
192
assessedid INT4 REFERENCES assessed (assessedid) NOT NULL,
193
path VARCHAR NOT NULL,
194
revision INT4 NOT NULL,
195
date_submitted TIMESTAMP NOT NULL,
196
submitter INT4 REFERENCES login (loginid) NOT NULL
199
CREATE TABLE project_mark (
200
assessedid INT4 REFERENCES assessed (assessedid) NOT NULL,
202
marker INT4 REFERENCES login (loginid) NOT NULL,
209
CREATE TABLE exercise (
210
identifier TEXT PRIMARY KEY CHECK (valid_url_name(identifier)),
213
description_xhtml_cache TEXT,
220
CREATE TABLE worksheet (
221
worksheetid SERIAL PRIMARY KEY,
222
offeringid INT4 REFERENCES offering (offeringid) NOT NULL,
223
identifier TEXT NOT NULL CHECK (valid_url_name(identifier)),
226
data_xhtml_cache TEXT,
227
assessable BOOLEAN NOT NULL,
228
published BOOLEAN NOT NULL DEFAULT true,
229
seq_no INT4 NOT NULL,
230
format TEXT NOT NUll,
231
UNIQUE (offeringid, identifier)
234
CREATE TABLE worksheet_exercise (
235
ws_ex_id SERIAL PRIMARY KEY,
236
worksheetid INT4 REFERENCES worksheet (worksheetid) NOT NULL,
237
exerciseid TEXT REFERENCES exercise (identifier) NOT NULL,
238
seq_no INT4 NOT NULL,
239
active BOOLEAN NOT NULL DEFAULT true,
240
optional BOOLEAN NOT NULL,
241
UNIQUE (worksheetid, exerciseid)
244
CREATE TABLE exercise_attempt (
245
loginid INT4 REFERENCES login (loginid) NOT NULL,
246
ws_ex_id INT4 REFERENCES worksheet_exercise (ws_ex_id) NOT NULL,
247
date TIMESTAMP NOT NULL,
248
attempt TEXT NOT NULL,
249
complete BOOLEAN NOT NULL,
250
active BOOLEAN NOT NULL DEFAULT true,
251
PRIMARY KEY (loginid, ws_ex_id, date)
254
CREATE TABLE exercise_save (
255
loginid INT4 REFERENCES login (loginid) NOT NULL,
256
ws_ex_id INT4 REFERENCES worksheet_exercise (ws_ex_id) NOT NULL,
257
date TIMESTAMP NOT NULL,
259
PRIMARY KEY (loginid, ws_ex_id)
262
CREATE TABLE test_suite (
263
suiteid SERIAL PRIMARY KEY,
264
exerciseid TEXT REFERENCES exercise (identifier) NOT NULL,
271
CREATE TABLE test_case (
272
testid SERIAL PRIMARY KEY,
273
suiteid INT4 REFERENCES test_suite (suiteid) NOT NULL,
280
CREATE TABLE suite_variable (
281
varid SERIAL PRIMARY KEY,
282
suiteid INT4 REFERENCES test_suite (suiteid) NOT NULL,
285
var_type TEXT NOT NULL,
289
CREATE TABLE test_case_part (
290
partid SERIAL PRIMARY KEY,
291
testid INT4 REFERENCES test_case (testid) NOT NULL,
292
part_type TEXT NOT NULL,
28
login varchar(80) REFERENCES users (login),
34
login varchar(80) REFERENCES users (login),
38
INSERT INTO users (login,nick) values ('conway', 'Tom');
39
INSERT INTO roles (login,role) values ('conway', 'student');
40
INSERT INTO users (login,nick) values ('apeel', 'Andrew');
41
INSERT INTO roles (login,role) values ('apeel', 'student');
42
INSERT INTO users (login,nick) values ('mgiuca', 'Matt');
43
INSERT INTO roles (login,role) values ('mgiuca', 'tutor');
44
INSERT INTO users (login,nick) values ('sb', 'Steven');
45
INSERT INTO roles (login,role) values ('sb', 'lecturer');
46
INSERT INTO users (login,nick) values ('mpp', 'Mike');
47
INSERT INTO roles (login,role) values ('mpp', 'student');
48
INSERT INTO users (login,nick) values ('ivo', 'Ivo');
49
INSERT INTO roles (login,role) values ('ivo', 'admin');
51
INSERT INTO groups (groupid, nick, subject, year) values ('2007-INFO10001-321', 'Purple Alert', 'INFO10001', '2008');
52
INSERT INTO groups (groupid, nick, subject, year) values ('2007-INFO10001-322', 'Blind Illuminati', 'INFO10001', '2008');
54
INSERT INTO group_members (login,groupid) values ('conway', '2007-INFO10001-321');
55
INSERT INTO group_members (login,groupid) values ('apeel', '2007-INFO10001-321');
56
INSERT INTO group_members (login,groupid) values ('mgiuca', '2007-INFO10001-321');
57
INSERT INTO group_members (login,groupid) values ('sb', '2007-INFO10001-321');
58
INSERT INTO group_members (login,groupid) values ('mpp', '2007-INFO10001-322');
59
INSERT INTO group_members (login,groupid) values ('ivo', '2007-INFO10001-322');
61
INSERT INTO enrolment (login,subject,year) values ('conway' , 'INFO10001', '2008');
62
INSERT INTO enrolment (login,subject,year) values ('apeel' , 'INFO10001', '2008');
63
INSERT INTO enrolment (login,subject,year) values ('mgiuca' , 'INFO10001', '2008');
64
INSERT INTO enrolment (login,subject,year) values ('sb' , 'INFO10001', '2008');
65
INSERT INTO enrolment (login,subject,year) values ('mpp' , 'INFO10001', '2008');
66
INSERT INTO enrolment (login,subject,year) values ('ivo' , 'INFO10001', '2008');