<!doctype linuxdoc system
[
 <!ENTITY pericolo "!!" >
 <!ENTITY posix    "POSIX" >
 <!ENTITY unix     "Unix" >
 <!ENTITY xwin     "X Window System" >
 <!ENTITY edizione "dicembre 1999"> 
 <!ENTITY medx	"<bf>Medinux</bf>"> 
 <!ENTITY kmedx	"<em>kmedinux</em>"> 
 <!ENTITY luigi	"dr. Pier Luigi Simari"> 
 <!ENTITY sql	"<em>Structured Query Language</em>"> 
 <!ENTITY win	"Microsoft Windows &trade"> 
 <!ENTITY linux	"<em>Linux</em>"> 
 <!ENTITY kde	"<em>KDE</em>"> 
 <!ENTITY psql	"PostgreSQL"> 
 <!ENTITY engine  "<em>SQL-engine</em>">
 <!ENTITY redhat  "RedHat">
 <!ENTITY user	"<tt>medinux</tt>">

 <!SHORTREF subst
         "[" lsqb
         "]" rsqb
         "_" lowbar
         "#" num
         "%" percnt
         "^" circ
         "{" lcub
         "}" rcub
	 "=" equals
	 "~" tilde
         "|" verbar >

]>

<!--	il progetto medinux è stato ideato per facilitare la gestione degli 
	studi medici e la condivisione delle esperienze, statistiche ed il 
	facile reperimento di informazioni in rete da parte dei medici
	questo documento descrive l'applicazione kmedinux che è il tentativo
	di utilizzare una base dati comune da parte dei medici
 --> 
 

<article>

<!-- Title information -->

<title>Progetto Medinux
<author>Pier Luigi Simari &amp; Luciano Cattani <tt>pl.simari@rolmai.it lucianocattani@tin.it</tt>
<date>v0.1, dicembre 1999
<abstract>
Questo documento descrive l'applicazione kmedinux
</abstract>

<!-- Table of contents -->
<toc>

<!-- Begin the document -->

<sect>Introduzione

<p>
Il progetto &medx è stato ideato dal &luigi che ha postato in una lista di 
discussione per &linux una proposta per realizzare una applicazione per la gestione
degli studi medici.

<p>
Egli possedeva già un programma su piattaforma &win;. Si trattava di un prodotto commerciale
molto professionale ma che aveva una grande lacuna: non era possibile modificare il
programma nè ottenere dalla base dati qualche cosa di diverso da quello previsto
dal programma stesso e, oltretutto, i dati erano memorizzati in un formato proprietario
illeggibile oltre che crittografato.

<p>
Da qui l'impossibilità di condividere i dati a disposizione (nel rispetto
della legge sulla privacy, ovviamente) con altri. Inoltre, il programma
posseduto da Luigi si comportava male in rete perchè non era stato progettato
per una elaborazione di tipo <em>client-server</em> con tutte le implicazioni
del caso.

<p>
Ecco perchè la scelta di usare quale base per i dati un &engine; in grado
di funzionare anche su una macchina remota: la separazione tra il programma
<em>client</em> ed il <em>server</em> consente di effettuare la elaborazione
dei dati direttamente sul server il quale restituisce solo quei record
di interesse per il client diminuendo drasticamente il traffico sulla rete.

<p>
Non è affatto necessario scrivere un &engine specifico per questo programma
poichè ce ne sono moltissimi a disposizione sia <em>freeware</em> che
commerciali.
La scelta è caduta su &psql perchè è quello che utilizzo e conosco di più
ma non è affatto obbligatorio usare questo: chiunque può modificare il
sorgente del programma per adattarlo a &engine diversi.

<sect1>A cosa serve

<p>
L'applicazione consente la gestione dei pazienti negli studi medici
 generici.
Essa utilizza un database relazionale per gestire:

<itemize>
<item>i pazienti privati, convenzionati, sostituiti, etc
<item>i farmaci 
<item>le visite, i sintomi, le diagnosi e le prognosi
<item>i certificati
<item>le esenzioni stabilite dalle A.S.L.
<item>gli informatori, amministratori, fornitori, specialisti, etc.
</itemize>

<p>
Queste informazioni, saranno disponibili in un formato facilmente leggibile
tramite il linguaggio SQL


<sect1>Prerequisiti

<p>
L'applicazione kmedinux è sviluppata per l'ambiente &kde anche se essa funzionerà
normalmente anche in un ambiente grafico diverso purchè le librerie essenziali
del &kde siano presenti nel sistema.
Per poter funzionare, ha bisogno che sul sistema siano installati i
seguenti pacchetti:

<itemize>
<item><url url="http://www.kde.org" name="KDE"> versione 1.0 o successiva
<item><url url="http://www.troll.no" name="Qt"> versione 1.40 o successiva
<item><url url="http://ww.postgreSQL.org" name="&psql"> versione 6.4 o successiva
</itemize>


<p>
Per quanto riguarda la libreria Qt vi è da rilevare che nella versione
2.0 ho sperimentato alcune incompatibilità con i listati sorgenti di
kmedinux poichè alcune funzioni utilizzate dalla applicazione non sono
più supportate nelle versioni 2.x.

<p>
Tuttavia, la libreria Qt in versione 2.x dovrebbe essere accompagnata da
una speciale libreria di compatibilità con il passato: la versione 1x-1.44
che dovrebbe garantire la compatibilità con la versione 1.40 utilizzata
da me.

<p>
Per facilitare il compito di installare tutte le librerie in versione
corretta è possibile acquistare o scaricare via Internet una distribuzione
di &linux che contiene già i pacchetti necessari a compilare ed eseguire
il programma.
Segue la lista delle distribuzioni da mè conosciute e che dovrebbero
contenere già i pacchetti necessari. Chiunque abbia notizie di altre
distribuzioni contenenti le librerie corrette non elencate qui di seguito
è pregato di farmi sapere via e-mail in modo che io possa aggiornare la
lista:

