1
Fork 0
mirror of https://github.com/Steffo99/alexandria.git synced 2024-11-24 14:34:19 +00:00

Scrivi un paio di query

This commit is contained in:
Steffo 2020-06-04 17:28:46 +02:00
parent 4c17a4ada4
commit 298466a58d
Signed by: steffo
GPG key ID: 896A80F55F7C97F0
4 changed files with 232 additions and 51 deletions

View file

@ -192,6 +192,31 @@ ALTER TABLE ONLY public.gioco_elemento
ALTER TABLE ONLY public.gioco_elemento
ADD CONSTRAINT istanza_di FOREIGN KEY (istanza_di) REFERENCES public.gioco_edizione(id);
CREATE FUNCTION public.update_n_giochi() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET gioco_elementi_posseduti = gioco_elementi_posseduti - 1
FROM gioco_elemento
WHERE utente.username = old.appartiene_a;
RETURN old;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente
SET gioco_elementi_posseduti = gioco_elementi_posseduti + 1
FROM gioco_elemento
WHERE utente.username = new.appartiene_a;
RETURN new;
END IF;
END;
$$;
CREATE TRIGGER numero_giochi_trigger
BEFORE INSERT OR DELETE
ON public.gioco_elemento
FOR EACH ROW EXECUTE PROCEDURE public.update_n_giochi();
```
Le tabelle degli elementi hanno due colonne `stato` e `provenienza` di tipo `*_stato` e `*_provenienza` rispettivamente: sono gli _ENUM_ creati in precedenza, che impediscono che vengano inseriti valori non consentiti nella tabella.
@ -199,11 +224,43 @@ Le tabelle degli elementi hanno due colonne `stato` e `provenienza` di tipo `*_s
La colonna `id` invece ha un valore di _DEFAULT_ particolare: `nextval('public.elemento_id_seq'::regclass)`.
Significa che, se non viene specificato un `id` durante un _INSERT_, alla riga verrà assegnato automaticamente il valore corrente della _SEQUENCE_, e il valore della sequenza sarà aumentato, garantendo l'**unicità** degli `id` anche attraverso tabelle diverse.
<!--TODO: qui dovremmo scrivere qualcosa sui trigger... quando sono finiti.-->
Inoltre, nella tabella è presente un _TRIGGER_, che incrementa o decrementa il conteggio dei giochi di un utente quando egli rispettivamente crea o elimina nuovi elementi.
### `libro_edizione`
<!--TODO: è pronto il check dell'ISBN?-->
```sql
create function is_numeric(text character varying) returns boolean
strict
language plpgsql
as
$$
DECLARE x NUMERIC;
BEGIN
x = $1::NUMERIC;
RETURN TRUE;
EXCEPTION WHEN others THEN
RETURN FALSE;
END;
$$;
CREATE TABLE public.libro_edizione (
isbn character(13) NOT NULL,
titolo_edizione character varying NOT NULL,
pagine integer,
copertina bytea,
relativa_a integer NOT NULL,
CONSTRAINT libro_edizione_isbn_check CHECK ((public.is_numeric(("substring"((isbn)::text, 1, 12))::character varying) AND (public.is_numeric(("right"((isbn)::text, 1))::character varying) OR ("right"((isbn)::text, 1) ~~ '%X'::text)))),
CONSTRAINT libro_edizione_pagine_check CHECK ((pagine >= 0))
);
ALTER TABLE ONLY public.libro_edizione
ADD CONSTRAINT libro_edizione_pkey PRIMARY KEY (isbn);
ALTER TABLE ONLY public.libro_edizione
ADD CONSTRAINT relativa_a FOREIGN KEY (relativa_a) REFERENCES public.libro(id);
```
La tabella delle edizioni di un libro include due _CHECK_: uno che controlla che le pagine, se specificate, siano un numero positivo, e un'altro che controlla che gli ISBN siano in un formato valido, assicurandosi che tutti i caratteri siano numerici e permettendo anche una `X` sull'ultimo.
### `utente`

