DROP VIEW studenten_veranstalter; DROP TABLE Veranstalter_Veranstaltung_Uhrzeit; DROP TABLE Studenten; DROP TABLE Veranstalter; DROP TABLE Uhrzeit; DROP TABLE veranstaltung; DROP SEQUENCE global_id_seq; CREATE SEQUENCE global_id_seq START WITH 1000000 INCREMENT BY 1; CREATE TABLE IF NOT EXISTS Studenten ( matrikelnummer INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'), name VARCHAR(30) NOT NULL, email VARCHAR(30) NOT NULL, passwort VARCHAR(30) NOT NULL ); CREATE OR REPLACE FUNCTION random_between_two() RETURNS VARCHAR AS $$ BEGIN IF random() < 0.5 THEN RETURN 'A'; ELSE RETURN 'B'; END IF; END; $$ LANGUAGE plpgsql; CREATE TABLE Uhrzeit ( ID SERIAL PRIMARY KEY, anfangszeit TIME NOT NULL, endzeit TIME NOT NULL ); CREATE TABLE Veranstalter ( ID INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'), name VARCHAR(30), email VARCHAR(30), passwort VARCHAR(30), arbeitszeit INTEGER DEFAULT 0, admin BOOLEAN NOT NULL DEFAULT FALSE ); CREATE VIEW studenten_veranstalter AS SELECT matrikelnummer AS id, passwort, NULL AS admin FROM Studenten UNION ALL SELECT ID, passwort, admin FROM Veranstalter; CREATE TABLE Veranstaltung ( ID SERIAL PRIMARY KEY, ort VARCHAR(1) DEFAULT random_between_two(), raum INTEGER NOT NULL, name VARCHAR(3) NOT NULL, dauer INTEGER NOT NULL, used INTEGER DEFAULT(0) ); CREATE TABLE StundenImPlan( uhrzeit_ID INTEGER REFERENCES Uhrzeit(ID), tag INTEGER NOT NULL, veranstalter_ID INTEGER REFERENCES Veranstalter(ID) ON DELETE CASCADE, veranstaltung_ID INTEGER REFERENCES Veranstaltung(ID) ON DELETE CASCADE, PRIMARY KEY(uhrzeit_ID, tag) ); CREATE TABLE Krankmeldung( uhrzeit_id INTEGER REFERENCES StundenImPlan(uhrzeit_ID), tag INTEGER REFERENCES StundenImPlan(tag), veranstalter_id INTEGER REFERENCES StundenImPlan(veranstalter_ID), PRIMARY KEY (uhrzeit_ID,tag,veranstalter_id) ) CREATE OR REPLACE FUNCTION handle_veranstalter_update() RETURNS TRIGGER AS $$ DECLARE neuer_veranstalter INTEGER; BEGIN -- Wenn die Veranstalter_ID auf NULL gesetzt wird oder ein Veranstalter gelöscht wird IF TG_OP = 'UPDATE' AND NEW.veranstalter_ID IS NULL THEN -- Eintrag in die Krankmeldung INSERT INTO Krankmeldung (uhrzeit_ID, tag, veranstalter_id) VALUES (OLD.uhrzeit_ID, OLD.tag, OLD.veranstalter_ID); ELSIF TG_OP = 'DELETE' THEN -- Eintrag in die Krankmeldung für jede betroffene Stunde INSERT INTO Krankmeldung (uhrzeit_ID, tag, veranstalter_id) SELECT uhrzeit_ID, tag, OLD.ID FROM StundenImPlan WHERE veranstalter_ID = OLD.ID; END IF; -- Finde den Veranstalter mit den wenigsten Arbeitsstunden, -- der am selben Tag keine Veranstaltung in einer anderen Uhrzeit an einem anderen Ort hat SELECT ID INTO neuer_veranstalter FROM Veranstalter WHERE ID NOT IN ( SELECT veranstalter_ID FROM StundenImPlan WHERE tag = OLD.tag AND uhrzeit_ID != OLD.uhrzeit_ID AND veranstaltung_ID IN ( SELECT ID FROM Veranstaltung WHERE ort != ( SELECT ort FROM Veranstaltung WHERE ID = NEW.veranstaltung_ID ) ) ) ORDER BY arbeitszeit ASC LIMIT 1; -- Wenn ein neuer Veranstalter gefunden wurde IF neuer_veranstalter IS NOT NULL THEN IF TG_OP = 'UPDATE' THEN NEW.veranstalter_ID := neuer_veranstalter; ELSIF TG_OP = 'DELETE' THEN UPDATE StundenImPlan SET veranstalter_ID = neuer_veranstalter WHERE veranstalter_ID = OLD.ID; END IF; -- Update der Arbeitszeit des neuen Veranstalters UPDATE Veranstalter SET arbeitszeit = arbeitszeit + ( SELECT dauer FROM Veranstaltung WHERE ID = ( CASE WHEN TG_OP = 'UPDATE' THEN NEW.veranstaltung_ID ELSE OLD.ID END ) ) WHERE ID = neuer_veranstalter; ELSE IF TG_OP = 'DELETE' THEN UPDATE StundenImPlan SET veranstalter_ID = NULL WHERE veranstalter_ID = OLD.ID; END IF; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_handle_veranstalter_update BEFORE UPDATE ON StundenImPlan FOR EACH ROW EXECUTE FUNCTION handle_veranstalter_update(); CREATE TRIGGER trg_handle_veranstalter_delete BEFORE DELETE ON Veranstalter FOR EACH ROW EXECUTE FUNCTION handle_veranstalter_update(); INSERT INTO Uhrzeit (anfangszeit, endzeit) VALUES ('08:00:00', '10:00:00'), ('10:00:00', '12:00:00'), ('12:00:00', '14:00:00'), ('14:00:00', '16:00:00'), ('16:00:00', '18:00:00'); INSERT INTO Veranstalter (name, email, passwort, admin) VALUES ('Davids', 'admin@example.com', 'password123', TRUE), ('Dalitz', 'user1@example.com', 'password1', FALSE), ('Tipp', 'user2@example.com', 'password2', FALSE), ('Quix', 'user3@example.com', 'password3', FALSE), ('Nietsche', 'user4@example.com', 'password4', FALSE), ('Ueberholz', 'user5@example.com', 'password5', FALSE), ('Rethmann', 'user6@example.com', 'password6', FALSE), ('Pohle-Fröhlich', 'user7@example.com', 'password7', FALSE), ('Stockmann', 'user8@example.com', 'password8', FALSE), ('Gref', 'user9@example.com', 'password9', FALSE), ('Naroska', 'user10@example.com', 'password10', FALSE), ('Grothe', 'user11@example.com', 'supersicherespasswort123', FALSE); INSERT INTO Veranstaltung (ort, raum, name, dauer) VALUES ('A', '101', 'GDI', 2), ('B', '202', 'ALD', 4), ('A', '103', 'ITS', 2), ('B', '204', 'BSY', 4), ('A', '105', 'PE1', 2), ('B', '206', 'THI', 4), ('A', '107', 'DBS', 2), ('B', '208', 'WEB', 2), ('A', '109', 'BVA', 2), ('B', '210', 'MA1', 2);