<itemize>
<item><url url="http://www.redhat.it" name="RedHat"> versione 5.2 e successive
<item>S.u.s.e. 6.0
</itemize>


<sect>Legalese

<p>
Non mi intendo molto di questo argomento ma, si sà che gli avvocati trovano
sempre qualche <em>cavillo</em> per farti passare dei guai anche quando
cerchi di fare qualcosa di utile e questo <bf>qualcosa</bf> provoca qualche
piccolo danno come per esempio la distruzione della galassia.
Ecco perchè, come consigliano gli esperti della <em>Free Software
Foundation</em> ho fatto il classico <tt>copy & paste</tt> della licenza 
d'uso di questo programma e della relativa documentazione

<p>
NESSUNA GARANZIA
<p>
POICHÉ IL PROGRAMMA È CONCESSO IN USO GRATUITAMENTE, NON C'È ALCUNA GARANZIA
PER IL PROGRAMMA, NEI LIMITI PERMESSI DALLE VIGENTI LEGGI.
SE NON INDICATO DIVERSAMENTE PER ISCRITTO, IL DETENTORE DEL COPYRIGHT E LE
ALTRE PARTI FORNISCONO IL PROGRAMMA "COSI` COM'È", SENZA ALCUN TIPO DI GARANZIA,
NÉ ESPLICITA NÉ IMPLICITA; CIÒ COMPRENDE, SENZA LIMITARSI A QUESTO, LA GARANZIA
IMPLICITA DI COMMERCIABILITÀ E UTILIZZABILITÀ PER UN PARTICOLARE SCOPO.
L'INTERO RISCHIO CONCERNENTE LA QUALITÀ E LE PRESTAZIONI DEL PROGRAMMA È
DELL'ACQUIRENTE. SE IL PROGRAMMA DOVESSE RIVELARSI DIFETTOSO, L'ACQUIRENTE
SI ASSUME IL COSTO DI OGNI MANUTENZIONE, RIPARAZIONE O CORREZIONE NECESSARIA. 

<p>
NÉ IL DETENTORE DEL COPYRIGHT NÉ ALTRE PARTI CHE POSSONO MODIFICARE O
RIDISTRIBUIRE IL PROGRAMMA COME PERMESSO IN QUESTA LICENZA SONO RESPONSABILI
PER DANNI NEI CONFRONTI DELL'ACQUIRENTE, A MENO CHE QUESTO NON SIA RICHIESTO
DALLE LEGGI VIGENTI O APPAIA IN UN ACCORDO SCRITTO. SONO INCLUSI DANNI
GENERICI, SPECIALI O INCIDENTALI, COME PURE I DANNI CHE CONSEGUONO DALL'USO
O DALL'IMPOSSIBILITÀ DI USARE IL PROGRAMMA; CIÒ COMPRENDE, SENZA LIMITARSI
A QUESTO, LA PERDITA DI DATI, LA CORRUZIONE DEI DATI, LE PERDITE SOSTENUTE
DALL'ACQUIRENTE O DA TERZE PARTI E L'INABILITÀ DEL PROGRAMMA A LAVORARE INSIEME
AD ALTRI PROGRAMMI, ANCHE SE IL DETENTORE O ALTRE PARTI SONO STATE AVVISATE
DELLA POSSIBILITÀ DI QUESTI DANNI. 


<p>
Per quanto riguarda la licenza d'uso del programma consultate il file <tt>COPYING</tt>
che accompagna il programma stesso e che troverete nella directory principale
dei sorgenti della applicazione.
La licenza è in originale lingua inglese ma potrete trovarne una traduzione
abbastanza fedele consultando gli <url url="hppt://genius.allnet.it/AppuntiLinux"
name="AppuntiLinux">.


<sect>Installazione

<p>
Poichè &kmedx si appoggia al &engine &psql la prima operazione
da compiere sarà quella di far partire (di solito già nella procedura di
init) il backend di &psql (cosidetto <em>postmaster</em>); consultare la
documentazione di &psql per maggiori informazioni.

<p>
Si dovrà successivamente creare uno user &psql abilitato a creare
database in modo che il programma di inizializzazione possa creare il
database e le tabelle.
A meno che non ci siano particolari esigenze di sicurezza oppure che il
server &psql non risieda su un computer remoto oppure su un server
condiviso nel qual caso di dovrà chiedere all'amministratore di quel
sistema, di seguito vengono descritti i passi da seguire per installare
l'applicazione su un computer stand-alone.

<p>
Per maggiori informazioni sulla sicurezza vedi il capitolo ad essa
relativo più avanti in questo stesso documento.


<sect1>Preparazione alla installazione

<p>
Controllate che siano presenti sul sistema i pacchetti necessari per
compilare ed eseguire l'applicazione: se usate il package manager 
della &redhat; potete dare questi comandi il cui output dovrebbe essere
simile a quello indicato di seguito:

<tscreen><verb>
  $ rpm -qa | grep kde
  kdesupport-1.0-2rh51
  kdelibs-1.0-2rh51
  kdebase-1.0-9rh51
  kdeadmin-1.0-2rh51
  kdegames-1.0-2rh51
  kdegraphics-1.0-2rh51
  kdemultimedia-1.0-2rh51
  kdenetwork-1.0-2rh51              

  $ rpm -qa | grep qt
  qt-1.40-1rh51
  qt-devel-1.40-1rh51   

  $ rpm -qa | grep postgre
  postgresql-rhcn-clients-6.4.2-3
  postgresql-clients-6.3.2-10
  postgresql-rhcn-6.4.2-3
  postgresql-rhcn-devel-6.4.2-3             

</verb></tscreen>

<p>
Ricordo che per <bf>&psql</bf> e <bf>qt</bf> sono necessari, oltre alle librerie vere
e proprie anche il package relativo allo sviluppo
identificato attraverso il suffisso <bf>devel</bf> nel nome del pacchetto.

