A lezione con il PostgreSQL

In molte scuole italiane si insegna in ambito curriculare la gestione delle basi di dati. Il riferimento è alle classi quarte e quinte degli Istituti professionali per il commercio (indirizzo informatico) e degli Istituti tecnici per programmatori, siano essi industriali che commerciali.

Ma negli Istituti professionali ad indirizo informatico, contrariamente al buon senso, l'insegnamento della disciplina informatica, non prevede l'ausilio del laboratorio di informatica (al riguardo si veda Fulvio Ferroni: "Il software libero nella didattica (II)" in Linux Magazine n. 12 giugno-luglio 2001, http://linuxdidattica.org.

Privare l'insegnante di informatica del rispettivo laboratorio corrisponde a privare un insegnante di un qualsivoglia libro di testo o strumento didattico e in ultima istanza, oggi, significa privarlo dell'esercizio della libertà d'insegnamento.


Nella scuola Fabio Besta di Treviso (Istituto Professionale di Stato ad indirizzo informatico), grazie al software libero e all'autonomia scolastica (ben interpretata dagli Organi dirigenti della scuola), tale assurdità è stata rimossa riuscendo così a far provare agli studenti, quello che si insegna in teoria. In questo modo ogni studente può rendersi conto anche praticamente delle varie problematiche inerenti alla gestione di una base di dati e di un sistema informativo più in generale.

La soluzione al paradosso: l'utilizzo di PostgreSQL in ambiente GNU/Linux

Utilizzando un vecchio elaboratore Pentium, venticinque i286 e una stampante, tutte macchine da rottamare, è stata costituita una rete TCP/IP basata sul sistema operativo GNU/Linux installato sul Pentium (rete 192.168.1.0). Durante l'installazione del sistema operativo è stato installato anche il DBMS PostgreSQL 7.0.2 e il suo client, a interfaccia a carattere, psql.

Sulle macchine i286 si è installato il Dos Caldera e un programma telnet per Dos. Tutte le macchine i286 sono state collegate al Pentium tramite due HUB.

Nella macchina GNU/Linux oltre al binario e ai sorgenti di PostgreSQL e di psql si è anche installata tutta la relativa documentazione nella directory: /usr/share/doc/postgresql-7.0.2/

Per ogni studente, su GNU/Linux, è stata creata un'utenza (account).

Si è, successivamente, configurato, con i permessi dell'utente root, il file pg_hba.conf per dare agli utenti gli accessi, senza restrizioni (trust), al server PostgreSQL:

#

#Example PostgreSQL host access control file.

#

......

host all 127.0.0.1 255.255.255.255 trust

Per maggiori dettagli sulla installazione e configurazione di PostgreSQL si veda Umberto Zanatta:"La rete: Linux per la didattica" cap. 13, in http//linuxdidattica.org).


Per ogni utente del sistema GNU/Linux si crea un utente PostgreSQL con il comando createuser. Si farà in modo, per semplicità, che siano uguali (utente linux=utente PostgreSQL):

toni$createuser toni <invio>

Shall the new user be allowed to create databases? (y/n) n <invio>

Shall the new user be allowed to create more new users? (y/n) n <invio>

CREATE USER

Ogni studente si collega, dalla macchina i286, a GNU/Linux digitando:

C>telnet 192.168.1.1 <invio>

login: toni <invio>

passwd: <invio>

apparirà il prompt (il Pentium si chiama cea):

toni@cea$

E qui siamo in ambiente GNU/Linux.

Dopo aver progettato in classe e analizzato la base di dati biblioteca (modello E-R, schema logico, schema fisico, ecc.) si passa alla esercitazione. Tale base di dati e la relativa esercitazione sono documentate in Daniele Giacomini «Appunti di informatica libera, Le funzioni e i trigger in PostgreSQL: un'esercitazione didattica», http://linuxdidattica.org.

Per prima cosa si parte dalla creazione della base di dati da parte dell'amministratore postgres. L'utente toni si trasforma nell'utente postgres:

toni@cea$su - postgres <invio>

bash-2.04$createdb biblioteca <invio>

CREATE DATABASE

usciamo dall'utente postgres con il comando exit

bash-2.04#exit <invio>

toni@cea$

Gli studenti, già a livello di progettazione della base di dati in classe, vengono suddivisi in gruppi dove a ogni gruppo è assegnato un compito e una gestione ben precisa di una parte della della base di dati.

Anche se utilizziamo solo una macchina GNU/Linux le esercitazioni sono obbligatoriamente in rete, in ambiente multiutente, client-server dove la concorrenza di accesso e la gestione delle transazioni si può verificare pienamente. Ne risulta una esercitazione più vicina alla realtà aziendale rispetto alle solite esercitazioni monoutente.

La base di dati biblioteca, serve per gestire i prestiti dei libri di una biblioteca, ed è formata dalle cinque tabelle riportate in fig. n. 1.


Fig. n. 1: schema del database biblioteca (grassetto= chiave primaria, corsivo=chiave esterna)


libri(n_inv,autore,titolo,collocazione,soggetto,cod_ed,prezzo,an_ed)

utenti(cod_ut,nome,cognome,telefono,indirizzo,citta)

localita(citta,cap,prov,nz)

editori(cod_ed,rag_soc,indirizzo,citta,telefono)

prestiti(n_prog,n_inv,cod_ut,data_p,data_r)


I singoli gruppi di studenti creano le tabelle (istruzione create) e le vanno a popolare (istruzione insert into).Tutti i gruppi devono popolare la tabella prestiti.

In questa esercitazione si utilizza la capacità del PostgreSQL e del psql di elaborare file ASCII dove sono scritte istruzioni SQL. Gli studenti scrivono le istruzioni in un file con l'editor VI, per poi eseguirlo all'interno della base di dati con il metacomando \i <nomefile>, come vedremo più avanti. Ovviamente, tutti i gruppi dovranno dare i permessi agli altri studenti (o toglierli, a seconda dei casi), dalle tabelle che creano, tramite le istruzioni grant e revoke.


Al lavoro con il server PostgreSQL e il client psql

Cominciamo con un esempio immaginando di essere l'utente toni che deve creare e popolare prestiti:

C>telnet 192.168.1.1 <invio>

login:toni <invio>

passwd: <invio>

toni@cea$psql -h localhost -d biblioteca -U toni <invio>

biblioteca=>

Ora siamo connessi al database biblioteca.

A questo punto l'utente toni può utilizzare i metacomandi psql o le istruzioni SQL. Psql è il client a interfaccia a carattere. I metacomadi psql, che permettono anche di interfacciarsi con GNU/Linux, iniziano sempre con la barra rovesciata \, come ad esempio:\q che serve per uscire,\d per vedere le tabelle della base di dati, \l per vedere le varie basi di dati, \d <nometabella> per vedere lo schema della tabella, \? la guida di psql, \h per avere la guida SQL, \! per utilizzare i comandi del sistema operativo, ecc.

L'utente toni crea la tabella prestiti utilizzando l'editor VI come mostrato in fig. n. 2.


Fig. n. 2: creazione della tabella prestiti


biblioteca=>\! vi creo_prestiti.sql

create table prestiti (

n_prog serial,

n_inv char(5) references libri,

cod_ut char(5) references utenti,

data_p date check (data_p<=data_r),

data_r date default '2050.1.1.');


Usciamo dal VI digitando i consueti esc:wq e mandiamo in esecuzione il file creo_prestiti.sql:

biblioteca=>\i creo_prestiti.sql <invio>

CREATE

Se non fossero già state create, dagli altri gruppi, le tabelle utenti e libri l'utente toni verrebbe avvisato che non può creare la tabella prestiti (perché fa riferimento alle chiavi primarie n_inv e cod_ut). Adesso inseriamo, interattivamente, un prestito:

biblioteca=>insert into prestiti (n_inv, cod_ut, data_p) <invio>

biblioteca->values ('12', '15','2001.10.10'); <invio>

INSERT 1

Nell'inserimento dei dati subito si incontra il problema del'integrità referenziale esterna.

Non si può popolare una tabella all'interno della quale un campo fa riferimento a una chiave primaria inesistente nell'altra tabella (nel caso precedente deve esistere il libro con n_inv =12 o utente con cod_ut =15).

Quando un libro rientra sarà sufficiente eseguire l'istruzione update, e nell'ipotesi che il numero progressivo del prestito sia 1:

biblioteca=>update libri set data_r=date('now') <invio>

biblioteca=>where n_prog=1; <invio>

UPDATE 1

In una esercitazione didattica è difficile controllare i dati prima che essi vengano inseriti. Tutti gli studenti dovevano preparare una decina di prestiti a piacere (ricavando i dati dalle tabelle libri e utenti) precedentemente stampate. Dovevano scrivere questi inserimenti in un file, che successivamente avrebbero eseguito con il metacomando \i. In questo modo, tra l'altro, si impara a lavorare anche off line, e non solo in maniera interattiva (alcuni studenti il file se lo sono scritto a casa).

Una volta popolata prestiti, osservandola, ci si è accorti che era stato dato a prestito lo stesso libro a più utenti contemporaneamente, cosa evidentemente assurda, come nell'esempio sottostante:

biblioteca=>select * from prestiti where n_inv='5'; <invio>

n_prog, n_inv, cod_ut, data_p, data_r

1 5 12 2001.10.10 2050.1.1

10 5 25 2001.11.11 2050.1.1

12 5 34 2001.11.28 2050.1.1


La soluzione è stata trovata utilizzando la caratteristica del PostgreSQL di gestire i trigger e le funzioni in vari linguaggi, tra cui il Plpgsql.

Si procede, perciò, prima ad associare questo linguaggio alla base di dati (operazione da fare come utente postgres) con il comando createlang:

toni@cea$su - postgres <invio>

bash-2.04$createlang -h localhost -d biblioteca --pglib=/usr/lib/pgsql/ plpgsql <invio>

toni@cea$

Successivamente come utente toni abbiamo creato il file controlla_inserimento.plpgsql, come descritto in fig. n. 3, contenente il trigger e la relativa funzione, precedentemente spiegati in classe.


Fig. n. 3: creazione del file controlla_inserimento.plpgsql


toni$vi controlla_inserimento.plpgsql

create function inserisci_prestito_trigger()

returns opaque
   as 'declare
     numero_inventario char(5);
     data_restituzione date;
     prestito record;
        begin
        numero_inventario:=new.n_inv;
        data_restituzione:=''2050.1.1'';
           select into prestito *
           from prestiti
           where n_inv=numero_inventario and
           data_r=data_restituzione;
              if found
                 then
                    raise exception \'il libro è già a prestito\';
                 else
                    return new;
               end if;
        end;'
language 'plpgsql';

create trigger controlla_libro_uscito
before insert
on prestiti
for each row

execute procedure inserisci_prestito_trigger();


Questo file è nella directory dell'utente toni. Ci colleghiamo al database biblioteca

toni@cea$psql -h localhost -d biblioteca -U toni <invio>

biblioteca=>

A questo punto possiamo compilare il trigger con il metacomando psql \i:

biblioteca=>\i controlla_inserimento.plpgsql <invio>

CREATE
CREATE

E' stata creata prima la funzione e poi il trigger.

Cancelliamo il contenuto del file prestiti, precedentemente popolato:

biblioteca=>delete from prestiti; <invio>

delete 74

Inseriamo dei prestiti eseguendo il contenuto del file inserimento_prestiti.sql già predisposto dall'utente mario:

biblioteca=>\i ..\mario\inserimento_prestiti.sql <invio>

INSERT 1

...

INSERT 10

Se si ripete l'operazione, si ottiene un errore:

biblioteca=>\i ..\mario\inserimento_prestiti.sql <invio>

ERROR il libro è già a prestito

.....

ERROR il libro è già a prestito

Come si vede (ERROR ecc.) il trigger ha impedito l'inserimento dei libri già a prestito.


Una volta costruita la base di dati biblioteca integra, senza dati contradditori, e dopo aver fatto rientare alcuni libri con date di rientro a piacere (controllate comunque dalla verifica check data_p<=data_r), si è passati ad interrogare i dati per vedere, ad esempio, quali libri erano ancora a prestito oltre il limite di 30 giorni dalla data del prestito, vedi fig. n. 4.


Fig. n. 4: esempio di select


biblioteca=>select p.n_inv, l.titolo, p.cod_ut, u.cognome, u.telefono, p.data_p

biblioteca->from prestiti p, utenti u, libri l

biblioteca->where data_r='2050.1.1' and

biblioteca-> data_p<date('now') and

biblioteca-> p.n_inv=l.n_inv and

biblioteca-> p.cod_ut=u.cod_ut

biblioteca->;


risultato della select


n_inv| titolo | cod_ut | cognome | telefono | data_p

-----+-----------+--------+------------+-------------+-----------

1 | LA COPPIA | A05 | TREVISAN | 021-495672 | 2001-01-01

10 | ESTASI | A05 | TREVISAN | 021-495672 | 2001-03-21

104 | IL GUFO | A14 | BAHASSOU | 07-440118 | 2001-02-22



Gli studenti hanno potuto interrogare la base di dati con altre istruzioni select di vario tipo, tutte rivolte a trasformare i dati contenuti nella base di dati in informazioni utili alla gestione della biblioteca. E così hanno potuto verificare sul campo il funzionamento di un semplice sistema informativo.

Conclusioni

All'Istituto Besta di Treviso è stato risolto abbastanza agevolmente il paradosso nel quale la politica del Ministero ha relegato l'insegnamento dell'informatica in questo ordine di scuole. Si è permesso così all'insegnante d'informatica di esercitare appieno il suo diritto alla libertà d'insegnamento potendo egli prima proporre e poi scegliere liberamente il suo libro di testo. E solo grazie al software libero un insegnante di informatica può esercitare il diritto alla libertà d'insegnamento come libera scelta del suo libro di testo.

Ma una domanda sorge spontanea: perché allora il software libero non è così diffuso nella scuola?

La risposta a mio avviso è altrettanto semplice.

Non è solo per mancanza di una politica del Ministero, almeno fino ad oggi, "in soggezione" al monopolio dell'informatica, perché l'insegnante, a difesa del suo lavoro, può sempre avvalersi dell'art. 33 della Costituzione e dell'autonomia progettuale.

Non è solo per mancanza di capacità tecnico-professionali tra i docenti (e operatori scolastici in genere) perché fra di essi ve ne sono anche di molto preparati.

Non è solo per mancanza di materiale hardware perché in questi anni, nella scuola italiana, sono stati spesi centinaia e centinaia di miliardi per acquisti in tale direzione.

Ma è perché la libertà si paga: usare il software libero richiede più impegno, più fatica, e solo l'insegnante che sente l'oppressione del software proprietario è disposto a fare più fatica per liberarsi dalla schiavitù che questo software impone.


Se gli insegnanti, usando il software proprietario nella didattica, non hanno consapevolezza di essere al servizio degli interessi di un monopolio anziché dei propri studenti e della collettività più in generale, non saranno mai disposti a fare più fatica per liberarsi da questa oppressione.

Dobbiamo allora lavorare sulle coscienze, far prendere coscienza del ruolo sostanzialmente servile che ha un insegnante che, oggi, utilizza il software proprietario monopolistico nella sua didattica.

Solo quando questa consapevolezza si sarà fatta strada tra gli operatori scolastici (insegnanti, tecnici, dirigenti scolastici, dirigenti amministrativi, ecc.) potremo liberarci dal giogo del software proprietario monopolistico nella scuola ed educare gli alunni alla libertà, inserendo l'insegnamento dell'informatica all'interno della moderna cultura scientifica.

Antonio Bernardi