View file

@ -145,18 +145,23 @@ ALTER FUNCTION public.is_numeric(text character varying) OWNER TO cookie;
CREATE FUNCTION public.update_n_audiolibri() RETURNS trigger
LANGUAGE plpgsql
AS $$BEGIN
AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.audiolibro_elementi_posseduti = old.audiolibro_elementi_posseduti - 1
WHERE utente.id = new.audiolibro_elemento.appartiene_a;
SET audiolibro_elementi_posseduti = audiolibro_elementi_posseduti - 1
FROM audiolibro_elemento
WHERE utente.username = old.appartiene_a;
RETURN OLD;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente
SET new.audiolibro_elementi_posseduti = old.audiolibro_elementi_posseduti + 1
WHERE utente.id = new.audiolibro_elemento.appartiene_a;
SET audiolibro_elementi_posseduti = audiolibro_elementi_posseduti + 1
FROM audiolibro_elemento
WHERE utente.username = new.appartiene_a;
RETURN new;
END IF;
RETURN NEW;
END;$$;
END;
$$;
ALTER FUNCTION public.update_n_audiolibri() OWNER TO cookie;
@ -167,18 +172,23 @@ ALTER FUNCTION public.update_n_audiolibri() OWNER TO cookie;
CREATE FUNCTION public.update_n_film() RETURNS trigger
LANGUAGE plpgsql
AS $$BEGIN
AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.film_elementi_posseduti = old.film_elementi_posseduti - 1
WHERE utente.id = new.film_elemento.appartiene_a;
SET film_elementi_posseduti = film_elementi_posseduti - 1
FROM film_elemento
WHERE utente.username = old.appartiene_a;
RETURN old;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente
SET new.film_elementi_posseduti = old.film_elementi_posseduti + 1
WHERE utente.id = new.film_elemento.appartiene_a;
SET film_elementi_posseduti = film_elementi_posseduti + 1
FROM film_elemento
WHERE utente.username = new.appartiene_a;
RETURN new;
END IF;
RETURN NEW;
END;$$;
END;
$$;
ALTER FUNCTION public.update_n_film() OWNER TO cookie;
@ -189,18 +199,23 @@ ALTER FUNCTION public.update_n_film() OWNER TO cookie;
CREATE FUNCTION public.update_n_giochi() RETURNS trigger
LANGUAGE plpgsql
AS $$BEGIN
AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.gioco_elementi_posseduti = old.gioco_elementi_posseduti - 1
WHERE utente.id = new.gioco_elemento.appartiene_a;
SET gioco_elementi_posseduti = gioco_elementi_posseduti - 1
FROM gioco_elemento
WHERE utente.username = old.appartiene_a;
RETURN old;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente
SET new.gioco_elementi_posseduti = old.gioco_elementi_posseduti + 1
WHERE utente.id = new.gioco_elemento.appartiene_a;
SET gioco_elementi_posseduti = gioco_elementi_posseduti + 1
FROM gioco_elemento
WHERE utente.username = new.appartiene_a;
RETURN new;
END IF;
RETURN NEW;
END;$$;
END;
$$;
ALTER FUNCTION public.update_n_giochi() OWNER TO cookie;
@ -211,18 +226,23 @@ ALTER FUNCTION public.update_n_giochi() OWNER TO cookie;
CREATE FUNCTION public.update_n_libri() RETURNS trigger
LANGUAGE plpgsql
AS $$BEGIN
AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.libro_elementi_posseduti = old.libro_elementi_posseduti - 1
WHERE utente.id = new.libro_elemento.appartiene_a;
SET libro_elementi_posseduti = libro_elementi_posseduti - 1
FROM libro_elemento
WHERE utente.username = old.appartiene_a;
RETURN old;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente
SET new.libro_elementi_posseduti = old.libro_elementi_posseduti + 1
WHERE utente.username = new.libro_elemento.appartiene_a;
SET libro_elementi_posseduti = libro_elementi_posseduti + 1
FROM libro_elemento
WHERE utente.username = new.appartiene_a;
RETURN new;
END IF;
RETURN NEW;
END;$$;
END;
$$;
ALTER FUNCTION public.update_n_libri() OWNER TO cookie;
@ -1242,8 +1262,8 @@ COPY public.libro_scritto_da (id_libro, id_autore) FROM stdin;
--
COPY public.utente (username, password, email, is_admin, is_banned, libro_elementi_posseduti, audiolibro_elementi_posseduti, film_elementi_posseduti, gioco_elementi_posseduti) FROM stdin;
sas \\x737573 ciao@steffo.eu t f 0 0 0 0
sis \\x737573 banana@steffo.eu f f 0 0 0 0
sas \\x737573 ciao@steffo.eu t f -4 0 0 0
sis \\x737573 banana@steffo.eu f f -2 0 0 0
\.
@ -1324,14 +1344,6 @@ SELECT pg_catalog.setval('public.libro_genere_id_seq', 1, false);
SELECT pg_catalog.setval('public.libro_id_seq', 1, false);
--
-- Name: libro_edizione Edizione(libro)_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE ONLY public.libro_edizione
ADD CONSTRAINT "Edizione(libro)_pkey" PRIMARY KEY (isbn);
--
-- Name: audiolibro_edizione audiolibro_edizione_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
@ -1372,14 +1384,6 @@ ALTER TABLE ONLY public.audiolibro_recensione
ADD CONSTRAINT audiolibro_recensione_pkey PRIMARY KEY (id);
--
-- Name: libro_correlazioni correlazioni_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE ONLY public.libro_correlazioni
ADD CONSTRAINT correlazioni_pkey PRIMARY KEY (id_1, id_2);
--
-- Name: film_appartenenza_a_genere film_appartenenza_a_genere_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
@ -1572,6 +1576,14 @@ ALTER TABLE ONLY public.libro_autore
ADD CONSTRAINT libro_autore_pkey PRIMARY KEY (id);
--
-- Name: libro_correlazioni libro_correlazioni_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE ONLY public.libro_correlazioni
ADD CONSTRAINT libro_correlazioni_pkey PRIMARY KEY (id_1, id_2);
--
-- Name: libro_editore libro_editore_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
@ -1580,6 +1592,14 @@ ALTER TABLE ONLY public.libro_editore
ADD CONSTRAINT libro_editore_pkey PRIMARY KEY (parte_isbn);
--
-- Name: libro_edizione libro_edizione_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE ONLY public.libro_edizione
ADD CONSTRAINT libro_edizione_pkey PRIMARY KEY (isbn);
--
-- Name: libro_elemento libro_elemento_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
--
@ -1636,11 +1656,32 @@ ALTER TABLE ONLY public.utente
ADD CONSTRAINT username PRIMARY KEY (username);
--
-- Name: audiolibro_elemento numero_audiolibri_trigger; Type: TRIGGER; Schema: public; Owner: cookie
--
CREATE TRIGGER numero_audiolibri_trigger BEFORE INSERT OR DELETE ON public.audiolibro_elemento FOR EACH ROW EXECUTE PROCEDURE public.update_n_audiolibri();
--
-- Name: film_elemento numero_film_trigger; Type: TRIGGER; Schema: public; Owner: cookie
--
CREATE TRIGGER numero_film_trigger BEFORE INSERT OR DELETE ON public.film_elemento FOR EACH ROW EXECUTE PROCEDURE public.update_n_film();
--
-- Name: gioco_elemento numero_giochi_trigger; Type: TRIGGER; Schema: public; Owner: cookie
--
CREATE TRIGGER numero_giochi_trigger BEFORE INSERT OR DELETE ON public.gioco_elemento FOR EACH ROW EXECUTE PROCEDURE public.update_n_giochi();
--
-- Name: libro_elemento numero_libri_trigger; Type: TRIGGER; Schema: public; Owner: cookie
--
CREATE TRIGGER numero_libri_trigger AFTER INSERT ON public.libro_elemento FOR EACH ROW EXECUTE PROCEDURE public.update_n_libri();
CREATE TRIGGER numero_libri_trigger BEFORE INSERT OR DELETE ON public.libro_elemento FOR EACH ROW EXECUTE PROCEDURE public.update_n_libri();
--