<p>
Controllate che il backend di &psql (postmaster) sia in esecuzione
utilizzando il comando:

<p>
<tscreen><verb>
  # ps -aux | grep postmas
  warning: `-' deprecated; use `ps aux', not `ps -aux'
  postgres   246  0.0  1.6  3672  1016  ?  S    20:53   0:00 /usr/bin/postmaster -
  root       517  0.0  0.6   920   428  p0 S    22:55   0:00 grep postmas                                      
</verb></tscreen>

<p>
e dovreste ottenere un output simile a quello riportato sopra (notare il demone
in esecuzione con PID 246).
Se, invece, ottenete solo la riga con il comando <tt>grep</tt> significa che il demone
non è in esecuzione.

<p>
Provate il seguente comando se avete una distribuzione basate su &redhat;:

<tscreen><verb>
  $ /etc/rc.d/init.d/postgresql start
</verb></tscreen>

<p>
e poi nuovamente il comando precedente. Se tutto è OK potete continuare altrimenti
dovrete controllare il PATH dove risiede lo script di avvio del postmaster.

<p>
Ora faremo in modo che &psql si avvii automaticamente al boot col comando

<tscreen><verb>
  $ cd /etc/rc.d/rc&lt;RUNLEVEL&gt;.d
  $ ln -s ../init.d/postgresql S86postgre
</verb></tscreen>

Nel primo comando sostituite a &lt;RUNLEVEL&gt il numero di <em>runlevel</em> di default
col quale parte il vostro computer che trovate col comando:

<tscreen><verb>
  # grep -e initdefault: /etc/inittab
  id:3:initdefault:                                           
</verb></tscreen>

Nel mio caso, il numero di runlevel è <tt>3</tt>.


<p>
Da root, creare un utente &psql da usare quale user-name per il
collegamento al &engine:

<tscreen><verb>
  # su postgres
  # createuser medinux
</verb></tscreen>

e rispondere in modo affermativo alla domanda del programma
<tt>createuser</tt> quando esso chiederà se l'utente &user è
abilitato a creare nuovi database.
Non è necessario che l'utente &user sia abilitato a creare nuovi
user e, a questo proposito, suggerisco di rispondere <tt>N</tt> alla relativa
domanda.

<p>
Faccio comunque notare che l'utente &user non ha <em>niente a che
fare</em> col nome di login &unix: &user è l'utente del database e non del
sistema Linux.
Perciò, creando l'utente &user in &psql non dovete affatto fare il
login con quel nome ma, invece, continuerete a farlo nel solito modo.

<p>
E' nel momento della connessione al &engine che vi sarà chiesto il nome
dell'utente (inteso come utente del database) e sarà in quel momento che
si specificherà &user (in realtà non è necessario poichè l'applicazione
lo usa per default).


<sect1>Compilazione dei sorgenti

<p>
Copiare il file compresso sulla propria home directory e decomprimerlo
col comando (probabilmente già fatto se leggete questo file):

<tscreen><verb>
  tar -xzvf kmedinux-0.1a.tar.gz
</verb></tscreen>

questo creerà la directory <tt>kmedinux-0.1a</tt> e vi copierà tutti i files
sorgenti, dei dati e documentazione della applicazione.

<p>
La compilazione vera e propria avviene spostandosi nella directory
appena creata ed eseguendo i comandi:

<tscreen><verb>
  make
  make install
</verb></tscreen>


<sect1>Il Makefile

<p>
Il file che controlla la compilazione è il <tt>Makefile</tt> che si trova
nella directory di cui sopra.
A seconda delle distribuzioni il file dovrà essere modificato perchè
il programma possa compilare.

<p>
Nella directory vi sono diversi <tt>Makefile</tt> con varie estensioni.
Questi sono dei files specifici per alcune distribuzioni di cui io o
alcuni amici siamo in possesso e che abbiamo creato per compilare il
programma.
L'estensione del <tt>Makefile</tt> controlla la distribuzione per la quale esso
è stato creato in modo specifico. Segue l'elenco:

<itemize>
<item><tt>Makefile.rh52</tt> RedHat versione 5.2
<item><tt>Makefile.rh61</tt> RedHat 6.1
<item><tt>Makefile.su61</tt> .u.s.E. 6.1
</itemize>

<p>
Se il <tt>Makefile</tt> specifico per la vostra distribuzione è presente
allora siete fortunati
e potrete compilare il programma con successo semplicemente creando un <em>link</em>
per la vostra specifica distribuzione (oppure usando il parametro -f
nel comando make).
Per esempio, se possedete una &redhat; versione 6.1 il comando per creare
il link sarà:

<tscreen><verb>
  ln -s ./Makefile.rh61 Makefile
</verb></tscreen>


Dopo aver creato il link, sarà possibile compilare l'applicazione

<tscreen><verb>
  make
  make install
</verb></tscreen>


<sect1>Modificare il Makefile

<p>
Se la vostra distribuzione non è presente, potrebbe anche compilare con
successo utilizzando un <tt>Makefile</tt> di una altra distribuzione come per
esempio nel caso delle <em>Mandrake</em> le quali, essendo basate su &redhat,
dovrebbero essere compatibili con essa.

<p>
Per altre distribuzioni che non compaiono nella lista di cui sopra è
possibile copiare uno qualunque dei file specifici come <tt>Makefile</tt> e tentare
la compilazione: potrebbe anche avere successo ma sarebbe davvero un
caso più unico che raro.

<p>
Molti sviluppatori usano strumenti quali <bf>autoconf</bf> ed <bf>automake</bf>
per creare degli
<em>script</em> di configurazione che riescono a creare il Makefile
specifico per il sistema in uso <em>on-the-fly</em>.

