• Non ci sono risultati.

2.3 Modellazione degli oggetti web

2.3.6 Repository e web object

Gli oggetti modellati sono memorizzati in modo persistente attraverso l’uso di classi che fungono da repository per tali oggetti.

Oltre alla suddivisione logica in insiemi distinti di oggetti omogenei, gi`a sviluppata nel prototipo del sistema, `e stata fornita anche la possibilit`a di una reale suddivisione di tali insiemi in pi`u file. Se inizialmente infatti la suddivisione in repository era soltanto logica e tutti gli oggetti dovevano ri- siedere in uno stesso file, adesso questa scelta `e lasciata all’utente finale che pu`o decidere in base ad esigenze di spazio o di comodit`a se disporre i repo- sitory che vengono creati su uno o pi`u file.

2.2.3.6 Repository e web object 47

Figura 2.2: Diagramma delle classi: repository & web object

zionale. Ogni repository introdotto corrisponde ad una tabella, e ogni oggetto in esso contenuto ad una entry della tabella. Come nel caso relazionale, in un repository possono essere contenuti solo oggetti omogenei, cio`e di uno stesso tipo. I file (con estensione .dbs) in cui sono memorizzati gli elementi, che devono essere resi persistenti, corrispondono ad un database. Come un database relazionale in genere contiene diverse tabelle, analogamente ognuno di questi file pu`o contenere uno o pi`u repository, anche contenenti ognuno un diverso tipo di oggetti. Viceversa mentre non possiamo mettere in relazione tabelle di diversi database, in questo caso gli oggetti possono contenere anche riferimenti ad oggetti non memorizzati nello stesso file, ma in un altro, anzi questa suddivisione risulta utile nel caso di database molto grandi in quanto i vari repository possono essere distribuiti su file diversi. Infatti possiamo tranquillamente avere pi`u repository contenenti istanze di una stessa classe.

Il diagramma 2.2 mostra quali sono i repository introdotti e quali oggetti contengono.

Sia gli oggetti web, sia i repository ereditano da due classi, che forniscono delle interfacce, che danno indicazioni sui metodi indispensabili da implemen- tare se si volesse introdurre un nuovo oggetto. Inoltre permettono di rendere i metodi implementati validi per qualsiasi tipo di oggetto web, sia esso un HttpRequest o un oggetto di tipo Session, o un qualsiasi altro tipo.

48 Web Object Store

Ogni repository gestisce l’interfaccia con Gigabase e fornisce i metodi per inserire e recuperare oggetti nel database. Queste classi, che possono sem- brare superflue, dal momento che si potrebbero chiamare direttamente le funzioni di Gigabase nel momento opportuno, sono invece fondamentali, poi- ch´e con la loro presenza permettono di cambiare il gestore delle persistenza senza dover riscrivere tutta l’applicazione, ma solo modificando i metodi al loro interno. Questo `e fondamentale dal momento che l’obiettivo `e rendere le varie componenti del sistema il pi`u possibile indipendenti l’una dall’altra.

Osserviamo adesso i metodi e gli attributi di un generico repository. Mostriamo solo quelli di una classe generica in quanto le differenze sono minime.

dbDatabase* db; char* filename;

Repository(char* filename, dbAccessType databaseAccess); void commit();

void open(char* filename); void close();

dbCursor<WebObject>* cursor_id;

void first_id(); // posiziona il cursore sul primo elemento void last_id(); // posiziona il cursore sull’ultimo elemento bool next_id(); // avanza il cursore di una posizione

WebObject* get_by_id(int key); // restituisce l’elemento con id = key WebObject* get_by_id(); // restituisce l’elemento puntato

dal cursore

void update_by_id(WebObject* obj); // aggiorna obj

WebObject * put(WebObject obj); // inserisce obj nel repository

I precedenti sono gli attributi e i metodi minimali che ogni oggetto che rea- lizzi un repository deve avere. I cursori sono il meccanismo con cui Gigabase permette di accedere e modificare gli elementi memorizzati e ne possono es- sere definiti uno per ogni attributo. Tutte le operazioni sul database vengono fatte tramite cursori, tranne l’inserzione di un nuovo oggetto.

2.2.3.6 Repository e web object 49

Per il precedente repository `e stato definito un cursore che permette di scorrere elementi in modo sequenziale (con i metodi first id(),next id()e

last id()) e di recuperare l’elemento attualmente puntato dal cursore, con il metodoget by id(). E’ possibile anche una ricerca per chiave (get by id(int key)). Sono presesti infine metodi per aggiornare all’interno del database

un oggetto che `e stato modificato (update by id(WebObject* obj)) e per

insierirne uno nuovo (put(WebObject obj)).

In genere si definisce un cursore su tutti gli attributi che serviranno per il recupero degli elementi per chiave o in modo ordinato, altrimenti uno `e sufficiente. Per ogni cursore definito sul database, comunque, `e necessario implementare i metodi per accedere agli oggetti in modo sequenziale e per chiave. Sono inoltre indispensabili i metodi per la modifica e l’inserimento di nuovi oggetti.

Per effettuare operazioni su un database `e necessario che il repository corrispondente sia aperto. All’apertura di un repository si deve specificare il file in cui `e stato o deve essere memorizzato il database: nel caso in cui il file non esista ne viene creato uno nuovo, altrimenti viene aperto, con il metodo

open(char* filename). L’apertura e la chiusura dei repository sono un pun- to abbastanza delicato poich´e Gigabase non permette di aprire, in scrittura, un repository, precedentemente aperto allo stesso modo. Questo implica che ogni volta che si cerca di caricare un nuovo database `e necessario effettuare i dovuti controlli per evitare eccezioni a tempo di esecuzione. Per rendere que- sti controlli trasparenti all’utente finale l’apertura e la chiusura dei database `

e gestita interamente all’interno dei metodi forniti. Questo meccanismo ha come conseguenza il fatto che, a seconda delle modalit`a di utilizzo, talvolta vengono chiusi database che verranno riaperti poco dopo, con conseguente calo di efficienza. Per questo, come vedremo nella prossima sezione, viene lasciata anche la possibilit`a di eseguire i metodi di preprocessing su databa- se gi`a aperti, lasciando all’utente, il compito di controllare che non vengano eseguite operazioni illecite.

50 Web Object Store

Documenti correlati