83
6-operazioni.md Normal file
View file

@ -0,0 +1,83 @@
# Query preprogrammate per l'utilizzo del database
Si sono inserite in questo capitolo della relazione alcuni esempi di query che permetteranno al sito web di interagire con la base di dati.
Come nel caso della [creazione tabelle](5-3-creazione-tabelle.md), si elencano solo le query più significative.
## Creazione di un nuovo utente
```sql
INSERT INTO utente (username, password, email) VALUES ($username, $hashed_password, $email);
```
## Promozione di un utente ad amministratore
```sql
UPDATE utente SET is_admin = true WHERE username = $username;
```
## Creazione di un elemento relativo a un libro non esistente nel database
```sql
INSERT INTO libro (titolo_primario) VALUES ($titolo);
INSERT INTO libro_edizione (isbn, titolo_edizione, relativa_a) VALUES ($isbn, $titolo, currval('libro_id_seq'));
INSERT INTO libro_elemento (istanza_di, appartiene_a) VALUES ($isbn, $username);
```
## Creazione di una recensione relativa a un elemento
```sql
INSERT INTO libro_recensione (id, commento, data, valutazione) VALUES ($isbn, $commento, now(), $valutazione);
```
## Conteggio degli elementi posseduti da un utente
```sql
SELECT
libro_elementi_posseduti libri,
audiolibro_elementi_posseduti audiolibri,
film_elementi_posseduti film,
gioco_elementi_posseduti giochi,
(libro_elementi_posseduti + audiolibro_elementi_posseduti + film_elementi_posseduti + gioco_elementi_posseduti) totale
FROM utente
WHERE username = $username;
```
## Conteggio del numero totale di edizioni di libri presenti nel database
```sql
SELECT COUNT(*) FROM libro_edizione;
```
## Conteggio del numero totale di edizioni di libri di ogni autore
```sql
SELECT COUNT(*)
FROM libro_edizione
WHERE relativa_a IN (
SELECT l.id
FROM libro l
JOIN libro_scritto_da lsd on l.id = lsd.id_libro
JOIN libro_autore la on lsd.id_autore = la.id
WHERE la.id = $id_autore
);
```
## Visualizzazione della valutazione media di un gioco
```sql
SELECT AVG(gr.valutazione)
FROM gioco_recensione gr
JOIN gioco_elemento gel on gr.id = gel.id
JOIN gioco_edizione ge on gel.istanza_di = ge.id
JOIN gioco g on ge.relativa_a = g.id
WHERE g = $id_gioco;
```
## Visualizzazione di tutte le edizioni di un dato editore
```sql
SELECT * FROM libro_editore ld JOIN libro_edizione lz ON ld.parte_isbn = substr(lz.isbn, 5, 5 + length(ld.parte_isbn));
```

View file

@ -28,9 +28,9 @@ Le specifiche di questo progetto sono disponibili nel file [`spec.pdf`](0-spec.p
4. [Dati derivati](4-4-dati-derivati.md)
5. [Schema logico](4-5-schema-logico.md)
6. [Verifica di normalizzazione](4-6-normalizzazione.md)
5. **Progettazione fisica**
5. **Progettazione fisica** ([dump](5-database.sql))
1. [Tecnologia database](5-1-tecnologia-database.md)
2. [Creazione database](5-2-creazione-database.md)
3. [Creazione tabelle](5-3-creazione-tabelle.md)
6. **Programmazione database**
1. [Query preprogrammate per l'utilizzo del database](6-operazioni.md)