<p>
Ho sperimentato uno di questi sistemi con un programma con pessimi
risultati perchè il programma non compilava.
Ma, quel che è peggio, il <tt>Makefile</tt> creato era talmente complesso
che non sono riuscito a modificarlo.
Oltre a ciò, non ho alcuna dimestichezza con questi strumenti e perciò
ho optato per una tecnica molto vecchia ma ancora funzionante;
tenere il <tt>Makefile</tt> corto e semplice e darvi le istruzioni per
configurarlo correttamente.
In fondo si tratta di controllare pochi percorsi per individuare quelli
corretti per le librerie usate.


<sect1>Inizializzazione

<p>
L'installazione termina con l'esecuzione del comando <tt>initmedx</tt>
che provvede a:

<itemize>
<item>creare il database della applicazione
<item>creare le tabelle all'interno del database
<item>popolare le tabelle che accompagnano l'applicazione e che fanno parte
	della stessa
</itemize>

Si tratta di una applicazione a riga di comando che deve essere eseguita
<bf>solo una volta</bf> per ogni installazione. Se si è provveduto già alla
creazione ed inizializzazione del database e si vuole solo ricompilare
il programma, evitare di eseguire questo comando.

<p>
Il comando và eseguito una volta per ogni installazione a prescindere
dal numero di utenti che usano il database.
In particolare, se il database viene installato su un server di rete
e sarà condiviso, sarà opportuno eseguire questo comando sul server
e non sui client oppure, in alternativa, su un solo client ma sarà
necessario specificare delle opzioni sulla riga di comando.

<p>
Per una installazione su computer stand-alone, il comando può essere
eseguito senza parametri: verranno usati i valori di default che
saranno corretti per la maggior parte delle installazioni.

Il comando <tt>initmedx</tt> accetta le seguenti opzioni sulla riga di
comando:

<descrip>
<tag>-u --user USERNAME</tag>
	permette di specificare un utente del &engine;. Per default
	esso è &user;
<tag>-p --passwd PASSWORD</tag>
	associa una password all'utente postgres. Per default non viene
	associata alcuna password all'utente
<tag>-d --dbname DBNAME</tag>
	specifica il nome del database da creare e da inizializzare.
	Per default il nome è <tt>medx0</tt>
<tag>-h --host HOSTADDR</tag>
	specifica l'indirizzo IP del computer remoto dove risiede il &engine
	al quale ci si collega. Il database sarà creato e
	inizializzato sul computer remoto. Per default nessun sistema remoto
	viene specificato ed il database viene creato sulla macchina locale
<tag>-o --port PORTNUMBER</tag>
	specifica la porta TCP/IP del sistema remoto sulla quale è in
	ascolto il &engine;. Questa opzione ha effetto solo se
	è già stata specificata l'opzione <tt>-h</tt>. Per default nessuna porta
	viene indicata e viene assunta la porta di default.
<tag>-n --nocreate</tag>
	sopprime la creazione del database poiché esso è già stato creato
	ed esegue, invece, solo la creazione delle tabelle e la loro
	popolazione.
</descrip>

<p>
Per esempio, se il &engine risiede su un computer remoto che si chiama
<bf>wodka</bf> e l'amministratore di quel sistema ha creato uno user &psql di
nome <bf>cognac</bf> a cui è anche associata la password <bf>tequila</bf>, si potrà 
inizializare il database da remoto col comando:
<tscreen><verb>
  initmedx -u cognac -p tequila -h wodka
</verb></tscreen>

presupponendo che il sistema remoto sia in esercizio ed il <em>postmaster</em>
sia attivo ed in ascolto sulla porta di default. (e che gli 
utenti non abbiano bevuto troppi di questi sistemi).

 
<sect>Il database di medinux 
 
<p> 
Il progetto &medx; si avvale di un database relazionale SQL per  
memorizzare i dati. 
Il principale vantaggio di una simile organizzazione è che l'estrazione 
dei dati ai fini statistici è molto agevole e non dipende affatto dalla 
applicazione usata poichè è possibile usare lo &sql da qualsiasi client 
perfino in ambienti diversi se il &engine; supporta ODBC o qualsiasi 
altro standard multipiattaforma. 
 
<p> 
Quella che viene descritta di seguito è la versione 0 del database. 
La numerazione delle versioni del database &medx segue lo standard 
di &linux; un pò perchè è il mio ambiente preferito ma anche perchè 
trovo molto pratico e flessibile la filosofia di numerazione delle 
versioni di quel sistema. 
 
<p> 
Il nome di default del database è 
 
<tscreen><verb>
medx&lt;N&gt; 
</verb></tscreen> 
 
con <tt>N</tt> che stabilisce il numero della versione <em>maggiore</em>
del database.
 
<p> 
Poichè è impensabile che la struttura del database rimanga sempre la stessa 
in quanto con il tempo è possibile avere bisogno di campi nuovi o modifiche 
ai campi esistenti, le modifiche lievi che non comportano grandi mutamenti 
alla struttura non modificano il numero di versione <em>maggiore</em> 
mentre i grandi cambiamenti saranno indicati con un 
nuovo numero nella versione (e quindi del nome del database). 
 
<p> 
Per cambiamenti lievi si intendono tutte quelle modifiche che, 
pur cambiando la struttura di una o più tabelle, mantengono la compatibilità 
con le versioni precedenti a livello di linguaggio SQL in tutte le 
<em>query</em>. 
Per esempio, la modifica della lunghezza di un campo - che non sia una 
<em>primary key</em> - o l'aggiunta di un campo che può avere il valore 
<tt>NULL</tt> dovrebbe mantenere la compatibilità con tutte le query 
scritte in precedenza e, perciò, modifiche di questo tipo faranno avanzare 
il numero di versione <em>minore</em> - che però non viene indicata nel
nome del database ma, invece, in una speciale tabella di quest'ultimo. 
 
<p> 
Al contrario, cambiamenti strutturali quali la modifica di un campo <em>key</em> 
oppure l'aggiunta di campi obbligatori ad una o più tabelle comportano anche 
la inevitabile conseguenza di rendere incompatibili le <em>query</em> scritte 
in precedenza e, pertanto, si renderà necessario aumentare il numero di 
<em>major version</em> - e, quindi, il nome stesso del database. 
 
