DROP TABLE IF EXISTS Artysta CASCADE; DROP TABLE IF EXISTS Galeria CASCADE; DROP TABLE IF EXISTS Instytucja CASCADE; DROP TABLE IF EXISTS Eksponat CASCADE; DROP TABLE IF EXISTS HistoriaWystawienWGalerii CASCADE; DROP TABLE IF EXISTS HistoriaMagazynowania CASCADE; DROP TABLE IF EXISTS HistoriaWypozyczenWInstytucji CASCADE; create table Artysta( id_artysty integer PRIMARY KEY, imie varchar(15) NOT NULL, nazwisko varchar(20) NOT NULL, rok_urodzenia integer NOT NULL, rok_smierci integer ); create table Galeria( id integer PRIMARY KEY, nazwa varchar(30) NOT NULL, sala integer NOT NULL ); create table Instytucja( id integer PRIMARY KEY, nazwa varchar(35) NOT NULL, miasto varchar(15) NOT NULL, typ varchar(40) NOT NULL ); create table Eksponat( id integer PRIMARY KEY, tytul varchar(50) NOT NULL, typ varchar(20) NOT NULL, id_artysty integer REFERENCES Artysta, szerokosc integer NOT NULL check (szerokosc>0), wysokosc integer NOT NULL check (wysokosc>0), waga integer NOT NULL check(waga>0), najcenniejszy char(3) check (najcenniejszy in ('tak', 'nie')) NOT NULL ); create table HistoriaWystawienWGalerii( id_wystawy integer PRIMARY KEY, galeria_id integer REFERENCES Galeria, sala integer NOT NULL, eksponat_id integer NOT NULL REFERENCES Eksponat, rozpoczecie date NOT NULL, zakonczenie date ); create table HistoriaMagazynowania( id_magazynu integer PRIMARY KEY, eksponat_id integer REFERENCES Eksponat, rozpoczecie date NOT NULL, zakonczenie date ); create table HistoriaWypozyczenWInstytucji( id integer PRIMARY KEY, eksponat_id integer REFERENCES Eksponat, instytucja_id integer REFERENCES Instytucja, rozpoczecie date NOT NULL, zakonczenie date ); CREATE OR REPLACE FUNCTION limitdni() RETURNS TRIGGER AS $$ DECLARE dnipoza INTEGER; BEGIN SELECT SUM(COALESCE(zakonczenie, CURRENT_DATE) - rozpoczecie) INTO dnipoza FROM HistoriaWystawienWGalerii WHERE NEW.eksponat_id = eksponat_id IF dnipoza>30 THEN RAISE EXCEPTION 'Eksponat nie powinien przebywać poza muzeum dłużej niż 30 dni rocznie'; END IF; RETURN NEW; END; $$ LANGUAGE 'plpgsql'; CREATE OR REPLACE FUNCTION eksponatartysty() RETURNS TRIGGER AS $$ BEGIN IF EXISTS ( SELECT 1 FROM Artysta a WHERE NOT EXISTS ( SELECT 1 FROM Eksponat e LEFT JOIN HistoriaWystawienWGalerii hwg ON e.id = hwg.eksponat_id LEFT JOIN HistoriaMagazynowania hm ON e.id = hm.eksponat_id LEFT JOIN HistoriaWypozyczenWInstytucji hwi ON e.id = hwi.eksponat_id WHERE e.id_artysty = a.id_artysty AND ( hwg.id_wystawy IS NOT NULL OR (hm.id_magazynu IS NOT NULL AND hm.zakonczenie IS NULL) OR (hwi.id IS NOT NULL AND hwi.zakonczenie IS NULL) ) ) ) THEN RAISE EXCEPTION 'Muzeum powinno zawsze mieć w swoich galeriach lub w magazynie co najmniej jeden eksponat każdego artysty!'; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE TRIGGER kontrola_artysty BEFORE INSERT OR UPDATE ON HistoriaWystawienWGalerii FOR EACH ROW EXECUTE FUNCTION eksponatartysty(); CREATE OR REPLACE TRIGGER kontrola_artysty_magazyn BEFORE INSERT OR UPDATE ON HistoriaMagazynowania FOR EACH ROW EXECUTE FUNCTION eksponatartysty(); CREATE OR REPLACE TRIGGER kontrola_artysty_wypozyczenia BEFORE INSERT OR UPDATE ON HistoriaWypozyczenWInstytucji FOR EACH ROW EXECUTE FUNCTION eksponatartysty(); CREATE OR REPLACE TRIGGER kontrola_limitu_dni_wystawien BEFORE INSERT OR UPDATE ON HistoriaWystawienWGalerii FOR EACH ROW EXECUTE FUNCTION limitdni; CREATE OR REPLACE TRIGGER kontrola_limitu_dni_magazyn BEFORE INSERT OR UPDATE ON HistoriaMagazynowania FOR EACH ROW EXECUTE FUNCTION limitdni; CREATE OR REPLACE TRIGGER kontrola_limitu_dni_wypozyczen BEFORE INSERT OR UPDATE ON HistoriaWypozyczenWInstytucji FOR EACH ROW EXECUTE FUNCTION limitdni; CREATE PROCEDURE dodajeksponat( IN id INTEGER, IN tytul VARCHAR(50), IN typ VARCHAR(20), IN artysta_id INTEGER, IN szerokosc INTEGER, IN wysokosc INTEGER, IN waga INTEGER, IN najcenniejszy CHAR(3) ) BEGIN INSERT INTO Eksponat (id, tytul, typ, artysta_id_artysty, szerokosc, wysokosc, waga, najcenniejszy) VALUES (id, tytul, typ, artysta_id, szerokosc, wysokosc, waga, najcenniejszy); END $$