DatabaseCreation: DDL_manual.sql

File DDL_manual.sql, 22.7 KB (added by 231082, 4 days ago)

Manually written DDL.

Line 
1CREATE TABLE Member (
2 id INTEGER GENERATED ALWAYS AS IDENTITY,
3
4 name TEXT,
5 surname TEXT,
6 username TEXT,
7 password_hash TEXT,
8 date_birth DATE,
9 is_active BOOLEAN DEFAULT TRUE,
10 created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
11 updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
12
13
14 CONSTRAINT pk_member PRIMARY KEY(id),
15
16 CONSTRAINT nn_member_name CHECK(name IS NOT NULL),
17 CONSTRAINT nn_member_surname CHECK(surname IS NOT NULL),
18 CONSTRAINT uq_member_username UNIQUE(username),
19 CONSTRAINT nn_member_username CHECK(username IS NOT NULL),
20 CONSTRAINT nn_member_password_hash CHECK(password_hash IS NOT NULL),
21 CONSTRAINT nn_member_date_birth CHECK(date_birth IS NOT NULL),
22 CONSTRAINT nn_member_created_at CHECK(created_at IS NOT NULL),
23
24 CONSTRAINT ck_member_created_before_updated CHECK(created_at <= updated_at)
25);
26
27CREATE TABLE Member_Message (
28 id INTEGER GENERATED ALWAYS AS IDENTITY,
29
30 member_id1 INTEGER,
31 member_id2 INTEGER,
32
33 message TEXT,
34 sent_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
35
36
37 CONSTRAINT pk_member_message PRIMARY KEY(id, member_id1, member_id2),
38
39 CONSTRAINT fk_member_message_member_id1 FOREIGN KEY(member_id1)
40 REFERENCES Member (id)
41 ON DELETE SET NULL ON UPDATE CASCADE,
42 CONSTRAINT fk_member_message_member_id2 FOREIGN KEY(member_id2)
43 REFERENCES Member (id)
44 ON DELETE SET NULL ON UPDATE CASCADE,
45
46 CONSTRAINT nn_member_message_message CHECK(message IS NOT NULL),
47 CONSTRAINT nn_member_message_sent_at CHECK(sent_at IS NOT NULL)
48);
49
50CREATE TABLE Student (
51 id INTEGER,
52
53 index TEXT,
54
55
56 CONSTRAINT pk_student PRIMARY KEY(id),
57
58 CONSTRAINT fk_student_id FOREIGN KEY(id)
59 REFERENCES Member (id)
60 ON DELETE SET NULL ON UPDATE CASCADE,
61
62 CONSTRAINT uq_student_index UNIQUE(index),
63 CONSTRAINT nn_student_index CHECK(index IS NOT NULL),
64 CONSTRAINT ck_student_index CHECK(index ~ '^\d{10}$')
65);
66
67CREATE TABLE Teacher (
68 id INTEGER,
69
70 date_registration DATE,
71
72
73 CONSTRAINT pk_teacher PRIMARY KEY(id),
74
75 CONSTRAINT fk_teacher FOREIGN KEY(id)
76 REFERENCES Member (id)
77 ON DELETE SET NULL ON UPDATE CASCADE,
78
79 CONSTRAINT nn_teacher_date_registration CHECK(date_registration IS NOT NULL)
80);
81
82CREATE TABLE Teaching_Assistant (
83 id INTEGER GENERATED ALWAYS AS IDENTITY,
84 student_id INTEGER,
85 teacher_id INTEGER,
86
87
88 CONSTRAINT pk_teaching_assistant PRIMARY KEY(id, student_id, teacher_id),
89
90 CONSTRAINT fk_teaching_assistant_student_id FOREIGN KEY(student_id)
91 REFERENCES Student(id)
92 ON DELETE SET NULL ON UPDATE CASCADE,
93 CONSTRAINT fk_teaching_assistant_teacher_id FOREIGN KEY(teacher_id)
94 REFERENCES Teacher(id)
95 ON DELETE SET NULL ON UPDATE CASCADE
96);
97
98CREATE TABLE Academic_Program (
99 code TEXT,
100
101 name TEXT,
102 numeric_id SMALLINT,
103 duration_years SMALLINT,
104 created_at DATE,
105 updated_at DATE,
106
107
108 CONSTRAINT pk_academic_program PRIMARY KEY(code),
109
110 CONSTRAINT nn_academic_program_name CHECK(name IS NOT NULL),
111 CONSTRAINT nn_academic_program_created_at CHECK(created_at IS NOT NULL),
112 CONSTRAINT nn_academic_program_updated_at CHECK(updated_at IS NOT NULL),
113 CONSTRAINT ck_academic_program_updated_after_created CHECK(updated_at >= created_at),
114 CONSTRAINT ck_academic_program_duration_years CHECK (duration_years >= 1 AND duration_years <= 6)
115);
116
117CREATE TABLE Program_Enrollment (
118 id INTEGER GENERATED ALWAYS AS IDENTITY,
119
120 student_id INTEGER,
121
122 date_enrollment DATE,
123 date_disenrollment DATE,
124 finished BOOLEAN,
125
126 academic_program_code TEXT,
127
128
129 CONSTRAINT pk_program_enrollment_id PRIMARY KEY(id),
130
131 CONSTRAINT fk_program_enrollment_student_id FOREIGN KEY(student_id)
132 REFERENCES Student(id)
133 ON DELETE SET NULL ON UPDATE CASCADE,
134 CONSTRAINT fk_program_enrollment_academic_program_code FOREIGN KEY(academic_program_code)
135 REFERENCES Academic_Program(code)
136 ON DELETE SET NULL ON UPDATE CASCADE,
137
138 CONSTRAINT uq_program_enrollment_1 UNIQUE(student_id, academic_program_code, date_enrollment),
139 CONSTRAINT nn_program_enrollment_student_id CHECK(student_id IS NOT NULL),
140 CONSTRAINT nn_program_enrollment_academic_program_code CHECK(academic_program_code IS NOT NULL),
141 CONSTRAINT nn_program_enrollment_date_enrollment CHECK(date_enrollment IS NOT NULL)
142);
143
144CREATE TABLE Course (
145 code TEXT,
146
147 name TEXT,
148 credits INT,
149 created_at DATE,
150
151
152 CONSTRAINT pk_course PRIMARY KEY(code),
153
154 CONSTRAINT nn_course_name CHECK(name IS NOT NULL),
155 CONSTRAINT nn_course_credits CHECK(credits IS NOT NULL),
156 CONSTRAINT nn_course_created_at CHECK(created_at IS NOT NULL),
157 CONSTRAINT ck_course_credits CHECK(credits >= 0)
158);
159
160CREATE TABLE Curriculum (
161 academic_program_code TEXT,
162 course_code TEXT,
163
164 semester SMALLINT,
165 mandatory BOOLEAN,
166
167
168 CONSTRAINT pk_curriculum PRIMARY KEY(academic_program_code, course_code),
169
170 CONSTRAINT fk_curriculum_academic_program_code FOREIGN KEY(academic_program_code)
171 REFERENCES Academic_Program(code)
172 ON DELETE SET NULL ON UPDATE CASCADE,
173 CONSTRAINT fk_curriculum_course_code FOREIGN KEY(course_code)
174 REFERENCES Course(code)
175 ON DELETE SET NULL ON UPDATE CASCADE,
176
177 CONSTRAINT nn_curriculum_semester CHECK(semester IS NOT NULL),
178 CONSTRAINT nn_curriculum_mandatory CHECK(mandatory IS NOT NULL)
179);
180
181CREATE TABLE Course_Prerequisite (
182 predecessor_course_code TEXT,
183 successor_course_code TEXT,
184
185
186 CONSTRAINT pk_course_prerequisite PRIMARY KEY(predecessor_course_code, successor_course_code),
187
188 CONSTRAINT fk_course_prerequisite_predecessor_course_code FOREIGN KEY(predecessor_course_code)
189 REFERENCES Course(code)
190 ON DELETE SET NULL ON UPDATE CASCADE,
191 CONSTRAINT fk_course_prerequisite_successor_course_code FOREIGN KEY(successor_course_code)
192 REFERENCES Course(code)
193 ON DELETE SET NULL ON UPDATE CASCADE,
194
195 CONSTRAINT ck_course_prerequisite_different_courses CHECK(predecessor_course_code <> successor_course_code)
196);
197
198CREATE TABLE Course_Equivalence (
199 course1_code TEXT,
200 course2_code TEXT,
201
202
203 CONSTRAINT pk_course_equivalence PRIMARY KEY(course1_code, course2_code),
204
205 CONSTRAINT fk_course_equivalence_course1_code FOREIGN KEY(course1_code)
206 REFERENCES Course(code)
207 ON DELETE SET NULL ON UPDATE CASCADE,
208 CONSTRAINT fk_course_equivalence_course2_code FOREIGN KEY(course2_code)
209 REFERENCES Course(code)
210 ON DELETE SET NULL ON UPDATE CASCADE,
211
212 CONSTRAINT ck_course_equivalence_different_courses CHECK(course1_code <> course2_code)
213);
214
215CREATE TABLE Course_Edition (
216 id INTEGER GENERATED ALWAYS AS IDENTITY,
217
218 course_code TEXT,
219 academic_year SMALLINT,
220 semester SMALLINT,
221
222
223 CONSTRAINT pk_course_edition PRIMARY KEY(id),
224
225 CONSTRAINT fk_course_edition FOREIGN KEY(course_code)
226 REFERENCES Course(code)
227 ON DELETE SET NULL ON UPDATE CASCADE,
228
229 CONSTRAINT uq_course_edition_ccays UNIQUE(course_code, academic_year, semester),
230 CONSTRAINT nn_course_edition_academic_year CHECK(academic_year IS NOT NULL),
231 CONSTRAINT nn_course_edition_semester CHECK(semester IS NOT NULL),
232 CONSTRAINT ck_course_edition_semester CHECK(semester >= 1 AND semester <= 2)
233);
234
235CREATE TABLE Teaches (
236 teacher_id INTEGER,
237 course_edition_id INTEGER,
238
239
240 CONSTRAINT pk_teaches PRIMARY KEY(teacher_id, course_edition_id),
241
242 CONSTRAINT fk_teaches_teacher_id FOREIGN KEY(teacher_id)
243 REFERENCES Teacher(id)
244 ON DELETE SET NULL ON UPDATE CASCADE,
245 CONSTRAINT fk_teaches_course_edition_id FOREIGN KEY(course_edition_id)
246 REFERENCES Course_Edition(id)
247 ON DELETE SET NULL ON UPDATE CASCADE
248);
249
250CREATE TABLE Announcement (
251 id INTEGER GENERATED ALWAYS AS IDENTITY,
252
253 teaches_teacher_id INTEGER,
254 teaches_course_edition_id INTEGER,
255
256 message TEXT,
257 sent_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
258
259
260 CONSTRAINT pk_announcement PRIMARY KEY(id, teaches_teacher_id, teaches_course_edition_id),
261
262 CONSTRAINT fk_announcement_teaches FOREIGN KEY(teaches_teacher_id, teaches_course_edition_id)
263 REFERENCES Teaches(teacher_id, course_edition_id)
264 ON DELETE SET NULL ON UPDATE CASCADE,
265
266 CONSTRAINT ck_announcement_message CHECK(message IS NOT NULL),
267 CONSTRAINT ck_announcement_sent_at CHECK(sent_at IS NOT NULL)
268);
269
270CREATE TABLE Announcement_Replies (
271 ann1_id INTEGER,
272 ann1_ttid INTEGER,
273 ann1_ceid INTEGER,
274 ann2_id INTEGER,
275 ann2_ttid INTEGER,
276 ann2_ceid INTEGER,
277
278
279 CONSTRAINT pk_announcement_replies
280 PRIMARY KEY(
281 ann1_id,
282 ann1_ttid,
283 ann1_ceid,
284 ann2_id,
285 ann2_ttid,
286 ann2_ceid
287 ),
288
289 CONSTRAINT fk_announcement_replies_ann1 FOREIGN KEY(ann1_id, ann1_ttid, ann1_ceid)
290 REFERENCES Announcement(id, teaches_teacher_id, teaches_course_edition_id)
291 ON DELETE SET NULL ON UPDATE CASCADE,
292 CONSTRAINT fk_announcement_replies_ann2 FOREIGN KEY(ann2_id, ann2_ttid, ann2_ceid)
293 REFERENCES Announcement(id, teaches_teacher_id, teaches_course_edition_id)
294 ON DELETE SET NULL ON UPDATE CASCADE,
295
296 CONSTRAINT ck_announcement_replies_different_replies CHECK ( NOT (ann1_id = ann2_id AND ann1_ttid = ann2_ttid AND ann1_ceid = ann2_ceid) )
297);
298
299CREATE TABLE Lecture (
300 id INTEGER GENERATED ALWAYS AS IDENTITY,
301
302 course_edition_id INTEGER,
303
304 title TEXT,
305 content_url TEXT,
306 created_at TIMESTAMP WITHOUT TIME ZONE,
307
308
309 CONSTRAINT pk_lecture PRIMARY KEY(id),
310
311 CONSTRAINT fk_lecture FOREIGN KEY(course_edition_id)
312 REFERENCES Course_Edition(id)
313 ON DELETE SET NULL ON UPDATE CASCADE,
314
315 CONSTRAINT nn_lecture_title CHECK (title IS NOT NULL),
316 CONSTRAINT nn_lecture_created_at CHECK (created_at IS NOT NULL)
317);
318
319CREATE TABLE Semester_Enrollment (
320 id INTEGER GENERATED ALWAYS AS IDENTITY,
321
322 program_enrollment_id INTEGER,
323
324 academic_year SMALLINT,
325 semester SMALLINT,
326
327
328 CONSTRAINT pk_semester_enrollment PRIMARY KEY(id),
329
330 CONSTRAINT fk_semester_enrollment FOREIGN KEY(program_enrollment_id)
331 REFERENCES Program_Enrollment(id)
332 ON DELETE SET NULL ON UPDATE CASCADE,
333
334 CONSTRAINT uq_semester_enrollment_peidays UNIQUE(program_enrollment_id, academic_year, semester),
335 CONSTRAINT nn_semester_enrollment_academic_year CHECK(academic_year IS NOT NULL),
336 CONSTRAINT nn_semester_enrollment_semester CHECK(semester IS NOT NULL),
337 CONSTRAINT ck_semester_enrollment_academic_year CHECK(academic_year >= 2000),
338 CONSTRAINT ck_semester_enrollment_semester CHECK(semester >= 1 AND semester <= 2)
339);
340
341CREATE TABLE Course_Enrollment (
342 id INTEGER GENERATED ALWAYS AS IDENTITY,
343
344 semester_enrollment_id INTEGER,
345 course_edition_id INTEGER,
346
347
348 CONSTRAINT pk_course_enrollment PRIMARY KEY(id),
349
350 CONSTRAINT fk_course_enrollment_seid FOREIGN KEY(semester_enrollment_id)
351 REFERENCES Semester_Enrollment(id)
352 ON DELETE SET NULL ON UPDATE CASCADE,
353 CONSTRAINT fk_course_enrollment_ceid FOREIGN KEY(course_edition_id)
354 REFERENCES Course_Edition(id)
355 ON DELETE SET NULL ON UPDATE CASCADE,
356
357 CONSTRAINT uq_course_enrollment_course_once_per_semenroll UNIQUE(semester_enrollment_id, course_edition_id)
358);
359
360CREATE TABLE Exercise (
361 id INTEGER GENERATED ALWAYS AS IDENTITY,
362
363 course_edition_id INTEGER,
364
365 title TEXT,
366 task TEXT,
367 expected_result TEXT,
368 deadline DATE,
369 max_grade INTEGER,
370 created_at DATE,
371
372
373 CONSTRAINT pk_exercise PRIMARY KEY(id),
374
375 CONSTRAINT fk_exercise FOREIGN KEY(course_edition_id)
376 REFERENCES Course_Edition(id)
377 ON DELETE SET NULL ON UPDATE CASCADE,
378
379 CONSTRAINT nn_exercise_title CHECK(title IS NOT NULL),
380 CONSTRAINT nn_exercise_task CHECK(task IS NOT NULL),
381 CONSTRAINT nn_exercise_expected_result CHECK(expected_result IS NOT NULL),
382 CONSTRAINT nn_exercise_max_grade CHECK(max_grade IS NOT NULL),
383 CONSTRAINT nn_exercise_created_at CHECK(created_at IS NOT NULL),
384 CONSTRAINT ck_exercise_max_grade CHECK(max_grade > 0),
385 CONSTRAINT ck_exercise_deadline_after_created CHECK (deadline IS NULL OR deadline > created_at)
386);
387
388CREATE TABLE Exercise_Submission (
389 id INTEGER GENERATED ALWAYS AS IDENTITY,
390
391 exercise_id INTEGER,
392 course_enrollment_id INTEGER,
393
394 content TEXT,
395 grade INTEGER,
396 submitted_at TIMESTAMP WITHOUT TIME ZONE,
397 graded_at TIMESTAMP WITHOUT TIME ZONE,
398
399
400 CONSTRAINT pk_exercise_submission PRIMARY KEY(id, exercise_id, course_enrollment_id),
401
402 CONSTRAINT fk_exercise_submission_exercise_id FOREIGN KEY(exercise_id)
403 REFERENCES Exercise(id)
404 ON DELETE SET NULL ON UPDATE CASCADE,
405 CONSTRAINT fk_exercise_submission_ceid FOREIGN KEY(course_enrollment_id)
406 REFERENCES Course_Enrollment(id)
407 ON DELETE SET NULL ON UPDATE CASCADE,
408
409 CONSTRAINT nn_exercise_submission_content CHECK(content IS NOT NULL),
410 CONSTRAINT nn_exercise_submission_submission_submitted_at CHECK(submitted_at IS NOT NULL),
411 CONSTRAINT ck_exercise_submission_submission_graded_after_submitted CHECK (graded_at >= submitted_at),
412 CONSTRAINT ck_exercise_submission_submission_grade_graded_at CHECK((grade IS NULL AND graded_at IS NULL) OR (grade IS NOT NULL AND graded_at IS NOT NULL))
413);
414
415CREATE TABLE Survey (
416 id INTEGER GENERATED ALWAYS AS IDENTITY,
417
418 course_edition_id INTEGER,
419 title TEXT,
420 open_until TIMESTAMP WITHOUT TIME ZONE,
421
422
423 CONSTRAINT pk_survey PRIMARY KEY(id),
424
425 CONSTRAINT fk_survey FOREIGN KEY(course_edition_id)
426 REFERENCES Course_Edition(id)
427 ON DELETE SET NULL ON UPDATE CASCADE,
428
429 CONSTRAINT nn_survey_title CHECK(title IS NOT NULL)
430);
431
432CREATE TABLE Survey_Option (
433 option TEXT,
434
435 survey_id INTEGER,
436
437 capacity INTEGER,
438
439
440 CONSTRAINT pk_survey_option PRIMARY KEY(option, survey_id),
441
442 CONSTRAINT fk_survey_option FOREIGN KEY(survey_id)
443 REFERENCES Survey(id)
444 ON DELETE SET NULL ON UPDATE CASCADE,
445
446 CONSTRAINT ck_survey_option_capacity CHECK(capacity > 0)
447);
448
449CREATE TABLE Survey_Response (
450 option_text TEXT,
451
452 survey_id INTEGER,
453 course_enrollment_id INTEGER,
454
455 responded_at TIMESTAMP WITHOUT TIME ZONE,
456
457
458 CONSTRAINT pk_survey_response PRIMARY KEY(option_text, survey_id, course_enrollment_id),
459
460 CONSTRAINT fk_survey_response_survey_id FOREIGN KEY(survey_id)
461 REFERENCES Survey(id)
462 ON DELETE SET NULL ON UPDATE CASCADE,
463
464 CONSTRAINT fk_survey_response_ceid FOREIGN KEY(course_enrollment_id)
465 REFERENCES Course_Enrollment(id)
466 ON DELETE SET NULL ON UPDATE CASCADE,
467
468 CONSTRAINT nn_survey_response_responded_at CHECK(responded_at IS NOT NULL)
469);
470
471CREATE TABLE Exam (
472 id INTEGER GENERATED ALWAYS AS IDENTITY,
473
474 course_edition_id INTEGER,
475
476 type EXAM_TYPE,
477 scheduled_at TIMESTAMP WITHOUT TIME ZONE,
478 duration_minutes SMALLINT,
479
480
481 CONSTRAINT pk_exam PRIMARY KEY(id),
482
483 CONSTRAINT fk_exam FOREIGN KEY(course_edition_id)
484 REFERENCES Course_Edition(id)
485 ON DELETE SET NULL ON UPDATE CASCADE,
486
487 CONSTRAINT nn_exam_type CHECK(type IS NOT NULL),
488 CONSTRAINT ck_exam_duration_minutes CHECK(duration_minutes > 0)
489);
490
491CREATE TABLE Exam_Attempt (
492 attempt_number SMALLINT,
493 exam_id INTEGER,
494 course_enrollment_id INTEGER,
495
496 total_points FLOAT,
497 submitted_at TIMESTAMP WITHOUT TIME ZONE,
498
499
500 CONSTRAINT pk_exam_attempt PRIMARY KEY(attempt_number, exam_id, course_enrollment_id),
501
502 CONSTRAINT fk_exam_attempt_exam_id FOREIGN KEY(exam_id)
503 REFERENCES Exam(id)
504 ON DELETE SET NULL ON UPDATE CASCADE,
505 CONSTRAINT fk_exam_attempt_ceid FOREIGN KEY(course_enrollment_id)
506 REFERENCES Course_Enrollment(id)
507 ON DELETE SET NULL ON UPDATE CASCADE,
508
509 CONSTRAINT nn_exam_attempt_submitted_at CHECK(submitted_at IS NOT NULL),
510 CONSTRAINT nn_exam_attempt_total_points CHECK(total_points IS NOT NULL),
511 CONSTRAINT ck_exam_attempt_total_points CHECK(total_points >= 0)
512);
513
514CREATE TABLE Exam_Problem (
515 id INTEGER GENERATED ALWAYS AS IDENTITY,
516 exam_id INTEGER,
517
518 description TEXT,
519 expected TEXT,
520 points FLOAT,
521
522
523 CONSTRAINT pk_exam_problem PRIMARY KEY(id, exam_id),
524
525 CONSTRAINT fk_exam_problem FOREIGN KEY(exam_id)
526 REFERENCES Exam(id)
527 ON DELETE SET NULL ON UPDATE CASCADE,
528
529 CONSTRAINT nn_exam_problem_description CHECK(description IS NOT NULL),
530 CONSTRAINT nn_exam_problem_expected CHECK(expected IS NOT NULL),
531 CONSTRAINT nn_exam_problem_points CHECK(points IS NOT NULL),
532 CONSTRAINT ck_exam_problem_points CHECK(points > 0.0)
533);
534
535CREATE TABLE Student_Answer (
536 exam_id INTEGER,
537 exam_problem_id INTEGER,
538 exam_attempt_ceid INTEGER,
539
540 exam_attempt_attempt_number SMALLINT,
541 answer TEXT,
542 points_acquired FLOAT,
543
544
545 CONSTRAINT pk_student_answer
546 PRIMARY KEY(
547 exam_id,
548 exam_problem_id,
549 exam_attempt_ceid,
550 exam_attempt_attempt_number
551 ),
552
553 CONSTRAINT fk_student_answer_exam FOREIGN KEY(exam_id)
554 REFERENCES Exam(id)
555 ON DELETE SET NULL ON UPDATE CASCADE,
556 CONSTRAINT fk_student_answer_exam_problem FOREIGN KEY(exam_id, exam_problem_id)
557 REFERENCES Exam_Problem(exam_id, id)
558 ON DELETE SET NULL ON UPDATE CASCADE,
559 CONSTRAINT fk_student_answer_exam_attempt FOREIGN KEY(exam_id, exam_attempt_ceid, exam_attempt_attempt_number)
560 REFERENCES Exam_Attempt(exam_id, course_enrollment_id, attempt_number)
561 ON DELETE SET NULL ON UPDATE CASCADE,
562
563 CONSTRAINT nn_student_answer_points_acquired CHECK(points_acquired IS NOT NULL),
564 CONSTRAINT ck_student_answer_points_acquired CHECK(points_acquired >= 0)
565);
566
567CREATE TABLE Exam_Results (
568 id INTEGER GENERATED ALWAYS AS IDENTITY,
569
570 data jsonb,
571 exported_at TIMESTAMP WITHOUT TIME ZONE,
572
573 teaches_teacher_id INTEGER,
574 teaches_course_edition_id INTEGER,
575 exam_id INTEGER,
576
577
578 CONSTRAINT pk_exam_results PRIMARY KEY (id),
579
580 CONSTRAINT fk_exam_results_teaches FOREIGN KEY (teaches_teacher_id, teaches_course_edition_id)
581 REFERENCES Teaches (teacher_id, course_edition_id)
582 ON DELETE SET NULL ON UPDATE CASCADE,
583 CONSTRAINT fk_exam_results_exam FOREIGN KEY (exam_id)
584 REFERENCES Exam (id)
585 ON DELETE SET NULL ON UPDATE CASCADE,
586
587 CONSTRAINT uq_exam_results_ette UNIQUE (exported_at, teaches_teacher_id, teaches_course_edition_id, exam_id),
588 CONSTRAINT nn_exam_results_exported_at CHECK (exported_at IS NOT NULL),
589 CONSTRAINT nn_exam_results_data CHECK (data IS NOT NULL),
590 CONSTRAINT ck_exam_results_exported_at CHECK (exported_at <= CURRENT_TIMESTAMP),
591 CONSTRAINT ck_exam_results_data CHECK (fn_validate_exam_data(data))
592);
593
594CREATE TABLE Aggregated_Course_Edition_Results (
595 id INTEGER GENERATED ALWAYS AS IDENTITY,
596
597 data jsonb,
598 exported_at TIMESTAMP WITHOUT TIME ZONE,
599
600 teaches_teacher_id INTEGER,
601 teaches_course_edition_id INTEGER,
602
603
604 CONSTRAINT pk_aggregated_course_edition_results PRIMARY KEY (id),
605
606 CONSTRAINT fk_aggregated_results_teaches FOREIGN KEY (teaches_teacher_id, teaches_course_edition_id)
607 REFERENCES Teaches (teacher_id, course_edition_id)
608 ON DELETE SET NULL ON UPDATE CASCADE,
609
610 CONSTRAINT uq_aggregated_results_ette UNIQUE (exported_at, teaches_teacher_id, teaches_course_edition_id),
611 CONSTRAINT nn_aggregated_results_exported_at CHECK (exported_at IS NOT NULL),
612 CONSTRAINT nn_aggregated_results_data CHECK (data IS NOT NULL),
613 CONSTRAINT ck_aggregated_results_data CHECK (fn_validate_aggregated_data(data))
614);
615
616CREATE TABLE Student_Grade (
617 course_enrollment_id INTEGER,
618
619 grade SMALLINT,
620 graded_at DATE,
621
622 aggr_course_edition_res_id INTEGER,
623
624
625 CONSTRAINT pk_student_grade PRIMARY KEY(course_enrollment_id),
626
627 CONSTRAINT fk_student_grade FOREIGN KEY(course_enrollment_id)
628 REFERENCES Course_Enrollment(id)
629 ON DELETE SET NULL ON UPDATE CASCADE,
630
631 CONSTRAINT fk_student_aceri FOREIGN KEY(aggr_course_edition_res_id)
632 REFERENCES Aggregated_Course_Edition_Results(id)
633 ON DELETE SET NULL ON UPDATE CASCADE,
634
635 CONSTRAINT nn_student_grade_grade CHECK(grade IS NOT NULL),
636 CONSTRAINT nn_student_grade_graded_at CHECK(graded_at IS NOT NULL),
637 CONSTRAINT ck_student_grade_grade CHECK(grade >= 6 AND grade <= 10)
638);