<p> 
Tutte le applicazioni o moduli che saranno sviluppati per &medx dovranno 
contenere sempre almeno il numero di <em>major version</em> che deve corrispondere 
alla versione maggiore del database che l'applicazione riesce a leggere. 
Così, per esempio, una applicazione come per esempio <bf>kmedinux-0.1</bf> 
dovrà essere in grado di gestire tutti i database del progetto il cui numero 
di versione maggiore è <tt>ZERO</tt>. 
 
<p> 
Segue l'elenco e la struttura delle tabelle usate dal progetto.


<sect1>La tabella Versioni 
 
<p> 
Questa tabella contiene dati di servizio del database, delle sue 
diverse versioni e le stringhe di quelle query che possono variare 
nelle varie versioni. 

<table LOC=hbtp>
<tabular CA="lllll">
	<hline>
	campo  <colsep> tipo <colsep> lungh <colsep> constraint <colsep> descrizione	<rowsep> 
	<hline>
	FieldID  <colsep> CHAR <colsep> 6 <colsep> PRIMARY KEY <colsep> identificativo del record <rowsep>
	Version  <colsep> INT4 <colsep> 4 <colsep> NOT NULL <colsep> codice della versione <rowsep>
	DateID   <colsep> DATE <colsep> -- <colsep> 	<colsep> data di creazione / modifica <rowsep> 
	Description <colsep> VARCHAR <colsep>  1024 <colsep>	<colsep> stringa di descrizione / query <rowsep>
	<hline>
 </tabular> 
 <caption> 
         Tabella Versioni 
 </caption> 
 </table> 
 
<p> 
<bf>Commento</bf> 
 
<p> 
La tabella è composta da diversi <em>tipi di records</em> che hanno 
significati specifici a seconda del tipo descritto. 
Non tutti i tipi di records possono essere presenti in uno specifico 
database tranne quelli obbligatori. 
Il campo <tt>FieldID</tt> indica il tipo di record secondo una codifica 
standard. Per esempio, il tipo di record <tt>CREATE</tt> contiene nel 
campo <tt>DateID</tt> la data di creazione delle tabelle, nel campo 
<tt>Description</tt> il nome del DBMS che lo ha creato e nel campo 
<tt>Version</tt> la versione del database codificata secondo la 
seguente formula: 
 
<tscreen><verb> 
	versione = ( major * 100 ) + minor 
</verb></tscreen> 
 
Il tipo di record <tt>CREATE</tt> è l'unico record obbligatorio nella 
tabella. 
 
 
<sect1>La tabella Anagrafiche 
 
<p> 
Questa tabella contiene le anagrafiche di tutte le persone fisiche  
gestite dal progetto che possono essere pazienti, informatori, 
amministratori, colleghi, specialisti, etc. 
Essa contiene soltanto i dati identificativi della persona e non della 
sua specializzazione di tipo poichè i campi specialistici sono previsti 
in tabelle separate (i pazienti nella tabella <tt>Pazienti</tt> etc.). 
 
<table LOC=hbtp>
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> Descrizione <rowsep>
      <hline> 
	CodFiscale	<colsep> CHAR <colsep> 16 <colsep> PRIMARY KEY <colsep> codice fiscale <rowsep> 
	Cognome <colsep> VARCHAR <colsep> 40 <colsep> NOT NULL <colsep> cognome <rowsep> 
	Nome    <colsep> VARCHAR <colsep> 40 <colsep> NOT NULL <colsep> nome di battesimo <rowsep> 
	LuogoNascita <colsep> VARCHAR <colsep> 40 <colsep>	<colsep> luogo di nascita  <rowsep> 
	ProvNascita  <colsep> CHAR	<colsep> 2	<colsep>	<colsep> provincia di nascita <rowsep> 
	DataNascita	 <colsep> DATE	<colsep> -- <colsep>	<colsep> data di nascita <rowsep> 
	Sesso		<colsep>  CHAR	<colsep>  1 <colsep>	<colsep> sesso <tt>"F" o "M"</tt> <rowsep> 
	ComuneResid <colsep>  VARCHAR	<colsep> 40	<colsep>	<colsep> comune di residenza <rowsep> 
	ProvResid	<colsep>  CHAR	<colsep>  2	<colsep>	<colsep> provincia di residenza <rowsep> 
	IndResid	<colsep>  VARCHAR	<colsep> 40	<colsep>	<colsep> indirizzo di residenza <rowsep> 
	CAP		<colsep>  CHAR	<colsep>  5	<colsep>	<colsep> codice di avviamento postale <rowsep> 
	TelNum	<colsep>  VARCHAR <colsep> 16	<colsep>	<colsep> numero di telefono <rowsep> 
	FaxNum	<colsep>  VARCHAR <colsep> 16	<colsep>	<colsep> numero di fax <rowsep> 
	MobileNum	<colsep>  VARCHAR <colsep> 16	<colsep>	<colsep> numero di cellulare <rowsep> 
	Email		<colsep>  VARCHAR <colsep> 40	<colsep>	<colsep> indirizzo e-mail <rowsep> 
	DataDecesso <colsep>  DATE	<colsep> -- <colsep>	<colsep> data del decesso <rowsep> 
      <hline> 
 </tabular> 
 <caption> 
         <label ID="tab_anag"> 
         Tabella Anagrafiche 
 </caption> 
 </table> 
 
<p> 
<bf>Commenti</bf> 
 
<p> 
La chiave primaria è costituita dal <em>codice fiscale</em> della persona 
fisica che è pertanto un campo obbligatorio. 
In caso di indisponibilità di esso, l'applicazione dovrebbe consentire  
il calcolo del codice fiscale dai dati anagrafici;  
in caso di indisponibilità anche di questi ultimi, l'applicazione dovrebbe 
generare un codice fiscale univoco su base casuale. 
 
<p> 
Questo modo di operare verrà mantenuto nelle prime versioni della applicazione 
ma in versioni successive, il codice fiscale dovrà essere fornito  
obbligatoriamente (o generato dai dati anagrafici). 
 
 
<sect1>La tabella Pazienti 
 
<p> 
Contiene tutti i pazienti gestiti compresi quelli privati, 
in sostituzione, convenzionati, etc. 
Questa è la tabella principale del database ed è in relazione con 
molte altre tabelle come per esempio la tabella <tt>Visite</tt>  
e <tt>FarmaciUsati</tt>. 
 
<table LOC=htbp> 
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> 
		Descrizione	<rowsep> 
      <hline> 
	IDPaziente	<colsep> CHAR <colsep> 16 <colsep> PRIMARY KEY <colsep> 
		codice fiscale del paziente<rowsep> 
	StartDate	<colsep> DATE <colsep> -- <colsep> NOT NULL <colsep> 
		data di inizio rapporto <rowsep> 
	CodUSL	<colsep> CHAR <colsep> 4  <colsep>  <colsep> 
		codice della A.S.L. <rowsep> 
	CodSSN	<colsep> CHAR <colsep> 16 <colsep>  <colsep> 
		codice del libretto sanitario <rowsep> 
	CodQualifica	<colsep> CHAR <colsep> 2 <colsep>  <colsep> 
		in relazione con tab. <tt>Qualifiche</tt> <rowsep> 
	CodEsenz		<colsep> INT4 <colsep> 4 <colsep>	<colsep> 
		codice di esenzione <rowsep> 
	 
 </tabular> 
 <caption> 
         <label ID="tab_pazi"> 
         Tabella Pazienti 
 </caption> 
 </table> 
 
<p> 
<bf>Commenti</bf> 
 
<p> 
Il campo della chiave primaria <tt>IDPaziente</tt> è in relazione 
con il campo <tt>CodFiscale</tt> della tabella <tt>Anagrafiche</tt> e deve essere 
presente in quella tabella. 
 
<p> 
I campi <tt>CodUSL</tt> e <tt>CodSSN</tt>, benchè non obbligatori 
(poichè ci possono essere pazienti privati) sono fortemente consigliati se si 
prevede di ottenere dalla <bf>A.S.L.</bf> il dischetto delle nuove esenzioni che, se non erro, 
riporta il codice SSN. 
 
<p> 
Per quanto riguarda il campo <tt>CodEsenz</tt> ho previsto un campo numerico ma non ho la 
minima idea di cosa debba contenere e se deve essere in relazione con una altra 
tabella. 
 
 
<sect1>La tabella Qualifiche 
 
<p> 
Questa tabella è <em>relazionata</em> con la tabella <ref id="tab_anag" name="<em>Anagrafiche</em>"> 
e la tabella <ref id="tab_spec" name="<em>Specialisti</em>"> e contiene le 
qualifiche speciali dei pazienti e degli specialisti come informatori, 
chirurghi, amministratori, etc. 
 
<table LOC=htbp> 
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> 
		Descrizione	<rowsep> 
      <hline> 
	CodQualifica <colsep> CHAR	<colsep> 2 <colsep> PRIMARY KEY <colsep> 
		codice di qualifica <rowsep> 
	Descrizione	 <colsep> VARCHAR	<colsep> 2 <colsep>	<colsep> 
		descrizione della qualifica <rowsep> 
 </tabular> 
 <caption> 
         <label ID="tab_qual"> 
         Tabella Qualifiche 
 </caption> 
 </table> 
 
<p> 
<bf>Commenti</bf> 
 
<p> 
In fase di installazione vengono inserite in questa tabella le qualifiche
standard utilizzate. Sarà comunque possibile aggiungerne quante si
desidera.

<table LOC=htbp> 
 <tabular CA="ll"> 
      <hline> 
      CodQualifica  <colsep> Descrizione	<rowsep> 
      <hline> 
	PI	<colsep> paziente iscritto <rowsep>
	PP	<colsep> paziente privato  <rowsep>
	PS	<colsep> paziente in sostituzione  <rowsep>
	IF	<colsep> informatore  <rowsep>
	AM	<colsep> amministratore  <rowsep>
	FO	<colsep> fornitore  <rowsep>
	MF	<colsep> medico di famiglia  <rowsep>
	MC	<colsep> medico chirurgo  <rowsep>
	MS	<colsep> medico specialista  <rowsep>
	DE	<colsep> development (riservato) <rowsep>
	<hline>
 </tabular> 
 <caption> 
         Contenuto
 </caption> 
 </table> 

<sect1>La tabella Farmaci

<p>
<table LOC=htbp> 
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> 
		Descrizione	<rowsep> 
      <hline> 
	CodFarmaco	<colsep> CHAR <colsep> 10 <colsep> PRIMARY KEY <colsep>
		il codice a barre del farmaco <rowsep>
	NomeFarmaco	<colsep> VARCHAR <colsep> 40 <colsep> NOT NULL <colsep>
		il nome del farmaco	<rowsep>
	Produttore	<colsep> VARCHAR <colsep> 32 <colsep>	<colsep>
		il produttore	<rowsep>
	<hline>
 </tabular> 
 <caption> 
         <label ID="tab_farm"> 
         Tabella Farmaci 
 </caption> 
 </table> 
 
<p> 
<bf>Commenti</bf> 
 
<p>
Questa tabella contiene tutti i farmaci prescitti dal medico 
e usati dai suoi pazienti.
Il programma viene fornito con una tabella iniziale di farmaci ma, come
si può ben immaginare, memorizzare l'intera produzione di farmaci
è impresa ardua e perciò molti farmaci anche di uso comune non saranno
disponibili.

<p>
Sarà comunque possibile inserire nuovi records mano a mano che i farmaco
viene prescritto e/o usato.
Spero, comunque, che se il progetto avrà successo, le case farmaceutiche
possano aiutarci ad implementare questo database magari fornendo un loro
database in <em>Internet</em> oppure su CD-ROM o qualunque altro supporto.

<p>
La tabella iniziale di questo database sarà realizzata con i dati
della <url url="http://www" name="Giofil"> a patto che quest'ultima mi
dia la autorizzazione all'utilizzo degli stessi.
In caso contrario, l'applicazione sarà accompagnata da un <em>programmillo</em>
di conversione dei dati della Giofil in un file leggibile dal database
ma si dovrà comunque <em>acuqistare</em> il file compresso dei dati dalla
società prima di utilizzarlo.

<p>
La chiave primaria di questa tabella è il codice del farmaco visibile sulla
confezione dello stesso - di solito vicino al codice a barre.
Nella fase iniziale, questo codice non sarà obbligatorio; sembra un
controsenso viso che si tratta di una <em>primary key</em> ma, la non
obbligatorietà del dato riguarda l'applicazione, non la tabella.
Se il codice del farmaco non sarà disponibile, esso sarà
generato in modo casuale ed univoco dalla applicazione.


<sect1>La tabella Composizione

<p>
In questa tabella viene memorizzata la composizione dei farmaci,
limitatamente ai loro <em>principi attivi</em>.
Per ogni farmaco ci possono essere uno o più record che ne descrivono
la composizione.

<p>
Nella organizzazione di questa tabella sono sempre stato combattuto tra
due soluzioni possibili:

<itemize>
<item>usare nei records di composizione dei farmaci il codice che si riferisce
	al farmaco ed un campo di tipo carattere che ne indica il principio
	attivo come, per esempio, <bf>desametasone</bf>
<item>usare per il campo della composizione un codice numerico, una sorta di
	<em>ID</em> da mettere in relazione con una tabella esterna che contiene
	tutti i principi attivi
</itemize>

<p>
Il vantaggio della seconda soluzione è evidente: tanti più sono i farmaci
che contengono lo stesso principio attivo tanto più megabytes di spazio
si risparmiano.
Ma ovviamente questo risparmio si paga con una maggiore complessità del
database e, di riflesso, anche delle applicazioni ad esso collegate.

<p>
Poichè dai <em>mass media</em> si sente sempre affermare che ci sono in
circolazione migliaia di farmaci inutili e assolutamente uguali ad altri
già in commercio, ne deduco che la quantità dei <em>principi attivi</em>
è di gran lunga inferiore a quella dei farmaci in commercio.
Perciò opterò per la seconda soluzione.

<p>
La tabella non possiede una chiave primaria poichè essa dovrebbe essere
lunga quanto l'intero record.
Tuttavia, entrambi i campi che compongono il record saranno indicizzati.

<table LOC=htbp> 
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> 
		Descrizione	<rowsep> 
      <hline> 
	CodFarmaco	<colsep> CHAR <colsep> 10 <colsep> NOT NULL <colsep>
		il codice a barre del farmaco <rowsep>
	CodPrincipio <colsep> INT4 <colsep> -- <colsep> NOT NULL <colsep>
		il codice del principio attivo <rowsep>
	<hline>
 </tabular> 
 <caption> 
         <label ID="tab_comp"> 
         Tabella Composizione dei farmaci 
 </caption> 
 </table> 
 
<p> 
<bf>Commenti</bf> 

<p>
Nessuno dei due campi del record può avere un valore <tt>NULL</tt> e,
inoltre, anche se non previsto dalla tabella, vi è una restrizione
sul contenuto dei due campi:
il valore di entrambi deve essere relazionato con i corrispondenti 
campi delle tabelle <em>Farmaci</em> e <em>Principi</em>.

<p>
Se il &engine; da Voi usato supporta le chiavi esterne e il modello
relazionale, vi consiglio di applicare questi <em>constraint</em> già
nella tabella e non lasciare il controllo alla applicazione.

<p>
Non è obbligatorio per un farmaco presente nella tabella <em>Farmaci</em>
avere anche la composizione: se il codice del farmaco non esiste in
questa tabella significa che la sua composizione non è disponibile.

  
<sect1>La tabella Principi

<p>
Elenca tutti i principi attivi di cui sono composti i farmaci presenti
nella tabella <ref id="tab_farm" name="Farmaci">.

<table LOC=htbp> 
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> 
		Descrizione	<rowsep> 
      <hline> 
	CodPrincipio <colsep> INT4 <colsep> -- <colsep> PRIMARY KEY <colsep>
		il codice del principio attivo <rowsep>
	NomePrincipio <colsep> VARCHAR <colsep> 40 <colsep> NOT NULL <colsep>
		il nome del principio attivo <rowsep>
	<hline>
 </tabular> 
 <caption> 
         <label ID="tab_princ"> 
         Tabella dei Principi Attivi
 </caption> 
 </table> 


<sect1>La tabella Specialisti

<p>
In relazione con la tabella <ref id="tab_anag" name="Anagrafiche">
questa contiene i nominativi di persone che non sono pazienti ma invece
collaboratori a vario titolo.
Il tipo di collaboratore viene determinato dal campo <tt>CodQualifica</tt>
che è in relazione con la tabella <ref id="tab_qual" name="Qualifiche">.

<table LOC=htbp> 
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> 
		Descrizione	<rowsep> 
      <hline> 
	CodAnagr <colsep> CHAR <colsep> 16 <colsep> PRIMARY KEY <colsep>
		il codice fiscale <rowsep>
	CodQualifica <colsep> CHAR <colsep> 2 <colsep> NOT NULL <colsep>
		il codice della qualifica <rowsep>
	Struttura <colsep> VARCHAR <colsep> 40 <colsep>  <colsep>
		struttura, società, etc	 <rowsep>
	Note	  <colsep> VARCHAR <colsep> 40   <colsep>  <colsep>
		note  <rowsep>
	<hline>
 </tabular> 
 <caption> 
         <label ID="tab_spec"> 
         Tabella Specialisti
 </caption> 
 </table> 

<bf>Commenti</bf> 

<p>
Il campo <tt>CodAnagr</tt> che costituisce la chiave primaria dei records
è in relazione con la tabella <em>Anagrafiche</em>.
Anche per questo campo, se il &engine; prevede la possibilità di definire
<em>chiavi esterne</em> è opportuno usare la relazione in modo da
evitare casi di inconsistenza della tabella.
L'applicazione, comunque, esegue già un controllo di questo tipo per quei
DBMS che non prevedono il modello relazionale.

<p>
Il campo <tt>Note</tt> è lasciato ai gusti personali dell'utente che lo può
usare come meglio crede, mentre il campo <tt>Struttura</tt> dovrebbe contenere
la struttura o società o commento a seconda del tipo di qualifica dello
specialista.
Ad esempio, se lo specialista è un chirurgo, il campo conterrà l'ospedale
o clinica privata presso cui egli opera, se invece si tratta di un fornitore,
verrà indicato il nome della ditta fornitrice.


<sect1>La tabella Visite

<p>
Questa tabella memorizza tutte le visite fatte ai pazienti registrati nel
database, il motivo della visita, la diagnosi emessa e l'eventuale prognosi
per il paziente.

<p>
Ovviamente, sia la diagnosi che la prognosi sono modificabili in ogni momento
poichè per questi dati non si ha mai la sicurezza matematica.

<table LOC=htbp> 
 <tabular CA="lllll"> 
      <hline> 
      Campo  <colsep> Tipo <colsep> Lungh <colsep> Constraint <colsep> 
		Descrizione	<rowsep> 
      <hline> 
	CodAnagr <colsep> CHAR <colsep> 16 <colsep> PRIMARY KEY <colsep>
		il codice fiscale <rowsep>
	DataVisita <colsep>  DATE <colsep> -- <colsep> PRIMARY KEY <colsep>
		la data della visita <rowsep>
	Motivo <colsep> TEXT <colsep> -- <colsep> NOT NULL <colsep>
		il motivo della visita  <rowsep>
	Diagnosi  <colsep> VARCHAR <colsep> 40   <colsep>  <colsep>
		la diagnosi temporanea  <rowsep>
	Prognosi  <colsep> INT4 <colsep> ..   <colsep>  <colsep>
		numeri di giorni previsti <rowsep>
	<hline>
 </tabular> 
 <caption> 
         <label ID="tab_visi"> 
         Tabella Specialisti
 </caption> 
 </table> 

<p>
<bf>Commenti</bf> 

<p>
Non credo ci sia molto da dire su questa tabella poichè i campi mi sembrano
molto <em>autoesplicativi</em>.
Se la prognosi è riservata il campo <tt>Prognosi</tt> conterrà
il valore <tt>-1</tt>.

<p>
Per quanto riguarda il campo <tt>Diagnosi</tt> esso è di tipo <tt>VARCHAR</tt> 
in modo che possa accettare qualsiasi stringa di caratteri.
Tuttavia, si dovrebbe inserire in questo campo sempre e solo il nome <em>completo 
e canonico</em> della diagnosi emessa per il paziente evitando modi di dire e/o
abbreviazioni dei termini.

<p>
Questo per poter garantire una certa precisione nelle query statistiche; se si 
vuole conoscere il numero di pazienti o il periodo dell'anno in cui si verifica 
una specifica infezione, i risultati non saranno corretti se ogni volta che si 
essa si presenta, verrà indicata con nomi diversi.

<p>
Il &luigi ha il desiderio di codificare tutte le diagnosi in formato numerico e 
relazionare questo campo con una tabella esterna contenente i nomi di tutte le possibili 
diagnosi in modo da costringere l'utente ad usare uno ed un solo nome per ogni diagnosi.

<p>
Prevedo che la codica delle diagnosi sarà un lavoro <bf>titanico</bf> e perciò in questa
prima versione del database questo <em>feature</em> non sarà disponibile.



<sect>Sicurezza

<p>
Non è nelle mie intenzioni fare in questa sede un trattato sulla
sicurezza poiché sono già stati scritti bidoni di toner a questo proposito
da persone certamente più esperte di me.

<p>
Se l'applicazione viene installata su un computer stand-alone, non
connesso ad una rete, e chiuso nello studio, penso che non ci dovrebbero
essere problemi. Tuttavia, poiché il database può risiedere fisicamente
su sistemi remoti elenco di seguito le principali caratteristiche del
programma in configurazione di default che potrebbero costituire dei
pericoli per la riservatezza dei dati; non dimentichiamo infatti che
questa applicazione gestisce pazienti di studi medici e che le
informazioni sulla salute delle persone sono considerate <em>dati sensibili</em>
e che pertanto vanno protette.

<itemize>
<item> il nome dello user postgres di default usato dalla applicazione è-
   &user; al quale non viene associata alcuna password; l'amministratore
   di sistemi server dovrebbe assegnare una password agli utenti.
   Si ricorda, comunque, che questo è un utente del DBMS che non ha nulla
   a che fare col nome di login degli utenti &unix;.
<item>l'utente &user è autorizzato a creare nuovi database; in un
   sistema condiviso questo potrebbe creare problemi e, perciò, sarà
   necessario togliere questo privilegio all'utente. Il database può
   essere creato dall'amministratore mentre il comando <tt>initmedx</tt> può
   essere eseguito tralasciando la creazione del DB
<item>su sistemi server che forniscono servizi a molti utenti diversi sarà
   opportuno cancellare l'utente di default e creare, invece, un numero
   appropriato di utenti da assegnare a persone diverse.
<item>alle tabelle del database viene garantito un accesso public
   all'utente &user;.
   su sistemi server sarà opportuno assegnare gli accessi a seconda
   degli utenti ed in particolare l'accesso PUBLIC dovrebbe essere 
   garantito solo alle tabelle che non contengono dati sensibili.
</itemize>


</article>


