Ottimizzazione e implementazione della verifica d...
Transcript of Ottimizzazione e implementazione della verifica d...
POLITECNICO DI MILANO
Facoltà di Ingegneria
Corso di laurea in Ingegneria Informatica
Ottimizzazione e implementazione della verifica
d’integrità per applicazioni web.
Relatore: Prof. Marco Brambilla
Tesi di laurea di:
Marco Vadrucci
Matricola n. 639317
Anno Accademico 2006/2007
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 2 ~
Alla mia famiglia.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 3 ~
Desidero ringraziare
il professor Marco Brambilla per la sua guida
e
il professor Jordi Cabot Sagrera per i suoi preziosi consigli tecnici.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 4 ~
SOMMARIO
1. INTRODUZIONE ............................................................................................ 6
1.1. I VINCOLI D’INTEGRITÀ ..................................................................................................... 6
1.2. TECNOLOGIE ATTUALMENTE ESISTENTI ............................................................................. 6
1.3. L’APPROCCIO PROPOSTO .................................................................................................... 7
1.4. IL PROGETTO GENERALE DEL METODO AUTOMATICO .......................................................... 9
2. BACKGROUND ............................................................................................. 11
2.1. UML ............................................................................................................................... 11
2.2. WEBML .......................................................................................................................... 14
2.3. OCL ................................................................................................................................ 19
2.3.1. Necessità di OCL ....................................................................................................... 19
2.3.2. Sintassi di OCL ......................................................................................................... 21
2.3.3. Pre-condizioni e post-condizioni ............................................................................. 24
2.3.4. Contesto del package ............................................................................................... 25
2.4. MODELLO DI ESEMPIO .................................................................................................... 26
3. ANALISI DEI VINCOLI D’INTEGRITÀ .......................................................... 29
3.1. ESTRAZIONE DEGLI EVENTI STRUTTURALI POTENZIALMENTE VIOLANTI DAI METAMODELLI 29
3.2. SCARTO DEGLI EVENTI STRUTTURALI CHE NON POSSONO ACCADERE .................................. 31
4. DETERMINAZIONE DELL’IMPLEMENTAZIONE OTTIMALE ....................... 36
4.1. CLASSIFICAZIONE DEI VINCOLI D’INTEGRITÀ .................................................................... 36
4.2. PARAMETRI DIPENDENTI DALL’AMBIENTE DI ESECUZIONE ................................................ 38
4.2.1. Tempo di controllo .................................................................................................. 38
4.2.2. Efficienza di esecuzione ........................................................................................... 39
4.2.3. Volume della popolazione ....................................................................................... 40
4.2.4. Uso del DBMS .......................................................................................................... 40
4.2.5. Scelta dei parametri ................................................................................................. 41
4.3. METODI DI IMPLEMENTAZIONE DELLA VERIFICA D’INTEGRITÀ ........................................... 41
4.3.1. Implementazione diretta ......................................................................................... 42
4.3.2. Trigger ..................................................................................................................... 46
4.3.3. View efficienti .......................................................................................................... 47
4.3.4. Approccio Semi-efficiente ....................................................................................... 49
4.3.5. Check ......................................................................................................................... 51
4.3.6. Check (differito) ........................................................................................................ 51
4.4. REGOLE PER LA DETERMINAZIONE DEL METODO DI IMPLEMENTAZIONE OTTIMALE ........... 52
4.4.1. Tempo di controllo: immediato .............................................................................. 54
4.4.2. Tempo di controllo: rinviato ................................................................................... 54
4.4.3. Tempo di controllo: posticipato .............................................................................. 55
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 5 ~
5. ICTUNINGGUI ............................................................................................. 58
5.1. FUNZIONALITÀ ............................................................................................................... 58
5.1.1. Vincoli d’integrità ed eventi strutturali .................................................................. 58
5.1.2. Tecniche implementative ........................................................................................ 58
5.1.3. Generazione del codice SQL .................................................................................... 59
5.2. ALGORITMI UTILIZZATI IN ICTUNINGGUI ........................................................................ 59
5.2.1. Estrazione degli eventi strutturali .......................................................................... 59
5.2.2. Classificazione dei vincoli d’integrità ..................................................................... 60
5.2.3. Determinazione delle tecniche migliori .................................................................. 62
5.2.4. Generazione dei trigger .......................................................................................... 62
5.2.5. Generazione delle view semi-efficienti ................................................................... 64
5.2.6. Generazione delle view efficienti ............................................................................ 65
5.2.7. Generazione dei Check e dei Check differiti ............................................................ 68
5.3. DESIGN DI ICTUNINGGUI ............................................................................................... 69
5.3.1. PSERelevant ............................................................................................................ 69
5.3.2. Dresden OCL Toolkit ............................................................................................... 70
5.3.3. Struttura di ICTuningGui ........................................................................................ 71
5.3.4. Package model .......................................................................................................... 71
5.3.5. Package technique ................................................................................................... 73
5.3.6. Package technique, classe TechniqueChooser ........................................................ 74
5.4. MANUALE D’USO DI ICTUNINGGUI .................................................................................. 74
5.4.1. Estrazione dei vincoli e dei relativi PSE ................................................................. 78
5.4.2. Pannello di configurazione dei parametri ............................................................. 79
5.4.3. Determinazione delle tecniche ................................................................................ 80
5.4.4. Configurazione del generatore SQL ....................................................................... 83
5.4.5. Generazione del codice SQL .................................................................................... 85
5.5. PROBLEMI NOTI .............................................................................................................. 86
5.5.1. Necessità di due modelli .......................................................................................... 86
5.5.2. Consistenza dei nomi utilizzati ............................................................................... 87
6. ESEMPIO DI UTILIZZO DELL’APPLICAZIONE ............................................ 88
7. CONCLUSIONE .......................................................................................... 100
7.1. SVILUPPI FUTURI ........................................................................................................... 101
7.1.1. Supporto per altre tecnologie ................................................................................ 101
7.1.2. Integrazione in WebRatio ...................................................................................... 101
7.1.3. Eliminazione della necessità del file XMI ............................................................. 102
8. BIBLIOGRAFIA .......................................................................................... 103
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 6 ~
1. INTRODUZIONE
I sistemi informativi moderni sono spesso costituiti da diversi componenti e
applicazioni, talvolta distribuiti in siti separati e sviluppati in tempi e luoghi
diversi. Pertanto, fin dalle prime fasi della progettazione del sistema, nasce la
necessità di garantire la consistenza della base di informazioni utilizzata. La
consistenza delle informazioni viene definita attraverso dei vincoli d’integrità
(Integrity Constraints o IC).
1.1. I VINCOLI D’INTEGRITÀ
I vincoli d’integrità sono definiti durante la progettazione di alto livello (schema
concettuale) del sistema informativo11 e definiscono delle condizioni che devono
essere soddisfatte in ogni stato della base di informazioni sottostante,
generalmente costituita da una base di dati relazionale. Il sistema informativo
deve quindi garantire che la base di informazioni sia sempre consistente con
l’insieme dei vincoli d’integrità imposti nello schema concettuale. Il processo di
controllo di tali vincoli viene chiamato controllo d’integrità (Integrity
Checking).
1.2. TECNOLOGIE ATTUALMENTE ESISTENTI
I metodi di sviluppo web attuali prestano poca attenzione ai problemi di
controllo d’integrità, nonostante la sua importanza. Alcuni linguaggi per la
modellazione concettuale per il web, come ad esempio W20001, supportano il
controllo dei vincoli d’integrità solo a livello di metamodello, limitando così il
modo in cui i modelli possono essere progettati ma non imponendo stati
consistenti della base di informazioni durante l’esecuzione dell’applicazione.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 7 ~
Altri linguaggi, come ad esempio WebML3,4, utilizzano regole ECA (Event –
Condition - Action), un tipico metodo di implementazione dei vincoli
d’integrità, ma solo per la gestione degli errori e la definizione di regole di
adattamento. La maggior parte dei linguaggi utilizza approcci basati su regole
per personalizzare e generare dinamicamente le pagine web ma nessun
linguaggio fornisce attualmente metodi per la gestione generalizzata dei vincoli
d’integrità per la base di informazioni7,8,9,16. In particolare non esistono tecniche
efficienti e flessibili per l’implementazione automatica della verifica d’integrità.
1.3. L’APPROCCIO PROPOSTO
Fin dall’inizio degli anni ’90 sono ben noti metodi per il controllo efficiente
dell’integrità nel campo delle basi di dati deduttive e relazionali10. Questi
metodi, conosciuti anche come metodi incrementali, sfruttano le
informazioni disponibili riguardo agli eventi strutturali in relazione alla base
di informazioni per considerare il minor numero di entità possibile durante il
controllo dei vincoli d’integrità. Un evento strutturale è un cambiamento
elementare nella popolazione di un’entità o di una relazione, come ad esempio:
creare un oggetto, aggiornare un attributo, creare una relazione e così via. Gli
eventi strutturali sono un modo per definire gli effetti delle operazioni che
compaiono nello schema concettuale.
I metodi incrementali potrebbero essere integrati nell’approccio allo sviluppo
web per garantire controlli d’integrità efficaci ed efficienti per i vincoli definiti
nello schema concettuale. In particolare, i metodi di generazione automatica di
codice per il web potrebbero essere migliorati con le tecniche incrementali in
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 8 ~
modo tale che l’implementazione generata dei vincoli d’integrità sia capace di
verificare efficientemente la consistenza della base di informazioni.
Sebbene la grande varietà e complessità dei requisiti delle applicazioni web e
degli scenari in cui sono usate rendano necessaria tale integrazione, la
complessità stessa del dominio di applicazione ne comporta un rallentamento.
Risulta impossibile, infatti, per una singola strategia incrementale essere adatta
a tutti i requisiti di tutte le applicazioni web. Per esempio, alcune applicazioni
potrebbero essere interessate alla verifica dell’integrità dopo ogni singolo evento
derivante dall’attività dell’utente, mentre altre potrebbero preferire rimandare il
controllo alla fine della transazione per fornire all’utente un’esperienza più
flessibile; oppure altre ancora potrebbero richiedere il minore tempo di risposta
possibile per l’utente, anche se questo dovesse comportare un controllo
dell’integrità a posteriori più oneroso. Un’ulteriore possibilità è rappresentata
dal rimandare a una certa ora del giorno tutti i controlli d’integrità, per ridurre il
carico dei server nei momenti di traffico intenso.
I metodi incrementali attualmente esistenti, d’altra parte, non prendono in
considerazione i modelli dinamici delle applicazioni. Durante l’elaborazione dei
vincoli d’integrità viene sempre considerato il caso pessimo, rappresentato dal
fatto che tutti i possibili eventi strutturali possono essere applicati alla base di
informazioni. Spesso però le applicazioni web offrono possibilità di gestione
delle informazioni limitate (ad esempio, non tutti i dati possono essere
modificati dall’applicazione). In questi casi, alcune strutture dati create nella
base di informazioni per assicurare una verifica efficiente risultano inutili e
possono essere rimosse per aumentare l’efficienza di esecuzione
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 9 ~
dell’applicazione. Ovviamente c’è una forte assunzione a priori: il processo di
ottimizzazione deve essere a conoscenza di tutte le applicazioni che opereranno
sulla base di informazioni e tenerne conto durante la fase di ottimizzazione.
1.4. IL PROGETTO GENERALE DEL METODO AUTOMATICO
Il progetto di un’applicazione web consiste nella definizione dello schema
concettuale, eventualmente avvalendosi di uno strumento CASE (Computer -
Aided Software Engineering), e dei vincoli d’integrità, espressi in linguaggio di
specifica come OCL (Object Constraint Language).
FIGURA 1: SCHEMA DELL'APPROCCIO PROPOSTO.
L’approccio proposto è raffigurato in Figura 1 e consta dei seguenti passaggi:
1. Dato un insieme di vincoli d’integrità, il metodo esegue un’analisi per
determinare quali cambiamenti (eventi strutturali) nella base di
informazioni possono infrangere i vincoli2. Tali eventi vengono chiamati
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Introduzione
~ 10 ~
Eventi Strutturali Potenzialmente Violanti (Potentially-Violating
Structural Events o PSE).
2. Dato il modello concettuale dinamico (o modello di ipertesto), il
metodo rimuove tutti gli eventi strutturali potenzialmente violanti che
non vi compaiono, eseguendo quindi una riduzione degli eventi estratti
nel primo punto.
3. In base ad alcuni requisiti, forniti dall’analista sotto forma di
parametri, il metodo analizza ogni vincolo d’integrità e suggerisce una
tecnica per implementare ciascun vincolo. Questi risultati possono
essere rimandati allo strumento di progettazione per pilotare gli
algoritmi di generazione del codice oppure essere forniti direttamente
allo sviluppatore per guidarlo nella progettazione.
Si noti che il metodo sfrutta due strategie distinte: prima la riduzione degli
eventi strutturali potenzialmente violanti, poi la determinazione della tecnica di
implementazione migliore per ogni vincolo d’integrità. Questi due metodi
possono essere applicati indipendentemente l’uno dall’altro e anche
l’applicazione di uno solo di essi può comportare un vantaggio in termini di
efficienza. E’ quindi possibile effettuare la riduzione degli eventi strutturali
potenzialmente violanti e procedere poi all’implementazione dei vincoli
rimanenti in maniera tradizionale, oppure implementare tutti i vincoli con la
tecnica più idonea.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 11 ~
2. BACKGROUND
Questa sezione ha lo scopo di illustrare le tecnologie e i linguaggi utilizzati nel
seguito della trattazione.
2.1. UML
UML (Unified Modeling Language)14 è un linguaggio di modellazione visuale
generico per specificare, costruire e documentare sistemi, utilizzato nei più
importanti domini di applicazione e piattaforme di implementazione. È stato
largamente adottato sia dall’industria sia dal mondo accademico come
linguaggio standard per la definizione di sistemi informativi. Questo si traduce
nella disponibilità di centinaia di strumenti commerciali e open-source.
D’altro canto, il fatto che UML sia una notazione generica può limitare la sua
efficacia nel modellare alcuni domini specifici20, per i quali esistono linguaggi e
strumenti specializzati. Un esempio di linguaggio specializzato per la
modellazione delle applicazioni web è WebML, che sarà illustrato nel paragrafo
successivo. Questi linguaggi specifici per un dominio (Domain Specific
Languages o DSL) tendono a supportare un’astrazione di più alto livello dei
linguaggi di modellazione generici, dando quindi l’impressione ai modellatori di
lavorare direttamente con i concetti e la semantica specifici del dominio in
considerazione. Inoltre le regole del dominio possono essere incluse nel
linguaggio come vincoli che impediscono di specificare modelli non conformi o
non corretti. Per questi motivi un linguaggio specifico per un dominio è
considerato più vicino al dominio del problema anziché al dominio
dell’implementazione.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 12 ~
Nonostante i potenziali benefici derivanti dall’uso di linguaggi specifici, nel
breve termine si può osservare un crescente interesse verso UML e MOF (Meta
Object Facility) per la modellazione di applicazioni web. Questo deriva dal fatto
che sempre più spesso si ha la necessità di scambiare informazioni con altri
strumenti e notazioni, nonché di scambiare modelli e dati, aumentando così la
riutilizzazione del lavoro già svolto. Per questo i DSL, nonostante possano
risultare più idonei per modellare alcuni aspetti delle applicazioni web rispetto a
UML, non hanno ancora raggiunto la diffusione e il supporto di cui UML gode.
UML consiste di diverse viste:
Diagramma delle classi (class diagram)
Diagramma dei casi d’uso (use case diagram)
Diagramma di stato (state diagram)
Diagramma delle attività (activity diagram)
Diagramma delle collaborazioni (collaboration diagram)
Diagramma delle sequenze (sequence diagram)
Diagramma dei componenti (component diagram)
Diagramma dello spiegamento (deployment diagram)
Per il metodo proposto sarà utilizzato il diagramma delle classi, un esempio del
quale è riportato in Figura 2.
Un diagramma delle classi è costituito da diversi componenti principali, che
rappresentano le entità del sistema:
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 13 ~
Package: I Package sono usati per organizzare il modello. Le classi
possono essere poste al loro interno oppure utilizzate per esprimere
l’interdipendenza tra i package.
FIGURA 2: UN ESEMPIO DI DIAGRAMMA DELLE CLASSI UML
Dipendenze: definite tra i package, esprimono il fatto che le classi
all’interno di un package utilizzano le classi dell’altro package
Collaborazioni: definite tra oggetti, richiede che sia associato
Classificatore per indicare il ruolo svolto da un elemento nella
collaborazione
Interfacce: possono contenere metodi, non attributi. I metodi sono
astratti e non hanno implementazione all’interno dell’interfaccia. Le
classi che implementano l’interfaccia devono anche implementare i
metodi.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 14 ~
Classi: le classi sono il concetto principale nello sviluppo software
orientato agli oggetti e in UML. Le classi contengono metodi e attributi e
sono in relazione con altre classi tramite associazioni o relazioni
gerarchiche. Una classe ha alcune proprietà specifiche, come il nome, lo
stereotipo e la visibilità, ma la sua caratteristica principale è la sua
relazione con le altre classi.
Relazioni gerarchiche: relazioni tra interface o tra classi. Non sono
permesse tra un’interfaccia e una classe.
Relazioni di implementazione: relazioni che esistono solo tra interfacce
e classi.
Relazioni di associazione: relazioni tra classi.
Per una definizione completa di UML, si può consultare il sito del OMG
http://www.omg.org/.
Come sarà illustrato nei capitoli successivi, lo studio proposto si basa su
WebML, ma a causa del supporto esclusivo a UML fornito dalle fondamentali
librerie software che sono state utilizzate, è stato necessario adottare anche un
modello UML dell’applicazione web. Ulteriori dettagli su questo problema
saranno illustrati nel Capitolo 8.
2.2. WEBML
WebML18 è un linguaggio di modellazione specifico per la modellazione di
applicazioni web. Sviluppato dal Politecnico di Milano, descrive le
applicazioni web a tre livelli di dettaglio: gli oggetti, l’organizzazione
dell’interfaccia utente e l’aspetto grafico. Gli oggetti sono definiti tramite
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 15 ~
un modello dei dati Entità - Relazione semplificato (in pratica un diagramma
delle classi UML semplificato) che comprende classi, entità, attributi, eredità
singola, relazioni binarie ed espressioni di derivazione dei dati. Un esempio di
modello E-R in WebML è rappresentato in Figura 3.
L’interfaccia utente è definita utilizzando il modello di ipertesto (hypertext
model), costituito da un’organizzazione gerarchica: ogni applicazione
corrisponde a una site view (vista del sito), organizzata internamente in aree
che a loro volta possono essere divise in sotto-aree o pagine. Un esempio di
modello di ipertesto è riportato in Figura 4. Allo stesso modello dei dati
possono essere associate molteplici site view, ad esempio per rappresentare
applicazioni che lavorano sugli stessi dati ma che sono destinate a diverse
tipologie di utenti oppure a diverse periferiche (web, telefoni cellulari, …).
FIGURA 3: MODELLO ENTITÀ-RELAZIONE DI WEBML
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 16 ~
Site view, aree e pagine non sono solo unità di modulazione, ma gestiscono
anche l’accesso, che può essere selettivamente concesso ad ogni singolo
modulo in base all’identità dell’utente e alla sua appartenenza a gruppi di utenti.
La configurazione base della navigazione, indipendente dal contenuto delle
pagine, può essere espressa sulle site view, aree e pagine tramite appositi
marchi. Se una pagina o un’area è marcata come landmark (L) (punto di
riferimento), questa sarà raggiungibile da tutte le altre aree e pagine dello stesso
modulo tramite appositi comandi di navigazione. Se una pagina o un’area è
marcata come default (D), sarà visualizzata come prima pagina quando si
accederà al modulo che la contiene. Se una pagina è marcata come home (H),
sarà mostrata all’avvio dell’applicazione.
Le pagine sono i contenitori base delle interfacce; possono essere strutturate in
sotto-pagine e comprendere unità di gestione dei contenuti (content unit).
Un’unità di gestione dei contenuti è definita come un componente che pubblica
dati di qualche tipo in una pagina. I dati pubblicati possono essere estratti
dinamicamente dagli oggetti specificati nel modello dei dati oppure essere
definiti staticamente nel modello di ipertesto, come nel caso di un form per
l’inserimento di dati. Oltre alle unità di gestione dei contenuti, WebML
comprende anche unità di operazione (operation units), definite come
componenti che eseguono operazioni logiche arbitrarie, quali l’inserimento o
l’eliminazione di una tupla nella base di dati, tra le altre. Le unità di operazione,
diversamente dalle unità di gestione dei contenuti, non pubblicano informazioni
e di conseguenza sono poste all’esterno delle pagine. I componenti (unità di
gestione dei contenuti e di operazione) possono essere dotati di parametri di
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 17 ~
ingresso e uscita, come l’OID (un identificativo univoco posseduto da ogni
oggetto definito in WebML) dell’oggetto da mostrare o modificare.
FIGURA 4: MODELLO DI IPERTESTO DI WEBML
Il passaggio dei parametri è espresso come effetto collaterale della
navigazione: i componenti sono collegati tra loro da collegamenti (link) che
hanno una triplice funzione:
Rendere possibile la navigazione tra i moduli da parte dell’utente.
Supportare il passaggio dei parametri.
Innescare l’esecuzione dei componenti.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 18 ~
In sostanza, un ipertesto WebML può essere descritto essenzialmente come un
grafo di componenti parametrici, connessi tramite collegamenti, nei quali
alcuni componenti pubblicano dei contenuti e sono contenuti all’interno di
pagine, mentre altri componenti eseguono operazioni logiche e sono innescati
dai collegamenti uscenti dalle pagine. I collegamenti esprimono l’impianto
dell’applicazione e ne sono necessarie cinque tipologie:
Collegamento normale: rappresentato da una freccia piena, permette sia
la navigazione sia il passaggio di parametri.
Collegamento di trasporto: rappresentato da una freccia tratteggiata,
permette il solo passaggio di parametri.
Collegamento automatico: rappresentato dal simbolo [A], è un
collegamento normale che viene seguito automaticamente.
Collegamento OK: rappresentato da una freccia verde, è un collegamento
di uscita di un’unità di operazione e viene seguito quando l’operazione ha
avuto successo.
Collegamento KO: rappresentato da una freccia rossa, è un collegamento
di uscita di un’unità di operazione e viene eseguito quando l’operazione
ha avuto esito negativo.
Nel Capitolo 2.5 sarà illustrato il modello di applicazione web che sarà
utilizzato come esempio durante il resto del documento.
Lo sviluppo di applicazioni web con WebML è supportato da WebRatio, un
software applicativo commerciale che permette la stesura dei modelli dei dati e
di ipertesto e la generazione del codice sorgente dell’applicazione. WebRatio
supporta inoltre tutte le operazioni di sviluppo web: dichiarazione della fonte
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 19 ~
dei dati e dei Web services usati nel progetto, ingegnerizzazione diretta e inversa
del modelli dei dati, definizione della presentazione tramite modelli delle pagine
e generazione e installazione del codice per diverse piattaforme.
2.3. OCL
OCL (Object Constraint Language)13 è un linguaggio formale utilizzato per
descrivere espressioni sui modelli UML. Tali espressioni generalmente
definiscono condizioni invarianti che devono essere sempre verificate per il
sistema che si sta modellando oppure per le query sugli oggetti descritti dal
modello. È importante notare che, quando le espressioni OCL vengono valutate,
non comportano effetti collaterali, cioè la loro valutazione non può
modificare lo stato del sistema. Le espressioni OCL però possono essere
utilizzate per definire operazioni o azioni che, quando eseguite, alterano lo stato
del sistema.
2.3.1. NECESSITÀ DI OCL
Un diagramma UML, come il diagramma delle classi necessario per applicare il
metodo oggetto di questo documento, solitamente non è abbastanza raffinato
per fornire tutti gli aspetti importanti di una specifica. Tra le altre cose, nasce la
necessità di descrivere vincoli addizionali riguardo gli oggetti del modello. Di
solito vincoli di questo tipo sono descritti in linguaggio naturale, ma
l’esperienza ha mostrato che possono spesso nascere delle ambiguità. Proprio
per scrivere vincoli univoci, sono stati sviluppati dei linguaggi definiti formali.
La controindicazione dei linguaggi formali è quella di essere adatti solo a
persone con una forte preparazione matematica, risultando di difficile
utilizzazione da parte di progettisti con una differente preparazione.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 20 ~
OCL è stato sviluppato per sopperire al problema. È un linguaggio formale che
rimane di facile lettura. È stato sviluppato come un linguaggio di
modellazione commerciale all’interno della divisione assicurazioni di IBM ed ha
le proprie radici nel metodo Syntropy, un metodo di analisi e progettazione
orientate agli oggetti sviluppato nel Regno Unito negli anni ‘90. OCL è un puro
linguaggio di specifica e, di conseguenza, un’espressione OCL non può avere
effetti collaterali: quando un’espressione OCL viene valutata, viene restituito
solo un valore, senza che sia modificato alcun dato all’interno del
modello. Questo significa che lo stato del sistema non potrà mai subire
cambiamenti in seguito alla valutazione di un’espressione OCL, anche se le
espressioni OCL possono essere usate per definire un cambiamento di stato,
come ad esempio una post-condizione. OCL non permette di eseguire processi o
di attivare operazioni diverse da query. Poiché OCL è principalmente un
linguaggio di modellazione, per definizione le espressioni OCL non sono
eseguibili direttamente, ma possono solo essere valutate. I progettisti UML
possono usare OCL per definire vincoli specifici dell’applicazione nei loro
modelli, oppure possono specificare query sul modello UML completamente
indipendenti dal linguaggio di programmazione utilizzato.
OCL è un linguaggio tipizzato e ogni espressione OCL ha un tipo. Per essere
ben formata, un’espressione OCL deve essere conforme delle regole dei tipi del
linguaggio. Ad esempio, non si può confrontare un intero con una stringa. Ogni
classe definita all’interno del modello UML rappresenta un tipo in OCL. Inoltre,
OCL include un insieme di tipi predefiniti aggiuntivi. Essendo un linguaggio di
specifica, non è possibile esprimere alcun problema di implementazione. La
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 21 ~
valutazione di un’espressione OCL è istantanea, di conseguenza lo stato degli
oggetti del modello non può cambiare durante la valutazione.
OCL può essere utilizzato per diverse attività:
Come linguaggio di query.
Per specificare invarianti sulle classi e i tipi del diagramma delle classi.
Per specificare invarianti di tipi per gli stereotipi.
Per descrivere pre-condizioni e post-condizioni sulle operazioni e sui
metodi.
Per descrivere controlli sulla consistenza dei dati.
Per specificare la destinazione di messaggi e azioni.
Per definire vincoli sulle operazioni.
Per specificare regole di derivazione per gli attributi di qualsiasi
espressione su un modello UML.
2.3.2. SINTASSI DI OCL
La parola chiave context introduce il contesto dell’espressione. Le parole
chiave inv, pre e post definiscono gli stereotipi rispettivamente invariante,
pre-condizione e post-condizione, del vincolo. L’espressione OCL vera e propria
viene dopo i due punti. Ad esempio:
context NomeTipo inv:'questa è un’espressione OCL con
lo stereotipo «invariante» nel contesto del
NomeTipo'='altra stringa'
In questo paragrafo si farà riferimento al diagramma delle classi UML
rappresentato in Figura 5 per esemplificare le espressioni OCL. Il modello
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 22 ~
rappresenta una semplice anagrafe, seppure incompleta, e ha il solo scopo di
fungere da base per le espressioni OCL che verranno mostrate in seguito.
Ogni espressione OCL è scritta nel contesto di un’istanza di un tipo specifico. In
un’espressione OCL, la parola riservata self è usata per riferirsi all’istanza
contestuale. Ad esempio, se il contesto è la classe Compagnia, allora self si
riferisce a un’istanza di Compagnia.
Le espressioni OCL possono essere parte di un invariante: si tratta di un vincolo
stereotipato come un invariant. Quando l’invariante è associato ad una classe,
quest’ultima è definita tipo. Un espressione OCL è un’invariante per il tipo e
deve essere vera per tutte le istanze di quel tipo in ogni istante di tempo.
È importante notare che tutte le espressioni OCL che esprimono invarianti sono
di tipo booleano. Ad esempio, nel contesto del tipo Compagnia, l’espressione
seguente definisce un invariante per il quale il numero dei dipendenti deve
sempre essere maggiore di 50:
self.numeroDiDipendenti > 50
Dove self rappresenta un’istanza del tipo Compagnia. È possibile considerare
self come l’oggetto a partire dal quale viene eseguita la valutazione
dell’espressione. L’invariante resta valido per ogni istanza del tipo Compagnia.
Il tipo dell’istanza contestuale di un’espressione OCL che fa parte di
un’invariante è definito tramite la parola chiave context, seguita dal nome del
tipo, come mostrato nell’esempio seguente:
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 23 ~
context Compagnia inv:
self.numeroDiDipendenti > 50
FIGURA 5: DIAGRAMMA DELLE CLASSI UML DI UN'IPOTETICA ANAGRAFE.
L’etichetta inv: indica che si tratta di un vincolo di tipo invariante.
Nella maggioranza dei casi, la parola chiave self può essere tralasciata perché il
contesto è chiaro, come negli esempi precedenti. Alternativamente, è possibile
definire un altro nome per svolgere le funzioni di self, come nell’esempio che
segue:
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 24 ~
context c: Compagnia inv:
c.numeroDiDipendenti > 50
Questo invariante è equivalente al precedente.
Facoltativamente è possibile specificare un nome per il vincolo scrivendolo dopo
la parola chiave inv, rendendo così possibile riferirsi al vincolo tramite il nome.
Nell’esempio seguente il nome del vincolo è abbastanzaDipendenti:
context c: Compagnia inv abbastanzaDipendenti:
c.numeroDiDipendenti > 50
2.3.3. PRE-CONDIZIONI E POST-CONDIZIONI
Le espressioni OCL possono essere parte di una pre-condizione o post-
condizione, che corrispondono agli stereotipi precondition e postcondition di
Constraint associato a un Operation o ad altre azioni. In questo caso
l’istanza contestuale di self risulta essere un’istanza del tipo che possiede
l’operazione o il metodo. La dichiarazione del contesto in OCL utilizza la parola
chiave context, seguita dalla dichiarazione del tipo e dell’operazione. Lo
stereotipo dei vincoli è indicato dalle etichette pre: e post: poste prima delle
pre-condizioni o post-condizioni. Ad esempio:
context nomeTipo::nomeOperazione(param1: Tipo1, ...):
TipoRestituito
pre: param1 > ...
post: result = ...
La parola self può essere usata per fare riferimento all’oggetto sul quale si è
invocata l’operazione. La parola riservata result indica il risultato
dell’operazione, se presente. Anche i nomi dei parametri possono essere usati
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 25 ~
nell’espressione OCL. Facendo riferimento al diagramma UML di esempio,
possiamo scrivere:
context Persona::reddito(d : Date) : Integer
post: result = 5000
Facoltativamente, il nome della pre-condizione o della post-condizione può
essere scritta dopo le parole chiave pre o post, permettendo così di fare
riferimento al vincolo tramite il nome. Nell’esempio che segue il nome della pre-
condizione è parametriOK e il nome della post-condizione è risultatoOK:
context nomeTipo::Operazione(param1 : Tipo1, ... ): T
pre parametriOk: param1 > ...
post risultatoOk : result = ...
2.3.4. CONTESTO DEL PACKAGE
La dichiarazione del contesto vista finora è sufficientemente chiara quando il
package di appartenenza delle classi è univoco. Per specificare esplicitamente
il package di appartenenza, invariante, pre-condizione e post-condizione
devono essere racchiusi dalle parole chiave package e endpackage. Le
dichiarazioni package hanno la seguente sintassi:
package Package::SubPackage
context X inv: ... un invariante ...
context X::nomeOperazione(..)
pre: ... una pre-condizione ...
endpackage
Un file OCL può contenere un qualsiasi numero di dichiarazioni package,
permettendo così di scrivere tutti gli invarianti, le pre-condizioni e le post-
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 26 ~
condizioni in un solo file. Questo file coesiste con il modello UML come
un’entità separata.
È possibile consultare la specifica completa del linguaggio OCL sul sito
dell’OMG (Object Management Group) http://www.omg.org.
2.4. MODELLO DI ESEMPIO
Durante la trattazione del metodo verrà utilizzato un esempio pratico per meglio
illustrare i concetti esposti. L’esempio è composto da un modello statico, un
modello dinamico e un insieme di vincoli d’integrità e rappresenta
un’applicazione per la gestione di un’università. Il semplice modello statico
dell’applicazione d’esempio è rappresentato in Figura 6. Le classi presenti
sono:
Studente: caratterizzato dai dati anagrafici, una matricola e un numero di
crediti conseguiti.
Professore: caratterizzato dai dati anagrafici e un titolo di studio.
Esame: caratterizzato dai crediti che conferisce allo studente che lo
supera.
EsameSuperato: caratterizzato da una data e dai crediti conferiti allo
studente.
Oltre al modello statico, deve essere definito un modello dinamico, che in
WebML è detto modello di ipertesto. L’esempio utilizzato comprende diversi
diagrammi, espressi in WebML. Ne viene riportato una parte come esempio in
Figura 7. Ulteriori diagrammi WebML relativi all’esempio saranno introdotti
successivamente.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 27 ~
FIGURA 6: DIAGRAMMA DELLE CLASSI UML DI UN'UNIVERSITÀ.
Infine, è necessario fornire una descrizione in linguaggio OCL (Object
Constraints Language) dei vincoli d’integrità che si desidera implementare.
Esistono diversi strumenti per la scrittura di vincoli OCL relativi a un
diagramma delle classi UML che possono semplificare questa procedura, ma è
perfettamente possibile scrivere il codice OCL a mano tramite un semplice
editor di testo. Alcuni esempi di vincoli OCL sugli attributi delle classi
dell’esempio verranno introdotti successivamente nel testo.
Un semplice esempio di vincoli è il seguente:
package Universita
context Studente
inv MatricolaCorretta: self.Matricola>0
endpackage
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Background
~ 28 ~
Il codice OCL esprime il vincolo, chiamato MatricolaCorretta, per cui la
matricola di uno studente deve necessariamente essere rappresentata da un
numero maggiore di zero. Ulteriori esempi di vincoli d’integrità espressi in
linguaggio OCL verranno presentati successivamente.
FIGURA 7: ESEMPIO DI MODELLO DI IPERTESTO.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Analisi dei vincoli d’integrità
~ 29 ~
3. ANALISI DEI VINCOLI D’INTEGRITÀ
I metodi ottimizzati per il controllo dei vincoli d’integrità fanno sempre uso di
strutture dati aggiuntive nella base di informazioni, come ad esempio trigger o
view, per ogni vincolo da controllare. Risulta chiaro quindi che qualora si possa
determinare con certezza che un dato vincolo non possa essere violato
dall’applicazione, si può trascurarne il controllo e aumentare così
l’efficienza di esecuzione dell’applicazione. Per determinare se un vincolo
possa essere violato o no, si ricorre prima all’estrazione di tutti gli eventi
potenzialmente violanti dal modello statico dell’applicazione e successivamente
si analizzano gli eventi contenuti nel modello dinamico dell’applicazione,
eliminando gli eventi che eventualmente non possono accadere. Si potrebbe
pensare di utilizzare direttamente i soli eventi strutturali potenzialmente
violanti estratti dal modello dinamico dell’applicazione, dal momento che sono i
soli che possono verificarsi, ma OCL è stato progettato espressamente per
definire vincoli sul diagramma delle classi UML e pertanto non può essere
utilizzato per definire vincoli sul modello di ipertesto di WebML.
3.1. ESTRAZIONE DEGLI EVENTI STRUTTURALI POTENZIALMENTE
VIOLANTI DAI METAMODELLI
Gli eventi strutturali che possono verificarsi in una base di informazioni sono i
seguenti2:
InsertET(ET): Inserimento di un’istanza dell’entità ET
DeleteET(ET): Eliminazione di un’istanza dell’entità ET
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Analisi dei vincoli d’integrità
~ 30 ~
UpdateAttribute(Attr,ET): Modifica dell’attributo Attr in un’istanza
dell’entità ET
SpecializeET(ET): Specializzazione di un’istanza di un supertipo di ET in
ET
Generalize(ET): Generalizzazione di un’istanza di un sottotipo di ET in
ET
InsertRT(RT): Inserimento di una nuova relazione di tipo RT
DeleteRT(RT): Eliminazione di una relazione di tipo RT
Ad esempio, il codice OCL per MatricolaCorretta definisce un vincolo che può
essere violato da un evento di inserimento di una nuova istanza della classe
studente oppure della modifica dell’attributo Matricola. Un altro vincolo
d’integrità in OCL potrebbe essere quello riportato di seguito:
package Universita
context Studente
inv CreditiCorretti: self.CreditiConseguiti =
self.EsameSostenuto.Crediti->sum()
endpackage
CreditiCorretti esprime la necessaria consistenza tra il valore del numero che
indica i crediti conseguiti da uno studente e la somma dei crediti conferiti dagli
esami che lo stesso studente ha superato positivamente.
Questo vincolo può essere violato da diversi eventi strutturali:
Inserimento di una nuova istanza di Studente
Modifica dell’attributo CreditiConseguiti della classe Studente
Modifica dell’attributo Crediti della classe EsameSostenuto
Inserimento di una istanza nella relazione Studente-EsameSostenuto
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Analisi dei vincoli d’integrità
~ 31 ~
Eliminazione di una istanza della relazione Studente-EsameSostenuto
Questi eventi strutturali potenzialmente violanti sono ricavati dal modello
statico dell’applicazione valutando tutti i possibili modi in cui il vincolo può
essere infranto. Il passo successivo consisterà nella determinazione degli eventi
che non possono avvenire tramite l’analisi del modello dinamico. E’
addirittura possibile che nessun evento si verifichi e in tal caso l’intero
controllo d’integrità può essere evitato senza rischi. Questo succede perché
capita spesso che le applicazioni abbiano un ruolo limitato nella gestione
della base di informazioni. Un’applicazione potrebbe infatti essere solo
destinata alla visualizzazione dei dati, oppure alla registrazione di nuovi dati ma
non alla loro cancellazione. Nell’ambito del nostro esempio, potrebbe esistere
un’applicazione web per gli studenti che permetta loro di iscriversi agli esami,
mentre le immatricolazioni e le altre operazioni di segreteria potrebbero essere
gestite da un’applicazione a sé stante sviluppata in un linguaggio compilato.
3.2. SCARTO DEGLI EVENTI STRUTTURALI CHE NON POSSONO
ACCADERE
L’analisi del modello dinamico dell’applicazione fornisce utili informazioni
riguardo quali eventi strutturali potenzialmente violanti possono effettivamente
avvenire e quali no. Un modello WebML contiene uno schema delle classi simile
al diagramma delle classi UML e uno o più modelli di ipertesto, chiamati site
view, che rappresentano l’interfaccia web tramite la quale vengono manipolati i
dati.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Analisi dei vincoli d’integrità
~ 32 ~
Una parte del modello dinamico espresso in WebML del nostro esempio è
visibile in Figura 8 e Figura 9. Le operazioni modellate sono quelle
riguardanti l’immatricolazione, l’eliminazione o la modifica di uno
studente.
FIGURA 8: MODELLO DI IPERTESTO DELLE IMMATRICOLAZIONI.
La notazione WebML contiene diverse unità, ognuna delle quali dà origine a
differenti eventi strutturali. La Tabella 1 contiene una breve panoramica degli
eventi derivanti da ogni unità di WebML nonché una breve spiegazione delle
funzioni delle stesse.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Analisi dei vincoli d’integrità
~ 33 ~
FIGURA 9: MODELLO DI IPERTESTO DELLA REGISTRAZIONE ESAMI.
Simbolo Operazione Eventi causati
Creazione di una nuova istanza di
un’entità
InsertET
SpecializeET
Eliminazione di un’istanza
dell’entità
DeleteET
GeneralizeET
Modifica di uno o più attributi di
un’istanza dell’entità UpdateAttribute
Crea una nuova relazione tra due
entità InsertRT
Elimina una relazione tra due
entità DeleteRT
TABELLA 1: UNITÀ OPERATIVE DI WEBML E EVENTI CAUSATI
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Analisi dei vincoli d’integrità
~ 34 ~
Dal confronto degli eventi strutturali ricavati dall’analisi del modello statico con
quelli derivanti dalle unità presenti nel modello dinamico è possibile
determinare quali eventi possono effettivamente accadere durante
l’esecuzione dell’applicazione e quali certamente non avverranno. Qualora
si verifichi che un vincolo d’integrità possa venire violato soltanto da eventi
strutturali che non possono verificarsi, sarà possibile trascurare la verifica di
tale vincolo senza rischi. Nel nostro esempio, il vincolo d’integrità
MatricolaCorretta può essere infranto da un evento InsertET, un evento
DeleteET e da un evento UpdateAttribute sull’attributo Matricola. Dal modello
dinamico rappresentato in Figura 5 possiamo estrarre gli eventi strutturali che
potranno avvenire durante l’esecuzione della nostra applicazione. L’unità di
creazione implica degli eventi InsertET e SpecializeET, mentre l’unità di
eliminazione implica gli eventi DeleteET e GeneralizeET; infine l’unità di
modifica comporta gli eventi UpdateAttribute per ogni attributo di Studente. In
questo caso quindi tutti gli eventi strutturali potenzialmente violanti possono
avvenire durante l’esecuzione dell’applicazione, e il vincolo deve essere
controllato.
Un altro vincolo d’integrità potrebbe essere ad esempio quello riportato di
seguito:
package Universita
context EsameSostenuto
inv CreditiMax: self.Crediti<10
endpackage
Il vincolo CreditiMax esprime la limitazione superiore per il valore dei crediti
per ogni esame sostenuto. Gli eventi strutturali che lo possono violare sono
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Analisi dei vincoli d’integrità
~ 35 ~
InsertET e UpdateAttribute sull’attributo Crediti. Tuttavia nel modello
dinamico non c’è alcuna unità di creazione o di modifica per la classe
EsameSostenuto, pertanto nessun evento strutturale potenzialmente violante
potrà verificarsi durante l’esecuzione dell’applicazione. Il controllo di questo
vincolo può essere trascurato senza rischi, ottenendo quindi un risparmio in
termini di tempo di CPU impiegato per il controllo d’integrità e
conseguentemente un incremento prestazionale.
E’ semplice verificare con la procedura appena descritta che il vincolo
CreditiCorretti introdotto precedentemente deve essere controllato in quanto
l’evento strutturale InsertRT può verificarsi durante l’esecuzione
dell’applicazione.
Non è raro che tutti i vincoli d’integrità vengano scartati da questa fase
dell’ottimizzazione. In generale questa fase comporta un notevole vantaggio sia
in termini di prestazioni finali sia in termini di tempo di sviluppo, in quando
permette di evitare di scrivere il codice necessario a eseguire i controlli
d’integrità per i vincoli scartati.
Anche nel caso in cui il vincolo d’integrità debba essere controllato, questa
procedura può comportare un risparmio sul codice di verifica da scrivere,
secondo la tecnica di controllo utilizzata. Ad esempio, si può scegliere di
controllare un vincolo d’integrità ogniqualvolta si verifichi uno dei suoi eventi
strutturali potenzialmente violanti. Scartando gli eventi strutturali che non
possono verificarsi, si eviteranno controlli inutili, ottenendo ancora un
vantaggio prestazionale durante l’esecuzione dell’applicazione.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 36 ~
4. DETERMINAZIONE DELL’IMPLEMENTAZIONE OTTIMALE
La seconda fase dell’ottimizzazione della verifica d’integrità consiste
nell’individuare, tra quelle disponibili, la tecnica più indicata al controllo
d’integrità per ogni vincolo, determinando in tal modo un insieme di
tecniche. Questa fase può essere eseguita indipendentemente dalla riduzione
degli eventi potenzialmente vincolanti esaminata in precedenza ma, poiché i
vantaggi prestazionali delle due metodologie si sommano, è consigliabile
eseguire entrambe le procedure. Si noti inoltre che eseguire le due fasi in ordine
inverso è sconsigliabile poiché la seconda fase può essere snellita dalla riduzione
del numero dei vincoli da analizzare conseguente della prima fase.
Le tecniche implementative ricercate sono le tecniche che offrono le migliori
prestazioni durante l’esecuzione dell’applicazione, rispettandone i requisiti.
Prima di procedere è necessario classificare i vincoli d’integrità in base alle
loro caratteristiche di complessità.
4.1. CLASSIFICAZIONE DEI VINCOLI D’INTEGRITÀ
Distinguiamo tre livelli di complessità per i vincoli d’integrità17:
Vincoli intra-istanza: vincoli che limitano il valore degli attributi di una
singola istanza di un’entità. È il caso del vincolo MatricolaCorretta.
Vincoli inter-istanza: vincoli che limitano le relazioni tra due entità
differenti o tra istanze di entità differenti. È il caso del vincolo
CreditiCorretti. Vale la pena distinguere una sottocategoria contenente
i vincoli definiti tramite l’uso degli aggregatori come sum, count o size.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 37 ~
Vincoli a livello di classe: vincoli che limitano un insieme di istanze della
stessa entità. E’ il caso del vincolo MaxCorsiAnalisi riportato sotto.
Questi vincoli devono essere definiti tramite l’uso della funzione OCL
AllInstances.
Il vincolo MaxCorsoAnalisi riportato di seguito esprime il limite massimo di
quattro corsi con il titolo Analisi. Trattandosi di una limitazione sul numero
delle istanze di un’entità, viene classificato come vincolo di complessità a
livello di classe.
package Universita
context Corso inv
MaxCorsoAnalisi:
Corso::allInstances()->select(o|o.Titolo='Analisi')->
size() <=4
endpackage
La classificazione dei vincoli d’integrità avviene analizzando la loro definizione
OCL in base alle seguenti regole pratiche:
1. I vincoli definiti tramite l’uso della variabile self e che non fanno
riferimento ad alcuna relazione sono classificati come complessità intra-
istanza.
2. I vincoli definiti tramite l’uso della variabile self ma che non soddisfano
la prima regola sono classificati come complessità inter-istanza.
3. I restanti vincoli sono classificati come complessità a livello di
classe. Questi vincoli saranno sempre definiti tramite la funzione
AllInstances.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 38 ~
Terminata la classificazione dei vincoli, è necessario tenere conto delle
necessità espresse dal progettista per decidere effettivamente quale tecnica
implementativa sia la più indicata.
4.2. PARAMETRI DIPENDENTI DALL’AMBIENTE DI ESECUZIONE
Per ogni vincolo d’integrità è necessario specificare il valore dei seguenti
parametri dell’ottimizzazione delle prestazioni:
Tempo del controllo (Checking Time)
Efficienza di esecuzione (Runtime Efficiency)
Volume della popolazione della tabella (Population Volumen)
Uso del DBMS (DataBase Management System)
Questi parametri indicano le caratteristiche dell’ambiente in cui l’applicazione
in fase di processo sarà eseguita. In questo modo si rende generale il metodo
decisionale, che si può adattare a molti possibili scenari. I paragrafi seguenti
illustrano i parametri e i valori che possono assumere.
4.2.1. TEMPO DI CONTROLLO
Questo parametro indica il tempo in cui è necessario effettuare il controllo dei
vincoli d’integrità. Può assumere i seguenti valori:
Immediato (Immediate): il controllo viene eseguito non appena si
verifica un evento strutturale potenzialmente violante per il vincolo
studiato.
Rinviato (Deferred): il controllo viene eseguito alla fine della
transazione che include l’evento strutturale.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 39 ~
Posticipato (Postponed): il controllo viene eseguito in un momento
successivo alla fine della transazione che include l’evento strutturale
che potrebbe violare il vincolo. Questo implica che la base di
informazioni possa trovarsi per un certo periodo di tempo in uno stato
inconsistente.
4.2.2. EFFICIENZA DI ESECUZIONE
Questo parametro indica la priorità che il progettista assegna alla valutazione
del singolo vincolo rispetto all’esecuzione dell’intera applicazione.
Generalmente l’obiettivo finale è minimizzare il tempo totale della verifica
d’integrità, ma vi sono casi in cui è necessario ottenere una valutazione di un
vincolo nel minor tempo possibile. Alcune tecniche per il controllo
efficiente dei vincoli d’integrità infatti tendono a raccogliere informazioni sugli
eventi durante le transazioni, causando un piccolo ma significativo impatto
nelle prestazioni finali. Questo parametro permette di favorire le prestazioni
della valutazione dei vincoli oppure le prestazioni dell’esecuzione degli eventi
strutturali. I seguenti sono i valori possibili:
Efficienza Individuale (Individual): ogni singolo evento strutturale viene
valutato il più velocemente possibile, anche se il tempo totale
impiegato per la valutazione dei vincoli può aumentare.
Efficienza Globale (Overall): il tempo totale della transazione (somma
dei tempi di valutazione per ogni evento strutturale e del tempo
necessario per la valutazione del vincolo) deve essere il minore
possibile, anche se la valutazione di ogni singolo evento risulta più
lenta.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 40 ~
Efficienza Media (Average): si può accettare una riduzione nelle
prestazioni di esecuzione dei singoli eventi in cambio di una
significativa riduzione del tempo totale impiegato dal controllo
d’integrità.
4.2.3. VOLUME DELLA POPOLAZIONE
Questo parametro indica il numero previsto delle tuple nella tabella della base
di informazioni. A seconda del volume previsto è necessario utilizzare tecniche
implementativa differenti. I possibili valori sono:
Alto (High): con un’elevata popolazione nella tabella è importante
utilizzare tecniche ottimizzate per il controllo d’integrità.
Basso (Low): non ci sono vantaggi certi nell’utilizzo di tecniche
ottimizzate per la verifica d’integrità. In alcuni casi è possibile caricare in
memoria tutti i dati e ottenere quindi prestazioni migliori controllando
l’intera tabella invece di determinare prima quali tuple sia necessario
controllare.
4.2.4. USO DEL DBMS
Questo parametro specifica la disponibilità di utilizzare le caratteristiche del
Database Management System per il controllo d’integrità. I possibili valori
sono:
Sì (Yes): utilizza il DBMS per il controllo d’integrità
No (No): non utilizza il DBMS per il controllo d’integrità
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 41 ~
4.2.5. SCELTA DEI PARAMETRI
A volte può risultare difficile decidere la giusta combinazione dei valori dei
parametri durante la fase di progettazione concettuale dell’applicazione. È
possibile infatti che durante la fase di collaudo dell’applicazione nell’ambiente di
lavoro finale la situazione possa apparire differente dalle previsioni. Ad
esempio, può capitare che le prestazioni del DBMS siano differenti da quelle che
ci si attendeva durante la fase di progettazione, oppure che il numero di utenti
sia maggiore di quello previsto, oppure ancora che il volume dei dati sia
superiore o inferiore a quanto preventivato. In questi casi, è sufficiente ripetere
tutta la procedura di analisi e ottimizzazione dei vincoli d’integrità adattando la
combinazione dei parametri alla nuova situazione.
4.3. METODI DI IMPLEMENTAZIONE DELLA VERIFICA D’INTEGRITÀ
Durante la fase di scrittura del codice applicativo, è necessario convertire i
vincoli d’integrità definiti nello schema concettuale in una combinazione di
codice ed eventuali strutture dati per assicurare che la base di informazioni resti
consistente. Nonostante sia possibile utilizzare diverse tecnologie per
l’implementazione di una base di informazioni, d’ora in avanti verranno prese in
considerazione le sole basi di dati.
Le tecniche che verranno illustrate sono tecniche già esistenti che verranno
combinate per fornire una gestione dei vincoli d’integrità efficiente. Tutte le
tecniche illustrate sono in grado di fornire all’utente informazioni dettagliate
circa le istanze che violano i vincoli. Il risultato finale sarà composto di una
combinazione delle tecniche illustrate di seguito.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 42 ~
4.3.1. IMPLEMENTAZIONE DIRETTA
Lo standard SQL definisce il meccanismo di asserzione (assertion) per
l’implementazione diretta dei vincoli d’integrità nelle basi di dati, tuttavia
nessun DBMS supporta attualmente questo meccanismo. Le uniche specifiche
SQL che effettivamente permettono una definizione di un limitato insieme di
vincoli d’integrità comprendono chiavi primarie (primary key), chiavi
esterne (foreign key), chiavi uniche (unique key) e check sui valori degli
attributi. Questo supporto limitato non è sufficiente a implementare tutti i
possibili tipi di vincoli d’integrità definiti nello schema concettuale. Degli
esempi proposti, solo MatricolaCorretta può essere implementato
utilizzando esclusivamente gli strumenti forniti dal DBMS.
È pertanto necessario generare ulteriori strutture dati atte a verificare l’integrità
dei vincoli. La strategia più semplice consiste nell’implementare i vincoli
d’integrità sotto forma di predicati di inconsistenza. Per fare ciò bisogna
creare, per ogni vincolo d’integrità, una view che restituisca un risultato non
vuoto solo nel caso in cui il vincolo venga violato durante la transazione. In
particolare, le tuple contenute nella view sono le tuple responsabili della
violazione del vincolo. Prima di terminare la transazione è necessario consultare
tutte le view generate e procedere in base al risultato ottenuto. Nel caso in cui
tutte le view siano vuote, si può procedere alla terminazione della transazione
con la certezza che i vincoli non siano stati violati, mentre nel caso in cui almeno
una view contenga almeno una tupla, è necessario annullare l’intera
transazione (roll back) oppure eseguire un adeguato codice per il ripristino
della consistenza della base di dati.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 43 ~
Innanzitutto è necessario creare le tabelle nella base di dati tramite apposite
espressioni SQL Create. Il riquadro seguente contiene le clausole SQL per la
creazione delle tabelle dell’esempio utilizzato finora:
CREATE TABLE T_Esame(Crediti INT,OID INT PRIMARY KEY);
CREATE TABLE T_Corso(OID INT PRIMARY KEY,Titolo
VARCHAR(255));
CREATE TABLE T_Professore(FK_Corso
VARCHAR(255),TitoloDiStudio VARCHAR(255),OID INT
PRIMARY KEY,Nome VARCHAR(255),Cognome VARCHAR(255));
CREATE TABLE T_Studente(DataDiNascita
VARCHAR(255),DataIscrizione VARCHAR(255),Matricola
INT,Cognome VARCHAR(255),Nome
VARCHAR(255),CreditiConseguiti INT,OID INT PRIMARY
KEY);
CREATE TABLE T_EsameSostenuto(Esito INT,OID INT PRIMARY
KEY,Data VARCHAR(255),Crediti INT);
Il codice può essere agevolmente scritto manualmente ma esiste anche la
possibilità di generarlo automaticamente dallo schema UML tramite
strumenti automatici già esistenti. Il codice dell’esempio è stato generato da
ICTuningGui, l’applicazione sviluppata appositamente per implementare il
metodo di ottimizzazione dei vincoli d’integrità oggetto di questo documento.
ICTuningGUi sarà descritto in dettaglio nei capitoli successivi. Il suo motore di
generazione di codice SQL è basato sul Dresden OCL Toolkit sviluppato
dall’università di Dresda in Germania.
È necessario anche scrivere Il codice relativo alle associazioni tra le classi, che
nella base di dati sono rappresentate ugualmente da tabelle. Il riquadro
seguente contiene tale codice:
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 44 ~
CREATE TABLE ASS_Corso_Esame (
FK_Corso VARCHAR(255),FK_Esame VARCHAR(255));
CREATE TABLE ASS_Corso_Studente (
FK_Corso VARCHAR(255),FK_Studente VARCHAR(255));
CREATE TABLE ASS_Esame_Studente (
FK_Esame VARCHAR(255),FK_Studente VARCHAR(255));
CREATE TABLE ASS_Professore_Esame (
FK_Professore VARCHAR(255),FK_Esame VARCHAR(255));
CREATE TABLE ASS_Studente_EsameSostenuto (
FK_EsameSostenuto VARCHAR(255),FK_Studente
VARCHAR(255));
CREATE TABLE ASS_Esame_Esame Sostenuto (
FK_Esame sostenuto VARCHAR(255),FK_Esame VARCHAR(255));
Il riquadro successivo riporta invece le view relative alle entità della base di dati
sulle quali si appoggeranno le view dei vincoli d’integrità:
CREATE VIEW OV_EsameSostenuto AS
(SELECT T_EsameSostenuto.Crediti AS
Crediti, T_EsameSostenuto.Data AS Data,
T_EsameSostenuto.Esito AS
Esito, T_EsameSostenuto.OID AS OID FROM
T_EsameSostenuto);
CREATE VIEW OV_Esame AS
(SELECT T_Esame.Crediti AS Crediti, T_Esame.OID AS OID
FROM T_Esame);
CREATE VIEW OV_Studente
AS (SELECT T_Studente.Cognome AS Cognome,
T_Studente.CreditiConseguiti AS CreditiConseguiti,
T_Studente.DataDiNascita AS DataDiNascita,
T_Studente.DataIscrizione AS DataIscrizione,
T_Studente.Matricola AS Matricola, T_Studente.Nome AS
Nome,T_Studente.OID AS OID FROM T_Studente);
CREATE VIEW OV_Professore
AS ( SELECT T_Professore.Cognome AS Cognome,
T_Professore.Nome AS Nome,T_Professore.OID AS OID,
T_Professore.TitoloDiStudio AS TitoloDiStudio,FK_Corso
FROM T_Professore);
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 45 ~
CREATE VIEW OV_Corso
AS ( SELECT T_Corso.OID AS OID,T_Corso.Titolo AS Titolo
FROM T_Corso);
L’espressione select della view è costruita partendo dalla negazione della
definizione del vincolo d’integrità poiché le tuple ricercate sono quelle che non
soddisfano la condizione imposta dal vincolo. E’ possibile ottenere tal
espressione utilizzando i metodi attualmente esistenti di conversione da OCL a
SQL4,6. Il riquadro che segue contiene la view relativa al vincolo
CreditiCorretti, generata da ICTuningGui:
CREATE OR REPLACE VIEW CreditiCorretti AS
(SELECT * FROM OV_Studente AS SELF WHERE NOT
((SELF.CreditiConseguiti = (SELECT
CASE
WHEN SUM(Crediti) IS NULL THEN 0
ELSE SUM(Crediti)
END
FROM OV_EsameSostenuto
WHERE Crediti IN (SELECT Crediti FROM
OV_EsameSostenuto WHERE OID IN
(SELECT OID FROM OV_EsameSostenuto WHERE OID IN
(SELECT FK_EsameSostenuto FROM
ASS_Studente_EsameSostenuto WHERE FK_Studente IN
(SELECT OID FROM OV_Studente WHERE OID =
SELF.OID))))))));
La view per CreditiCorretti seleziona tutte le tuple della tabella Studente per
cui il valore dell’attributo CreditiConseguiti non è uguale alla somma
dell’attributo Crediti delle istanze di EsameSostenuto presenti nella tabella
Studente_EsameSostenuto e associate alla stessa istanza di studente.
È facile notare che questo metodo è molto dispendioso perché per verificare
un vincolo, è necessario controllare tutte le tuple e non solo quelle che
rischiano di violare effettivamente il vincolo. Ad esempio, una transazione
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 46 ~
potrebbe comportare la modifica dell’attributo Crediti per una sola istanza della
classe Studente ma questo metodo di controllo andrebbe a verificare tutte le
tuple presenti nella tabella e non solo l’istanza interessata dalla modifica. Inoltre
non viene tenuta traccia degli eventi strutturali che avvengono sulla base di
dati, rendendo impossibile alla fine della transazione decidere quali vincoli
controllare e rendendo pertanto obbligatorio controllarli tutti. Tuttavia, nel
caso in cui il numero di tuple previste e il numero degli eventi strutturali
potenzialmente violanti per il vincolo studiato siano sufficientemente
piccoli, questa strategia implementativa può risultare più efficiente di
metodi più elaborati.
4.3.2. TRIGGER
Un trigger è un codice procedurale che viene eseguito automaticamente in
seguito all’avvenimento di un determinato evento strutturale su una tabella
della base di dati. I trigger sono l’implementazione nelle basi di dati delle regole
ECA (Evento – Condizione - Azione)5, già proposte in passato per la verifica dei
vincoli d’integrità. La tecnica proposta consiste nel definire un trigger per ogni
evento strutturale potenzialmente violante determinato per il vincolo d’integrità
studiato. Il corpo del trigger è finalizzato a verificare che nessuna tupla violi il
vincolo d’integrità. Durante la transazione, la base di dati esegue il trigger
appropriato subito dopo l’avvenimento di un evento strutturale. Poiché i trigger
sono definiti in modo da non poter modificare la base di dati, non sorgono
problemi di terminazione o consistenza.
Il codice per la definizione di un trigger per il vincolo CreditiCorretti è il
seguente:
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 47 ~
CREATE TRIGGER tCreditiCorretti
AFTER INSERT OR UPDATE ON T_Studente FOR EACH ROW
DECLARE v_Sum NUMBER; Error_CreditiCorretti Exception;
BEGIN
SELECT COUNT(*) INTO v_Sum FROM CreditiCorretti;
IF (v_Sum>0) THEN RAISE Error_CreditiCorretti;
END IF;
END;
Poiché il vincolo interessa tre tabelle distinte, sarà necessario creare un trigger
per ogni tabella coinvolta dal vincolo. Giacché la sintassi per la creazione di un
trigger varia notevolmente secondo la base di dati utilizzata, la generazione
automatica di tale codice può risultare complessa. Il trigger dell’esempio conta
le tuple contenute nella view relativa al vincolo CreditiCorretti e nel caso in
cui queste risultino in numero maggiore di zero solleva un’eccezione. Il
software dovrà quindi intercettare l’eccezione e risolvere la violazione del
vincolo.
4.3.3. VIEW EFFICIENTI
Questo metodo ha come obiettivo quello di creare un insieme di strutture dati
per ogni vincolo d’integrità. In particolare, per ogni evento strutturale
potenzialmente violante, sarà creata una view che includa solamente le tuple
modificate durante la transazione10. In questo modo saranno controllate solo le
tuple che potenzialmente possono essere state modificate in modo da violare i
vincoli d’integrità. Di conseguenza le view sono chiamate view efficienti
(efficient view) per distinguerle dalle view non efficienti viste in precedenza.
L’implementazione di questo metodo nelle basi di dati attuali comporta la
creazione di tabelle ausiliarie che riflettano i cambiamenti effettuati sui dati
dagli eventi strutturali di una transazione. Queste tabelle sono note con il nome
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 48 ~
di tabelle degli eventi. L’inserimento e la rimozione delle tuple in tali tabelle
devono avvenire in maniera automatica e trasparente all’utente. Nelle basi
di dati relazionali l’aggiornamento automatico delle tabelle degli eventi può
essere implementata tramite l’utilizzo di trigger che controllano i cambiamenti
che avvengono nella base di dati. Poiché tali trigger modificano solo le tabelle
degli eventi, sulle quali non sono definiti ulteriori trigger, non sorgono
problemi di convergenza o terminazione. Inoltre le tabelle degli eventi
devono essere vuote all’inizio di ogni transazione, situazione facilmente
ottenibile tramite l’implementazione delle tabelle degli eventi come tabelle
temporanee (definite nello standard SQL:1999)12.
Per il vincolo CreditiCorretti una view efficiente potrebbe essere la seguente,
composta da una tabella temporanea (tabella degli eventi), un trigger per ogni
tabella coinvolta nel vincolo e una view:
CREATE GLOBAL TEMPORARY TABLE
tuT_Studente(DataDiNascita VARCHAR(255),
DataIscrizione VARCHAR(255),Matricola INT,
Cognome VARCHAR(255), Nome VARCHAR(255),
CreditiConseguiti INT,OID INT PRIMARY KEY)
ON COMMIT DELETE ROWS;
CREATE TRIGGER tCreditiCorretti
AFTER INSERT OR UPDATE ON T_Studente
FOR EACH ROW
BEGIN
INSERT INTO tuT_Studente VALUES (:NEW.*);
END;
CREATE TRIGGER
tCreditiCorretti_ASS_Studente_EsameSostenuto
AFTER INSERT ON ASS_Studente_EsameSostenuto
FOR EACH ROW
BEGIN
INSERT INTO tuT_Studente
SELECT * FROM T_Studente WHERE OID = :NEW.FK_Studente);
END;
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 49 ~
CREATE OR REPLACE VIEW CreditiCorretti AS
(SELECT * FROM tuT_Studente SELF
WHERE NOT ((SELF.CreditiConseguiti =
(SELECT NVL(SUM(Crediti),0)
FROM OV_EsameSostenuto
WHERE Crediti IN (SELECT Crediti FROM
OV_EsameSostenuto WHERE OID IN
(SELECT OID FROM OV_EsameSostenuto WHERE OID IN
(SELECT FK_EsameSostenuto FROM
ASS_Studente_EsameSostenuto WHERE FK_Studente IN
(SELECT OID FROM tuT_Studente WHERE OID =
SELF.OID))))))));
Il primo trigger inserisce nella tabella degli eventi i valori rilevanti della riga di
T_Studente in cui il valore dell’attributo CreditiConseguiti è stato modificato. Il
secondo trigger inserisce invece la riga di T_Studente relativa alla nuova
relazione inserita nella tabella ASS_Studente_Esamesostenuto. La view esegue
la ricerca solo sulle tuple inserite nella tabella degli eventi, evitando di
controllare in tal modo l’intera popolazione della tabella.
4.3.4. APPROCCIO SEMI-EFFICIENTE
L’approccio semi-efficiente si pone a metà tra le view non efficienti e le view
efficienti. La tecnica consiste nel registrare le informazioni relative al verificarsi
degli eventi che riguardano i vincoli d’integrità, consentendo così di verificare
solo i vincoli per i quali si sono verificati degli eventi possibilmente violanti. In
questo modo è possibile trascurare il controllo dei vincoli per i quali non
avvengano eventi strutturali potenzialmente violanti, ma qualora si verifichino,
si procederà al controllo dell’intera popolazione della tabella.
L’implementazione di tale tecnica consiste nella creazione di un trigger FOR
EACH STATEMENT (per ogni espressione), che differentemente dai trigger
FOR EACH ROW (per ogni riga) visti finora sono eseguiti una volta sola per
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 50 ~
ogni transazione indipendentemente dal numero di tuple modificate. Tale
trigger memorizza in una tabella degli eventi solamente l’accadimento di un
evento strutturale ma non le informazioni relative alle tuple modificate,
rendendo possibile ridurre la tabella degli eventi a una semplice tabella con un
singolo attributo. La presenza di una o più tuple nella tabella degli eventi
segnala che si sono verificati degli eventi strutturali potenzialmente violanti e
pertanto è necessario procedere alla verifica d’integrità tramite le view descritte
nell’implementazione diretta.
Di seguito è riportato il codice di una view semi-efficiente per il vincolo
MaxCorsoAnalisi:
CREATE GLOBAL TEMPORARY TABLE
seMaxCorsoAnalisi (Event char(1)) ON COMMIT DELETE
ROWS;
CREATE TRIGGER tMaxCorsoAnalisi
AFTER INSERT OR UPDATE ON T_Corso FOR EACH STATEMENT
BEGIN
INSERT INTO seMaxCorsoAnalisi VALUES ('1');
END;
CREATE OR REPLACE VIEW MaxCorsoAnalisi AS
(SELECT * FROM OV_Corso ALIAS4
WHERE NOT (((SELECT NVL(COUNT(*),0)
FROM OV_Corso
WHERE OID IN (SELECT OID FROM OV_Corso)
MINUS
SELECT OID FROM OV_Corso ALIAS5
WHERE NOT ((ALIAS5.Titolo = 'Analisi')))) <= 4)));
Nel caso in cui alla fine della transazione si verifichi che nella tabella
temporanea seMaxCorsoAnalisi si trovino una o più tuple, si procederà alla
verifica del vincolo tramite la view utilizzata nell’implementazione diretta. In
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 51 ~
questo modo è possibile evitare di controllare le view relative ai vincoli per i
quali non si sono verificati eventi potenzialmente violanti.
4.3.5. CHECK
I DBMS forniscono un sistema molto semplice di gestione dei vincoli d’integrità:
la clausola Check. Tale clausola, utilizzata durante definizione di una tabella,
specifica un’espressione che produce un risultato booleano che le tuple inserite
o modificate devono rispettare affinché l’inserimento o la modifica abbiano
successo. Le espressioni che vengono valutate come vere o indefinite hanno
successo, mentre quelle che danno falso come risultato falliscono e causano il
lancio di un’eccezione. I Check non sono potenti e flessibili come gli altri
metodi implementativi illustrati in precedenza e infatti non supportano
espressioni complesse o sotto-query. Possono solamente verificare che il valore
di un attributo sia entro certi limiti, oppure confrontarne il valore con
quello di un altro attributo della stessa tabella. Per questo motivo i Check sono
utilizzabili solamente per i vincoli di tipo intra-istanza. Per il vincolo
MatricolaCorretta il Check è il seguente:
ALTER TABLE T_Studente
ADD CONSTRAINT checkMatricolaCorretta
CHECK (Matricola > 0);
4.3.6. CHECK (DIFFERITO)
I Check hanno la possibilità di essere definiti come differiti (deferred). Un
Check differito viene controllato solo alla fine della transazione, contrariamente
a quanto accade normalmente. In questo modo è possibile accettare
momentanei stati inconsistenti nella base di dati, che devono essere risolti
prima della fine della transazione. Al momento però non tutti i DBMS
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 52 ~
supportano questa clausola. Un esempio di Check differito per il vincolo
MatricolaCorretta è il seguente:
ALTER TABLE T_Studente
ADD CONSTRAINT checkMatricolaCorretta
CHECK (Matricola > 0) DEFERRABLE;
4.4. REGOLE PER LA DETERMINAZIONE DEL METODO DI
IMPLEMENTAZIONE OTTIMALE
In base ai parametri di ottimizzazione dell’applicazione visti nel Capitolo 4.2 e
la complessità di ogni vincolo d’integrità definita nel Capitolo 4.1 è possibile
determinare automaticamente l’insieme di tecniche più adatte per
l’implementazione del controllo d’integrità. Il diagramma di flusso riportato in
Figura 10 illustra il processo decisionale adottato.
Per prima cosa è necessario notare che nel caso in cui sia prevista una bassa
popolazione nella base di dati, i vantaggi derivanti dall’adozione di una tecnica
ottimizzata vengono annullati dal maggior tempo di cpu necessario alla loro
elaborazione e pertanto la strategia migliore risulta essere l’implementazione
diretta del controllo di integrità.
Il parametro che influenza maggiormente la scelta della tecnica migliore è il
tempo di controllo, che viene preso come base per la decisione nel caso in cui
sia previsto un alto volume di popolazione. Successivamente vengono
considerati i parametri relativi all’efficienza di esecuzione, alla complessità e
all’uso del DBMS quando possibile.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 53 ~
FIGURA 10: SCHEMA DELL'APPROCCIO PROPOSTO.
Nei paragrafi seguenti verranno analizzate tutte le possibili combinazioni dei
valori dei parametri forniti dal progettista e per ognuna di esse saranno discusse
le possibili implementazioni, evidenziandone vantaggi, svantaggi e casi d’uso.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 54 ~
4.4.1. TEMPO DI CONTROLLO: IMMEDIATO
Per il controllo immediato, la scelta più indicata è sempre il trigger, poiché
registrare informazioni sugli eventi in una tabella temporanea e procedere
immediatamente al controllo del vincolo tramite le view comporterebbe un
aumento del tempo di cpu richiesto.
Il parametro relativo al tempo di esecuzione è ininfluente giacché il controllo va
effettuato forzatamente subito dopo l’accadimento di un evento. Qualora si
desideri utilizzare le funzionalità di un DBMS per il controllo d’integrità, è
opportuno implementare il controllo dei vincoli con complessità intra-istanza
con dei check, poiché è probabile che il DBMS risulti più efficiente
nell’elaborazione.
Nel caso di vincoli con complessità a livello di classe, a causa della loro elevata
complessità, un controllo immediato porterebbe a un consistente degrado
dell’efficienza durante l’esecuzione e alla conseguente vanificazione
dell’ottimizzazione. Qualora possibile è consigliabile rimandare la verifica di tali
vincoli alla fine della transazione.
4.4.2. TEMPO DI CONTROLLO: RINVIATO
La scelta della tecnica dipende dal parametro relativo all’efficienza durante
l’esecuzione:
Efficienza individuale: non è permesso alcun rallentamento
nell’elaborazione dell’integrità del vincolo, pertanto l’unica soluzione
possibile è la verifica diretta del vincolo tramite view inefficienti. Qualora
si utilizzino le caratteristiche del DBMS, è opportuno rimandare i
controlli per evitare che siano eseguiti prima della fine della
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 55 ~
transazione. È consigliabile utilizzare questo valore del parametro solo
nei casi in cui la popolazione delle tabelle non è elevata, altrimenti il
tempo totale necessario per la transazione potrebbe diventare
inaccettabile.
Efficienza globale: la tecnica ottimale è la view efficiente per i vincoli di
complessità inter-istanza o intra-istanza. Per questi tipi di vincoli,
infatti, conoscere quali istanze sono interessate da modifiche durante una
transazione riduce notevolmente il tempo necessario alla verifica. Per i
vincoli di complessità intra-istanza, nel caso in cui sia disponibile il
DBMS, è consigliabile utilizzare la tecnica dei check differiti. Per i vincoli
di complessità a livello di classe invece è sempre necessario controllare
tutte le tuple della tabella, rendendo quindi inutile memorizzare quali
tuple sono state modificate. Risulta importante però memorizzare quali
vincoli vadano effettivamente controllati e quali no, per cui la tecnica
consigliata in questo caso è l’approccio semi-efficiente.
Efficienza media: la tecnica consigliata è l’approccio semi-efficiente per
tutti i vincoli d’integrità. In questo modo si ottiene il giusto
bilanciamento tra rapidità di esecuzione per ogni evento e ottimizzazione
del controllo d’integrità. I vincoli intra-istanza possono essere verificati
con un controllo differito. Per popolazioni della base di dati molto elevata
è possibile considerare anche le view efficienti come tecnica possibile.
4.4.3. TEMPO DI CONTROLLO: POSTICIPATO
La principale caratteristica di questa situazione è data dal fatto che l’integrità
dei vincoli non viene verificata durante la transazione ma in un momento
successivo alla fine della transazione stessa. Sfortunatamente i DBMS attuali
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 56 ~
non supportano questa funzione, pertanto non si può fare affidamento sul loro
supporto. L’unica possibilità in questo senso potrebbe essere data dalla
disabilitazione del controllo d’integrità durante la transazione e dalla loro
riabilitazione solo nel momento del controllo d’integrità, ma per procedere in tal
senso sarebbe necessario collegarsi al DBMS con i permessi di amministrazione.
Inoltre tutte le tuple verrebbero verificate, ottenendo un procedimento non
ottimizzato.
Nel proporre una tecnica implementativa per questa configurazione di
parametri è necessario tenere presente che il numero degli eventi strutturali non
controllati (appartenenti a tutte le transazioni terminate nel periodo trascorso
dal controllo d’integrità precedente) può essere molto elevato.
Le tecniche proposte variano secondo il parametro relativo all’efficienza di
esecuzione:
Efficienza individuale: l’unica tecnica possibile è quella delle view
inefficienti. Dato il probabile elevato numero di tuple da verificare la
differenza con una tecnica più ottimizzata come le view semi-efficienti o
le view efficienti non è sempre apprezzabile.
Efficienza globale: la tecnica più idonea è quella delle view efficienti,
giacché per grandi popolazioni di tuple la differenza tra la tecnica non
ottimizzata e quella ottimizzata è rilevante, specialmente per i vincoli di
complessità inter-istanza che includano operatori di aggregazione. Si
potrebbe utilizzare anche l’approccio semi-efficiente ma, poiché il
controllo avviene al di fuori della transazione, le tabelle temporanee non
possono essere utilizzate e la gestione dei dati temporanei ricade
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Determinazione dell’implementazione ottimale
~ 57 ~
sull’applicazione. L’approccio semi-efficiente è applicabile anche ai
vincoli di complessità a livello di classe, ma poiché il numero degli eventi
strutturali non verificati tende a essere elevato la maggior parte dei
vincoli deve essere verificato.
Efficienza media: nel contesto della verifica d’integrità posticipata,
quest’opzione è praticamente inutile ed è consigliato sceglierne una delle
due precedenti. Considerando che una transazione è composta di diversi
eventi strutturali, risulta probabile che ogni vincolo d’integrità annoveri
tra i propri eventi strutturali potenzialmente violanti uno o più eventi
della transazione e sia pertanto da controllare. Di conseguenza è difficile
giustificare il lavoro necessario alla registrazione degli eventi strutturali
ai fini di determinare quali vincoli debbano essere controllati. La
situazione varia secondo il numero di transazioni non ancora verificate,
dal numero e dalla eterogeneità degli eventi strutturali di ogni
transazione e dall’insieme dei vincoli da verificare. Nel caso in cui siano
presenti dei vincoli d’integrità la cui verifica risulta particolarmente
complessa, si può utilizzare ugualmente una tecnica ottimizzata.
Si può facilmente notare che non sono state considerate tutte le possibili
combinazioni di valori dei parametri. Il motivo risiede nella non idoneità di
alcune di queste combinazioni. ICTuningGui è stato progettato per segnalare al
progettista una scelta di parametri non idonea.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 58 ~
5. ICTUNINGGUI
Nell’ambito dello studio delle tecniche di ottimizzazione illustrate in questo
documento è stata realizzata un’applicazione chiamata ICTuningGui.
L’obiettivo finale di tale strumento è fornire al progettista un supporto per la
determinazione automatica delle tecniche implementative più idonee per
l’implementazione della verifica d’integrità di un’applicazione web. Attualmente
il software è in grado di generare anche il codice SQL relativo alle tecniche
selezionate.
5.1. FUNZIONALITÀ
ICTuningGui è strutturato a passi. Ad ogni passo vengono fornite informazioni
aggiuntive riguardo i vincoli d’integrità del modello caricato.
5.1.1. VINCOLI D’INTEGRITÀ ED EVENTI STRUTTURALI
Il primo passo dopo il caricamento dei file del modello è l’estrazione dei vincoli
d’integrità e dei relativi eventi strutturali potenzialmente violanti. Tali eventi
vengono estratti esaminando solamente il modello UML e successivamente
vengono presentati all’utente in una tabella.
5.1.2. TECNICHE IMPLEMENTATIVE
Successivamente l’utente configura i parametri illustrati nel Capitolo 4.2. e
ICTuningGui propone una tecnica implementativa per ogni vincolo d’integrità.
In questa fase viene esaminato il modello dinamico e viene eseguita la riduzione
degli eventi strutturali potenzialmente violanti, eliminando gli eventi che non si
possono verificare come visto nel Capitolo 3.2. Il risultato presentato
all’utente comprende gli eventi strutturali rimanenti e la tecnica più indicata per
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 59 ~
ogni vincolo. A questo punto è possibile configurare nuovamente i parametri per
eseguire un nuovo calcolo, salvare i risultati in un file di testo, oppure procedere
alla generazione del codice SQL.
5.1.3. GENERAZIONE DEL CODICE SQL
Anche in questo caso viene presentata all’utente una schermata di
configurazione. I parametri da configurare sono relativi al motore di
generazione SQL e comprendono opzioni quali il DBMS di destinazione e i
prefissi da anteporre ai nomi degli oggetti creati. Il risultato viene presentato in
due blocchi separati, uno contenente gli oggetti della base di dati come tabelle e
view mentre l’altro contiene il codice che implementa le tecniche suggerite. A
questo punto è possibile configurare nuovamente i parametri e procedere a una
nuova generazione del codice oppure salvare i risultati in un file di testo.
5.2. ALGORITMI UTILIZZATI IN ICTUNINGGUI
Gli algoritmi che costituiscono le fondamenta di ICTuningGui si occupano di
estrarre gli eventi strutturali dal modello di ipertesto, di scegliere la tecnica
migliore per un vincolo e di generare il codice sql per implementare le tecniche.
Le altre operazioni, quali l’estrazione degli eventi strutturali dal modello statico
e la generazione del codice SQL per la generazione delle tabelle del sistema,
vengono eseguite tramite l’uso di librerie esterne. Tali librerie saranno illustrate
nel Capitolo 5.3.
5.2.1. ESTRAZIONE DEGLI EVENTI STRUTTURALI
Gli eventi strutturali vengono estratti dal modello WebML tramite la semplice
scansione del file XML per mezzo di un parser di tipo SAX. Le informazioni
relative alle classi, ai loro attributi e alle relazioni tra classi sono raccolte in
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 60 ~
un’apposita struttura dati. Queste informazioni sono contenute nella sezione
Entity del modello WebML. Successivamente si procede all’analisi della sezione
Siteview, che contiene le informazioni relative alla navigazione delle pagine. In
particolare, si analizzano le sezioni Area, che costituiscono dei raggruppamenti
logici di pagine, e si esaminano i nodi contenuti nella sezione OperationUnits di
tali sezioni. Le OperationUnits vengono convertite in eventi e inserite in
un’apposita struttura dati secondo i seguenti criteri:
CreateUnit: dà origine ad un evento InsertET sulla classe indicata
dall’attributo entity.
DeleteUnit: implica evento DeleteET per la classe indicata dall’attributo
entity.
ConnectUnit: dà origine ad un evento InsertRT sulla relazione indicata
dall’attributo relashionship.
DisconnectUnit: implica un evento DeleteRT sulla relazione indicata
dall’attributo relashionship.
ModifyUnit: genera un evento UpdateAttribute per ogni attributo della
classe indicata dall’attributo entity.
La struttura dati così ottenuta contiene tutti gli eventi strutturali che possono
avvenire secondo il modello dinamico dell’applicazione web contenuto nel file
WebML.
5.2.2. CLASSIFICAZIONE DEI VINCOLI D’INTEGRITÀ
L’algoritmo di determinazione delle tecniche migliori fa riferimento, oltre ai
parametri dipendenti dall’ambiente di esecuzione inseriti dal progettista, anche
alla classificazione del tipo di vincolo che si sta analizzando. Come visto in
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 61 ~
precedenza nel Capitolo 4.1, i vincoli d’integrità possono essere classificati in
vincoli intra-istanza, inter-istanza o con complessità a livello di classe. La
classificazione di un vincolo avviene in maniera automatica tramite l’analisi
della sua rappresentazione in forma di albero binario, che come vedremo in
seguito, è creato da PSERelevant. Innanzitutto si attribuiscono due valori
booleani al vincolo in oggetto:
èNavigazionale: questo attributo è vero se e solo se l’albero binario
associato al vincolo in esame contiene un nodo di tipo
AssociationCallExp del’albero sintattico astratto di OCL21.
èSeStesso: questo attributo è vero se e solo se l’albero binario associato al
vincolo in esame contiene un nodo di tipo variabile di nome self.
TABELLA 2: SCHEMA PER LA CLASSIFICAZIONE DEI VINCOLI D’INTEGRITÀ
In termini implementativi si tratta semplicemente di determinare i valori degli
attributi per le classi di cui i nodi dell’albero sono istanze.
La classificazione del tipo di vincolo si ottiene secondo lo schema indicato in
Tabella 2.
èNavigazionale èSeStesso Complessità
No Sì Intra-istanza
Sì Sì Inter-istanza
- No Complessità a livello di classe
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 62 ~
5.2.3. DETERMINAZIONE DELLE TECNICHE MIGLIORI
L’algoritmo di selezione delle tecniche si basa su un file di configurazione
esterno codificato in XML e strutturato ad albero. Il file contiene la logica per la
scelta delle tecniche implementative in base ai valori dei parametri, come
illustrato in Figura 10. Il software legge il file e costruisce un albero
decisionale che sarà utilizzato dall’algoritmo di scelta delle tecniche in modo
ricorsivo.
5.2.4. GENERAZIONE DEI TRIGGER
Poiché il motore di generazione SQL (Dresden OCL Toolkit) adottato non è
ancora in grado di generare trigger, è stato sviluppato un generatore di trigger
provvisorio. Il processo di generazione si basa sulle view generate dal Dresden
OCL Toolkit e procede tramite un template nel quale si sostituiscono i nomi
relativi agli oggetti su cui opera il vincolo in esame. Gli oggetti vengono
determinati esaminando le view e gli oggetti del database tramite apposite
funzioni. Il template per i trigger per PostgresSQL è riportato di seguito:
CREATE OR REPLACE FUNCTION f%constraint%()
RETURNS trigger
AS $$
DECLARE
num integer;
BEGIN
SELECT COUNT(*) INTO num FROM %constraint%;
IF num >0 THEN RAISE EXCEPTION 'Error: %constraint%
violated';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 63 ~
Sostituendo alla variabile %constraint% il nome del vincolo in esame, si ottiene
una funzione che conta le tuple contenute nella view omonima. Per i trigger in
PostgresSQL è necessario specificare una funzione da eseguire separata dal
corpo del trigger, cosa che invece non è necessaria in Oracle. Per generare il
corpo del trigger vero e proprio si è utilizzato il template riportato di seguito:
CREATE TRIGGER t%constraint%_%table%
%firecondition%ON %table% FOR EACH ROW
EXECUTE PROCEDURE f%constraint%();
In questo template è necessario sostituire anche alla variabile %table% il nome
della tabella su cui si deve definire il trigger e alla variabile %firecondition% la
clausola che specifica quando il trigger deve essere eseguito. Nel caso in cui il
vincolo riguardi più tabelle, sarà necessario creare un trigger per ognuna di
esse.
Per Oracle invece è sufficiente un template solo, in quanto i trigger possono
essere definiti con del codice applicativo nel corpo, come riportato nel riquadro
seguente:
CREATE TRIGGER t%constraint%_%table%
%firecondition%ON %table% FOR EACH ROW
DECLARE v_Sum NUMBER; Error_%constraint% Exception;
BEGIN
SELECT COUNT(*) INTO v_Sum FROM %constraint%;
IF (v_Sum>0) THEN RAISE Error_%constraint%;
END IF;
END;
Anche in questo caso è necessario generare un trigger per ogni tabella coinvolta
nel vincolo d’integrità.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 64 ~
In entrambi i casi le clausole AFTER, che vanno a sostituire la variabile
%firecondition% sono determinate dal tipo di eventi strutturali potenzialmente
violanti rimasti dopo la riduzione per il vincolo d’integrità esaminato. In questo
modo si possono evitare inutili esecuzioni del trigger quando l’evento
strutturale che lo fa eseguire non può violare il vincolo.
5.2.5. GENERAZIONE DELLE VIEW SEMI-EFFICIENTI
Anche per la generazione delle view semi-efficienti è necessario generare un
trigger, come visto nel Capitolo 4.3.4. È inoltre necessario generare una
tabella temporanea nella quale il trigger andrà ad inserire i dati per decidere se
un vincolo debba essere controllato o no. Il template, nel caso in cui il codice
SQL sia generato per la piattaforma PostgresSQL, è riportato nel riquadro che
segue:
CREATE TEMPORARY TABLE se%constraint% (Event char(1))
ON COMMIT DELETE ROWS;
CREATE OR REPLACE FUNCTION f%constraint%()
RETURNS trigger
AS $$
BEGIN
INSERT INTO se%constraint% VALUES ('1');
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER t%constraint%
%firecondition%ON %table% FOR EACH STATEMENT
EXECUTE PROCEDURE f%constraint%();
Anche in questo caso è necessario sostituire i valori corretti alle variabili
%constraint%, %firecondition% e %table% ed è necessario generare un trigger
per ogni tabella coinvolta nel vincolo d’integrità in esame. Si noti come questi
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 65 ~
trigger siano eseguiti una volta sola per transazione grazie alla clausola for each
statement.
Il template per Oracle varia leggermente per conformarsi alla diversa sintassi
utilizzata per la definizione delle tabelle temporanee e alla definizione del codice
operativo direttamente nel corpo del trigger. Il codice del template è il
seguente:
CREATE GLOBAL TEMPORARY TABLE se%constraint% (Event
char(1))
ON COMMIT DELETE ROWS;
CREATE TRIGGER t%constraint%
%firecondition%ON %table% FOR EACH STATEMENT
BEGIN
INSERT INTO se%constraint% VALUES ('1');
END;
Anche in questo caso è necessario creare un trigger per ogni tabella coinvolta
dal vincolo d’integrità in esame.
5.2.6. GENERAZIONE DELLE VIEW EFFICIENTI
La generazione automatica delle view efficienti non banale. È necessario creare
diverse strutture dati per ogni tabella coinvolta nel vincolo e le variabili da
sostituire sono molte. La generazione avviene tramite i seguenti template, nel
caso di PostgresSQL:
CREATE TEMPORARY TABLE tu%tabledefinition%
ON COMMIT DELETE ROWS;
CREATE OR REPLACE FUNCTION f%constraint%()
RETURNS trigger
AS $$
BEGIN
INSERT INTO tu%maintable% VALUES (NEW.*);
RETURN NULL;
END;
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 66 ~
$$
LANGUAGE plpgsql;
CREATE TRIGGER t%constraint%
%firecondition%ON %maintable%
FOR EACH ROW EXECUTE PROCEDURE f%constraint%();
Questo template è sufficiente nel caso in cui il vincolo possa essere violato solo
da eventi che accadono sulla tabella principale, ovvero la tabella su cui si basa la
view di partenza. La variabile %maintable% contiene infatti il nome di tale
tabella, mentre la variabile %tabledefinition% contiene la sua dichiarazione
delle colonne. Nel caso in cui siano coinvolte più tabelle, è necessario utilizzare
ulteriori template. È anche necessario distinguere tra tabelle di associazione e
tabelle di entità. Nel caso di tabelle di associazione, il template è il seguente:
CREATE OR REPLACE FUNCTION f%constraint%_%table%()
RETURNS trigger
AS $$
BEGIN
INSERT INTO tu%maintable%
SELECT * FROM %maintable%
WHERE OID = NEW.%foreignkey%;
RETURN NULL;
END;
$$
LANGUATE plpgsql;
CREATE TRIGGER t%constraint%_%table%
%firecondition%ON %table% FOR EACH ROW
EXECUTE PROCEDURE f%constraint%_%table%();
Il trigger inserisce nella tabella temporanea una copia della tupla il cui OID è
referenziato dalla nuova tupla della tabella di associazione.
Nel caso di tabella di entità infine si utilizza un altro template:
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 67 ~
CREATE OR REPLACE FUNCTION f%constraint%_%table%()
RETURNS trigger
AS $$
BEGIN
INSERT INTO tu%maintable%
SELECT * from %maintable%
WHERE OID IN
(SELECT %foreignkey% FROM %asstable%
WHERE %foreignkey2% = NEW.OID);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER t%constraint%_%table%
%firecondition%ON %table%
FOR EACH ROW EXECUTE PROCEDURE f%constraint%_%table%();
Per completare questo template è necessario estrarre ulteriori informazioni da
sostituire alle variabili. Bisogna infatti ricavare il nome della tabella di
associazione che associa l’entità della tabella con l’entità della tabella principale
e sostituirlo alla variabile %asstable%. Tale tabella associativa avrà due chiavi
esterne, una relativa all’entità della tabella principale, che andrà sostituita a
%foreignkey% , e l’altra relativa all’entità della tabella, che andrà sostituita a
%foreignkey2%.
Per Oracle si usano template diversi. Per la tabella principale, si usa il seguente
template:
CREATE GLOBAL TEMPORARY TABLE tu%tabledefinition%
ON COMMIT DELETE ROWS;
CREATE TRIGGER t%constraint%
%firecondition%ON %table% FOR EACH ROW
BEGIN
INSERT INTO tu%maintable% VALUES (:NEW.*);
END;
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 68 ~
Mentre per le tabelle di associazione si usa il seguente:
CREATE TRIGGER t%constraint%_%table%
%firecondition%ON %table% FOR EACH ROW
BEGIN
INSERT INTO tu%maintable%
SELECT * FROM %maintable%
WHERE OID = :NEW.%foreignkey%;
END;
Infine il template per le tabelle di entità:
CREATE TRIGGER t%constraint%_%table%
%firecondition%ON %table% FOR EACH ROW
BEGIN
INSERT INTO tu%maintable%
SELECT * from %maintable%
WHERE OID IN
(SELECT %foreignkey% FROM %asstable%
WHERE %foreignkey2% = :NEW.OID);
END;
La variabile %tabledefinition% contiene il nome della tabella e l’elenco delle
colonne secondo la sintassi SQL, ad esempio:
T_Studente(OID int, …)
5.2.7. GENERAZIONE DEI CHECK E DEI CHECK DIFFERITI
La generazione dei Check avviene in modo molto semplice, tramite il seguente
template:
ALTER TABLE %table% ADD CONSTRAINT Check%constraint%
CHECK (%condition%) [DEFERRABLE];
Come nei casi precedenti bisogna sostituire i valori corretti alla variabile
%table% e alla variabile %constraint%, ma in più in questo caso è necessario
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 69 ~
sostituire la condizione da verificare alla variabile %condition%. La clausola
deferrable viene aggiunta in caso di necessità, ma alcuni DBMS non la
supportano. PostgresSQL ad esempio la supporta attualmente solo per i vincoli
di tipo foreign key.
5.3. DESIGN DI ICTUNINGGUI
ICTuningGui è stato sviluppato interamente in linguaggio Java. Tale linguaggio
è stato scelto per diversi motivi, tra i quali i più importanti risultano essere la
facilità di programmazione, la portabilità del codice a diversi sistemi operativi e
architetture e la disponibilità di librerie per lo svolgimento delle funzioni di
generazione del codice SQL e dell’analisi dei vincoli OCL.
L’interfaccia grafica fa uso delle librerie Swing, che garantiscono un aspetto
grafico uniforme con il resto dell’interfaccia del sistema operativo.
5.3.1. PSERELEVANT
Per l’analisi dei file XML e la determinazione degli eventi strutturali
potenzialmente violanti per i vincoli d’integrità è stata integrata in ICTuningGui
la libreria PSERelevant, realizzata da Carol Cervellò nell’ambito della sua tesi
di Laurea presso l’Universitat Oberta de Catalunya, sotto la supervisione del
professor Jordi Cabot Sagrera. PSERelevant utilizza degli alberi binari per la
rappresentazione dei vincoli OCL e permette di estrarre gli eventi strutturali
potenzialmente violanti semplicemente chiamando un metodo della classe che
rappresenta un nodo dell’albero binario. Anche PSERelevant si basa sul
Dresden OCL Toolkit per l’analisi del codice OCL e dei file XMI. Tramite il nodo
alla base dell’albero binario è possibile indicare l’intero albero che rappresenta il
vincolo d’integrità.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 70 ~
5.3.2. DRESDEN OCL TOOLKIT
Sviluppato dal Technische Universität Dresden, il Dresden OCL Toolkit19 è un
insieme di strumenti che permettono di analizzare i vincoli OCL e trasformarli
in codice SQL. Il Dresden OCL Toolkit viene utilizzato da ICTuningGui come
motore per la generazione del codice SQL per le tabelle e per le view inefficienti
e per l’estrazione delle informazioni relative ai vincoli d’integrità dal codice
OCL. Il codice per le view semi-efficienti e per i trigger viene generato tramite
l’utilizzo di template e espressioni regolari a partire dal codice delle view
inefficienti.
Il processo di generazione del codice SQL è implementato come una
trasformazione tra metamodelli. La specifica del linguaggio OCL 2.0 definisce
sia una sintassi concreta, sia una sintassi astratta. La sintassi concreta permette
di scrivere le espressioni OCL testuali, mentre la sintassi astratta permette di
rappresentare i concetti dell’OCL utilizzando un metamodello MOF (Meta
Object Facility). Il Dresden OCL Tookit costruisce l’albero sintattico concreto a
partire dalle espressioni OCL testuali tramite l’analisi lessicale e sintattica,
dopodiché genera l’albero sintattico astratto tramite l’analisi contestuale. La
definizione di tale trasformazione è data da metamodelli contenuti in un
repository MDR (MOF Data Repository). L’albero sintattico astratto viene
inserito nel repository MDR e quindi convertito in codice SQL tramite un
compilatore.
Il Dresden OCL Toolkit supporta i dialetti SQL di Oracle 8i, PostgresSQL 8.1 e lo
standard SQL:1999. Ulteriori dialetti possono essere aggiunti tramite file di
specifica.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 71 ~
Poiché il Dresden OCL Toolkit al momento non supporta la generazione di
trigger, si è utilizzato un algoritmo basato su espressioni regolari per la loro
generazione.
5.3.3. STRUTTURA DI ICTUNINGGUI
ICTuningGui è costituito dai seguenti package:
Gui: contiene le classi relative all’interfaccia grafica
Model: contiene le classi relative ai modelli statici e dinamici
Technique: contiene le classi relative alle tecniche implementative, la loro
determinazione e la loro conversione in codice SQL.
Util: contiene metodi di utilità generici, come il supporto alla gestione dei
file.
Le classi del package gui utilizzano Swing per disegnare la finestra e i
componenti grafici del programma. La classe LanguageManager inoltre si
occupa di gestire i diversi linguaggi. È sufficiente modificare il file di
configurazione Languages.xml per aggiungere il supporto ad altri linguaggi al
programma. I paragrafi successivi illustrano nei dettagli le classi principali.
5.3.4. PACKAGE MODEL
Il package Model contiene due classi principali: Model e IntegrityConstraint,
rappresentate secondo il diagramma delle classi UML in Figura 11. La classe
Model contiene i modelli UML (espresso in XMI) e XML e i vincoli OCL per
l’applicazione web in fase di sviluppo. Il costruttore riceve come parametri i
percorsi per i tre file e li analizza, estraendo i vincoli d’integrità e i relativi eventi
strutturali potenzialmente violanti prima e dopo la riduzione presentata nel
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 72 ~
Capitolo 3.2. Il metodo getConstraints() restituisce un Vettore contenente tutti
i vincoli di integrità, ognuno rappresentato dalla classe IntegrityConstraint.
FIGURA 11: CLASSI PRINCIPALI DEL PACKAGE MODEL
La classe IntegrityConstraint rappresenta un singolo vincolo d’integrità. Il
costruttore richiede come parametri il nome del vincolo, l’elenco dei suoi eventi
strutturali potenzialmente violanti prima e dopo la riduzione e la
rappresentazione ad albero creata da PSERelevant. I molti metodi set e get
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 73 ~
permettono di impostare i parametri di scelta delle tecniche e di estrarre tutte le
informazioni sul vincolo, tra le altre cose. Il metodo findBestTechnique() infine
calcola la tecnica più indicata, che può essere estratta tramite il metodo
getTechnique. La tecnica è rappresentata dalla classe Technique e dalle sue
implementazioni nel package technique.
5.3.5. PACKAGE TECHNIQUE
Il package Technique contiene le classi che rappresentano le diverse tecniche
implementative. Tali classi sono rappresentate in Figura 12.
FIGURA 12: CLASSI DEL PACKAGE TECHNIQUE
La classe Technique è una classe astratta che definisce numerosi metodi ad uso
interno per determinare i valori da sostituire alle variabili nei template per la
generazione del codice SQL. Il metodo astratto getSQL() infine deve essere
implementato da ogni sottoclasse.
Le sottoclassi rappresentano ognuna una tecnica implementativa diversa,
comprese le classi NoTechnique e NotNecessaryTechnique che vengono
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 74 ~
utilizzate quando la configurazione dei parametri non è supportata oppure il
vincolo non deve essere controllato. Il costruttore riceve come parametro un
IntegrityConstraint che rappresenta il vincolo che la tecnica deve implementare.
5.3.6. PACKAGE TECHNIQUE, CLASSE TECHNIQUECHOOSER
Questa classe è una classe con un’unica istanza. Il costruttore infatti è privato e
viene gestito dal metodo getInstance(). Durante l’inizializzazione della classe
viene letto il file TechniqueChooserConfig.xml e viene creato un albero
decisionale. Il metodo findBestTechnique(IntegrityConstraint IC) determina la
tecnica più indicata percorrendo l’albero decisionale in forma ricorsiva. Ogni
nodo dell’albero decisionale è costituito da un parametro di configurazione.
Analizzando il valore del nodo il metodo decide se proseguire l’analisi su quel
ramo oppure tornare indietro (backtracking).
5.4. MANUALE D’USO DI ICTUNINGGUI
La schermata principale di ICTuningGui è rappresentata in Figura 13. Tale
immagine, come tutte le immagini dell’interfaccia grafica del programma che
saranno presentate in seguito, è stata presa durante l’esecuzione di
ICTuningGui in un ambiente operativo Microsoft Windows Vista ma il suo
funzionamento è stato testato con successo anche in un ambiente Linux
recente.
Il requisito fondamentale per l’esecuzione di ICTuningGui è la Sun Java
Virtual Machine versione 5.0 o successiva.
L’interfaccia utente è stata progettata con l’obiettivo primario dell’immediatezza
d’uso. I menù, le etichette e i pulsanti possono essere tradotti in altre lingue
tramite la semplice modifica di un file XML. La struttura a linguette permette di
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 75 ~
avere rapidamente a portata di mano tutte le informazioni elaborate
dall’applicazione.
FIGURA 13: SCHERMATA PRINCIPALE DI ICTUNINGGUI.
Utilizzando i pulsanti posti sulla destra si possono caricare nel programma i tre
file necessari per procedere all’analisi, come mostrato in Figura 14. La finestra
di selezione dei file filtra i risultati in base all’estensione.
I tre file necessari sono:
Un file XMI, che contiene la rappresentazione UML del diagramma delle
classi dell’applicazione in fase di progetto. XMI (XML Metadata
Interchange) è un formato di interscambio sviluppato da OMG16. Questo
file può essere generato agevolmente tramite la funzione di esportazione
di cui sono generalmente dotati i software per la modellazione UML. Per
la realizzazione dei file di esempio è stato utilizzato il software
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 76 ~
ArgoUML, sviluppato da Linus Tolke, dell’Università della California, e
liberamente scaricabile da internet. Maggiori informazioni possono
essere ottenute sul sito ufficiale di ArgoUML: http://argouml.tigris.org.
FIGURA 14: CARICAMENTO FILE IN ICTUNINGGUI.
Un file OCL, che contiene i vincoli d’integrità da verificare espressi in
linguaggio OCL. Questo file può essere creato con un qualsiasi editor di
testo semplice. OCL, come UML, è uno standard aperto definito dal OMG
(Object Management Group). Per ulteriori informazioni e per le
specifiche complete del linguaggio OCL è possibile consultare il sito:
http://www.omg.org.
Un file XML, che contiene la rappresentazione del modello dinamico
dell’applicazione in fase di progetto espressa in linguaggio WebML.
WebML è stato sviluppato dal Politecnico di Milano per
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 77 ~
rappresentare complesse applicazioni web. Ulteriori dettagli su WebML
sono reperibili sul sito http://www.webml.org. Per la realizzazione di tale
file è necessario utilizzare WebRatio, un’applicazione commerciale per
la progettazione di applicazioni web orientate alla gestione dei dati
contenuti in una base di dati. Per maggiori informazioni è possibile
consultare il sito http://www.webratio.com.
FIGURA 15: I FILE SONO CARICATI E ICTUNINGGUI È PRONTO A INIZIARE L'ELABORAZIONE.
La Figura 15 rappresenta la schermata di ICTuningGui quando i tre file
necessari sono stati caricati. In caso di errori durante l’apertura dei file, oppure
di errori di formattazione dei file stessi, sarà visualizzato un avviso e i dettagli
dell’errore saranno visualizzati nella linguetta denominata Log.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 78 ~
5.4.1. ESTRAZIONE DEI VINCOLI E DEI RELATIVI PSE
Dopo aver caricato tutti i file necessari, il pulsante Constraints diventa
disponibile, come si può vedere in Figura 15. Premendo tale pulsante viene
visualizzato un elenco dei vincoli definiti per l’applicazione web e gli eventi
strutturali per ogni vincolo.
FIGURA 16: VISUALIZZAZIONE DEI VINCOLI E DEI RELATIVI EVENTI STRUTTURALI
POTENZIALMENTE VIOLANTI.
La Figura 16 rappresenta i vincoli e gli eventi strutturali per l’esempio
utilizzato finora nel testo. Gli eventi strutturali qui elencati sono ricavati
dall’analisi del solo modello statico dell’applicazione web. Nel passo successivo
saranno mostrati gli eventi strutturali potenzialmente violanti rimanenti dopo
l’eliminazione degli eventi che non possono verificarsi, determinati in seguito
all’analisi del modello dinamico.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 79 ~
5.4.2. PANNELLO DI CONFIGURAZIONE DEI PARAMETRI
In seguito alla pressione del pulsante Constraints, ICTuningGui procede
all’analisi del modello statico ed estrae alcuni dati che saranno utilizzati in
seguito per le successive operazioni. Il pulsante Techniques viene abilitato e,
in seguito alla pressione di tale pulsante, viene visualizzato un pannello di
configurazione dei parametri relativi all’ambiente di esecuzione
dell’applicazione web. Tale pannello è mostrato in Figura 17.
FIGURA 17: PANNELLO DI CONFIGURAZIONE DEI PARAMETRI.
Il pannello visualizza un elenco dei vincoli determinati al passo precedente e per
ognuno di essi presenta all’utente dei menù a tendina per la configurazione dei
quattro parametri discussi nel Capitolo 4.2. L’ultima riga contiene dei menù
rapidi che consentono di modificare i parametri di tutti i vincoli
contemporaneamente, per velocizzare le operazioni di configurazione.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 80 ~
Premendo il pulsante Find Techniques si procederà alla computazione
dell’insieme di tecniche più indicato per la configurazione di parametri inserita.
I nomi dei parametri e i valori che possono assumere sono sempre in inglese e
non possono essere tradotti tramite il file XML di configurazione della lingua.
Questo succede perché l’algoritmo di determinazione delle tecniche, che sarà
illustrato in seguito, è configurabile tramite la modifica di un file XML, pertanto
i nomi dei parametri e delle tecniche devono essere univoci.
5.4.3. DETERMINAZIONE DELLE TECNICHE
In seguito alla pressione del pulsante Find Techniques il pannello di
configurazione viene sostituito da un pannello contenente la visualizzazione
delle tecniche implementative consigliate. Tale pannello è visibile in Figura 18.
Per ogni vincolo vengono visualizzati gli eventi strutturali potenzialmente
violanti rimasti dopo la riduzione dovuta all’analisi del modello dinamico
dell’applicazione (ovvero il modello di ipertesto del diagramma WebML) e la
eventuale tecnica implementativa consigliata. Qualora tutti gli eventi strutturali
di un vincolo vengano scartati (ovvero non possono accadere secondo l’analisi
del modello di ipertesto), il vincolo sarà scartato e non sarà necessaria alcuna
verifica d’integrità per esso.
I pulsanti sottostanti il pannello dei risultati permettono di configurare
nuovamente i parametri oppure di salvare il risultato in un file di testo.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 81 ~
FIGURA 18: PANNELLO DI VISUALIZZAZIONE DELLE TECNICHE IMPLEMENTATIVE.
Per l’esempio in figura il file di testo risultante è riportato nel riquadro
seguente:
//File generated by ICTuningGui:
Constraint: MaxCorsoAnalisi
Configuration Parameters:
- Checking Time: Immediate
- Run Time Efficiency: Individual
- Population Volumen: High
- Use DBMS: Yes
Events for this constraint:
-> insertET(Corso)
-> updateAttribute(Corso-Titolo)
=> Best technique: not defined because the combination
of parameters is not advisable
Constraint: CreditiMax
Configuration Parameters:
- Checking Time: Deferred
- Run Time Efficiency: Overall
- Population Volumen: High
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 82 ~
- Use DBMS: No
Events for this constrant:
None.
=> Best technique: Constraint discarded. It is not
violated by the hypertext model
Constraint: CreditiCorretti
Configuration Parameters:
- Checking Time: Deferred
- Run Time Efficiency: Overall
- Population Volumen: Low
- Use DBMS: Yes
Events for this constraint:
-> updateAttribute(Studente-CreditiConseguiti)
-> insertET(Studente)
=> Best technique: direct implementation
Constraint: MatricolaCorretta
Configuration Parameters:
- Checking Time: Immediate
- Run Time Efficiency: Individual
- Population Volumen: High
- Use DBMS: Yes
Events for this constraint:
-> updateAttribute(Studente-Matricola)
-> insertET(Studente)
=> Best technique: checks
Per completezza nel file salvato vengono riportati i parametri inseriti, gli eventi
strutturali potenzialmente violanti rimasti dopo la riduzione dell’insieme degli
eventi e la tecnica consigliata.
Dopo aver determinato l’insieme di tecniche consigliate si sbloccherà il pulsante
SQL, che permette di procedere alla generazione del codice SQL vero e proprio.
I risultati ottenuti in questa fase dell’analisi saranno conservati in memoria ed
utilizzati per dirigere la generazione del codice SQL. È possibile visualizzare
questo pannello in ogni momento premendo il pulsante Techniques oppure
selezionando la linguetta corrispondente.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 83 ~
5.4.4. CONFIGURAZIONE DEL GENERATORE SQL
Il motore di generazione del codice SQL utilizzato da ICTuningGui deriva dal
Dresden OCL Toolkit e ne eredita pertanto le caratteristiche. La Figura 19
illustra il pannello di configurazione per la generazione del codice SQL. Anche
in questo caso le opzioni e i valori sono disponibili solamente in lingua inglese e
non possono essere tradotti per ragioni di compatibilità con le librerie del
Dresden OCL Toolkit incluse in ICTuningGui.
FIGURA 19: PANNELLO DI CONFIGURAZIONE DEL GENERATORE DI CODICE SQL.
I parametri da configurare sono i seguenti:
Destination Language (linguaggio di destinazione): permette di
specificare quale dialetto SQL utilizzare per la generazione del codice. I
valori al momento supportati sono:
o PostgresSQL 8.1
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 84 ~
o Oracle 8i
o SQL Standard (SQL::1999)
Mapping Modus (metodo di mappatura): specifica quale metodo per la
mappatura delle tabelle debba essere usato. I valori possibili sono:
o Typed (tipizzato): viene creata una sola tabella per ogni classe,
comprendente ogni sua sotto-classe.
o Vertical (verticale): viene create una tabella per ogni classe e per
ogni sotto-classe.
Table Prefix (prefisso delle tabelle): permette di scegliere il prefisso da
porre all’inizio del nome delle tabelle.
Foreign Key Prefix (prefisso della chiave esterna): specifica quale prefisso
utilizzare per i nomi delle chiavi esterne.
Association Table Prefix (prefisso della tabella di associazione): indica
quale prefisso utilizzare per i nomi delle tabelle che contengono le
relazioni tra le classi del modello.
Object View Prefix (prefisso delle view oggetto): indica quale prefisso
apporre ai nomi delle view.
Premendo il pulsante Generate SQL si procederà alla generazione del codice
SQL. ICTuningGui provvede e generare il codice sia delle tabelle corrispondenti
alle classi di tutto il modello, sia le view e i trigger necessari
all’implementazione della verifica d’integrità secondo l’insieme di tecniche
determinato in precedenza.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 85 ~
5.4.5. GENERAZIONE DEL CODICE SQL
La generazione del codice richiede una quantità considerevole di tempo,
secondo le prestazioni della macchina su cui si sta utilizzando ICTuningGui. Al
termine dell’elaborazione il pannello della configurazione viene sostituito da un
pannello contenente il codice SQL risultante. Il codice è separato in due parti
per semplificarne la lettura, come mostrato in Figura 20. La prima parte,
contenuta nella linguetta Table Schema, contiene il codice SQL necessario per la
generazione delle tabelle dell’applicazione, delle view sulle tabelle e dei
constraint sulle tabelle, nel caso siano supportati dalla base di dati selezionata
durante la configurazione.
FIGURA 20: PANNELLO DI VISUALIZZAZIONE DEL CODICE SQL GENERATO.
Il codice contenuto in questa sezione non dipende dall’insieme di tecniche
determinate in precedenza. La linguetta Integrity Views contiene invece il
codice per la verifica d’integrità vera e propria. Per ogni vincolo d’integrità viene
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 86 ~
generato il codice SQL che implementa la tecnica più indicata concordemente ai
risultati ottenuti durante l’elaborazione dell’insieme di tecniche più idonee.
Anche in questo caso è possibile salvare il codice SQL in un file di testo tramite
il pulsante Save SQL oppure è possibile cambiare le opzioni e generare
nuovamente il codice. Agendo sui pulsanti sulla destra è anche possibile tornare
a un punto precedente dell’elaborazione e cambiare le opzioni, cosa che rende
semplice confrontare diverse configurazioni di parametri.
È anche possibile selezionare e copiare parti di testo di ogni pannello
dell’applicazione, sia tramite il menù Edit, sia tramite la pressione del tasto
destro del mouse, che fa comparire un menù a scomparsa con le funzioni di
selezionare tutto il testo e copiare il testo selezionato negli appunti del sistema
operativo. Infine, la funzione Clear all data del menù File permette di
riportare ICTuningGui allo stato iniziale, rendendo possibile analizzare un
nuovo set di file di modello.
5.5. PROBLEMI NOTI
Questa sezione presenta i problemi noti di ICTuningGui. Alcuni di questi
problemi potranno con ogni probabilità essere risolti al momento
dell’integrazione con WebRatio.
5.5.1. NECESSITÀ DI DUE MODELLI
Per poter utilizzare ICTuningGui è necessario disporre di due modelli della
stessa applicazione: un modello WebML e un modello UML. Seppur sia
probabile che durante la progettazione dell’applicazione il progettista abbia
prima di tutto creato il modello UML e successivamente il modello WebML, tale
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
ICTuningGui
~ 87 ~
ridondanza può risultare poco pratica. La difficoltà maggiore nasce dal fatto che
i due modelli devono essere perfettamente equivalenti fin nei minimi dettagli,
come l’uso delle maiuscole nei nomi degli attributi.
5.5.2. CONSISTENZA DEI NOMI UTILIZZATI
Uno dei maggiori problemi che possono verificarsi utilizzando ICTuningGui per
l’ottimizzazione del controllo d’integrità di un’applicazione web progettata
tramite l’uso di WebRatio è la mancanza di consistenza tra i nomi delle tabelle e
degli oggetti usati in WebRatio e i nomi delle tabelle e degli oggetti generati da
ICTuningGui. Questo comporta la necessità di modificare manualmente il
codice generato da ICTuningGui per conformare i nomi degli oggetti a quelli in
uso nella base di dati gestita da WebRatio. Benché tale risultato possa essere
ottenuto tramite una semplice sostituzione di termini, si tratta di un’operazione
tediosa e che può causare errori.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 88 ~
6. ESEMPIO DI UTILIZZO DELL’APPLICAZIONE
Questo capitolo presenta un esempio di utilizzo completo di ICTuningGui. Il
modello dell’applicazione web riguarda la gestione del catalogo di una libreria. Il
modello UML delle classi è rappresentato in Figura 21.Figura 1
FIGURA 21: DIAGRAMMA DELLE CLASSI DELLA LIBRERIA
L’oggetto principale è il Libro, con un Titolo, un codice univoco ISBN, un
contatore del numero di pagine, un prezzo di copertina e un identificativo OID
univoco. Le altre entità del modello sono l’Autore, che può essere collegato (ha
scritto) a un qualsiasi numero di libri, la Categoria alla quale ogni libro
appartiene e la CasaEditrice che pubblica il libro. Un libro può avere uno o più
autori, una o più case editrici e può appartenere a una o più categorie. Il
modello statico è presente anche nel modello WebML, sotto forma di
diagramma entità-relazione ed è riportato in Figura 22.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 89 ~
FIGURA 22: DIAGRAMMA E-R DELLA LIBRERIA
FIGURA 23: GESTIONE DELLE CASE EDITRICI
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 90 ~
Il modello WebML contiene anche il modello dinamico dell’applicazione.
Trattandosi di un catalogo di libri, le operazioni supportate saranno di gestione
della base di dati dei libri, delle categorie, degli autori e delle case editrici. Sarà
inoltre possibile creare ed eliminare associazioni tra le varie entità. Le Figure
23, 24, 25 e 26 rappresentano il modello di ipertesto dell’applicazione web.
FIGURA 24: GESTIONE DEGLI AUTORI
I vincoli della classe Libro assicurano che ogni istanza di libro abbia un prezzo
maggiore di zero, un codice ISBN univoco e almeno un autore, una casa editrice
e una categoria. Per la classe Autore il vincolo assicura invece che non ci siano
due istanze con lo stesso nome e cognome, mentre per la classe CasaEdistrice è
previsto un vincolo che limita la lunghezza massima della stringa contenente
l’indirizzo web della compagnia. Il valore è riferito alla massima lunghezza
supportata dal browser Microsoft Internet Explorer.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 91 ~
FIGURA 25: GESTIONE DEI LIBRI
FIGURA 26: GESTIONE DELLE CATEGORIE
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 92 ~
La Figura 27 riporta la schermata di ICTuningGui subito dopo la valutazione
dei vincoli d’integrità.
FIGURA 27: VINCOLI PER LA LIBRERIA
Infine è necessario definire i vincoli d’integrità in linguaggio OCL. Sono definiti i
seguenti vincoli:
package Libreria
context Libro
inv PrezzoCorretto: self.PrezzoDiCopertina > 0
inv AlmenoUnAutore: self.Autore->size() > 0
inv AlmenoUnEditore: self.CasaEditrice->size() > 0
inv AlmenoUnaCategoria: self.Categoria->size() > 0
inv ISBNUnico:
Libro::allInstances()->select(o,p|o.ISBN=p.ISBN)-
>size() < 1
context Autore
inv AutoreUnico: Autore::allInstances()->select
(x,y|x.Nome=y.Nome and x.Cognome=y.Cognome)->size() < 1
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 93 ~
context CasaEditrice
inv SitoCorretto: self.SitoInternet->size()<2083
endpackage
I parametri di configurazione influenzano la scelta finale delle tecniche.
Prevediamo un volume basso per la popolazione delle case editrici e degli autori,
mentre il volume della popolazione dei libri sarà elevato. Poiché le operazioni di
associazione di autore, casa editrice e categoria a un libro non avvengono tutte
contemporaneamente, richiediamo che la verifica avvenga in modo posticipato
per permettere uno stato inconsistente per un breve periodo di tempo. Infine
chiediamo di avere una prestazione globale. La Figura 28 mostra i parametri.
FIGURA 28: PARAMETRI DI CONFIGURAZIONE
È semplice prevedere, osservando il modello di ipertesto, che i vincoli
AlmenoUnaCategoria, AlmenoUnAutore e AlmenoUnEditore saranno
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 94 ~
implementati alla stessa maniera, e che il vincolo SitoCorretto non può essere
violato. La schermata visualizzata in Figura 29 conferma le previsioni.
ICTuningGui suggerisce di implementare direttamente il vincolo AutoreUnico,
di utilizzare le view semi-efficienti per ISBNUnico e di usare le view efficienti
per i vincoli rimanenti.
La configurazione per la generazione del codice SQL viene lasciata ai valori
predefiniti, ad esclusione della selezione del linguaggio di destinazione,
impostato a Oracle.
FIGURA 29: TECNICHE IMPLEMENTATIVE
Il codice SQL per la creazione delle tabelle della base di dati è il seguente:
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 95 ~
CREATE TABLE T_Autore(OID INT PRIMARY KEY,Cognome
VARCHAR(255),Nome VARCHAR(255));
CREATE TABLE T_CasaEditrice(SitoInternet
VARCHAR(255),Sede VARCHAR(255),OID INT PRIMARY KEY,Nome
VARCHAR(255));
CREATE TABLE T_Categoria(Nome VARCHAR(255),OID INT
PRIMARY KEY);
CREATE TABLE T_Libro(NumeroDiPagine
INT,PrezzoDiCopertina INT,ISBN VARCHAR(255),Titolo
VARCHAR(255),OID INT PRIMARY KEY);
CREATE TABLE ASS_Categoria_Libro (
FK_Libro VARCHAR(255),FK_Categoria VARCHAR(255)
);
CREATE TABLE ASS_Libro_CasaEditrice (
FK_CasaEditrice VARCHAR(255),FK_Libro VARCHAR(255)
);
CREATE TABLE ASS_Libro_Autore (
FK_Autore VARCHAR(255),FK_Libro VARCHAR(255)
);
CREATE VIEW OV_CasaEditrice
AS ( SELECT T_CasaEditrice.Nome as
Nome,T_CasaEditrice.OID as OID,T_CasaEditrice.Sede as
Sede,T_CasaEditrice.SitoInternet as SitoInternet
FROM T_CasaEditrice
);
CREATE VIEW OV_Autore
AS ( SELECT T_Autore.Cognome as Cognome,T_Autore.Nome
as Nome,T_Autore.OID as OID
FROM T_Autore
);
CREATE VIEW OV_Categoria
AS ( SELECT T_Categoria.Nome as Nome,T_Categoria.OID as
OID
FROM T_Categoria
);
CREATE VIEW OV_Libro
AS ( SELECT T_Libro.ISBN as ISBN,T_Libro.NumeroDiPagine
as NumeroDiPagine,T_Libro.OID as
OID,T_Libro.PrezzoDiCopertina as
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 96 ~
PrezzoDiCopertina,T_Libro.Titolo as Titolo
FROM T_Libro
);
ALTER TABLE ASS_Categoria_Libro ADD CONSTRAINT
CONASS_Categoria_LibroFK_Libro
FOREIGN KEY (FK_Libro) REFERENCES T_Libro(OID);
ALTER TABLE ASS_Libro_CasaEditrice ADD CONSTRAINT
CONASS_Libro_CasaEditriceFK_CasaEditrice
FOREIGN KEY (FK_CasaEditrice) REFERENCES
T_CasaEditrice(OID);
ALTER TABLE ASS_Categoria_Libro ADD CONSTRAINT
CONASS_Categoria_LibroFK_Categoria
FOREIGN KEY (FK_Categoria) REFERENCES T_Categoria(OID);
ALTER TABLE ASS_Libro_CasaEditrice ADD CONSTRAINT
CONASS_Libro_CasaEditriceFK_Libro
FOREIGN KEY (FK_Libro) REFERENCES T_Libro(OID);
ALTER TABLE ASS_Libro_Autore ADD CONSTRAINT
CONASS_Libro_AutoreFK_Autore
FOREIGN KEY (FK_Autore) REFERENCES T_Autore(OID);
ALTER TABLE ASS_Libro_Autore ADD CONSTRAINT
CONASS_Libro_AutoreFK_Libro
FOREIGN KEY (FK_Libro) REFERENCES T_Libro(OID);
Inoltre il codice per la verifica d’integrità:
-- Constraint: SitoCorretto
-- Technique: constraint discarded. It is not violated
by the hypertext model
-- Constraint: AutoreUnico
-- Technique: direct implementation
create or replace view AutoreUnico as
(select * from OV_Autore SELF
where not (((select NVL(COUNT(*),0)
from OV_Autore
where OID in (select OID from OV_Autore) minus
select OID from OV_Autore ALIAS2
where not (((ALIAS2.Nome = ALIAS2.Nome) AND
(ALIAS2.Cognome = ALIAS2.Cognome))))) < 1)));
-- Constraint: ISBNUnico
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 97 ~
-- Technique: semi-efficient approach
CREATE GLOBAL TEMPORARY TABLE seISBNUnico (Event
char(1))
ON COMMIT DELETE ROWS;
CREATE TRIGGER tISBNUnico
AFTER INSERT OR DELETE OR UPDATE ON T_Libro FOR EACH
STATEMENT
BEGIN
INSERT INTO seISBNUnico VALUES ('1');
END;
-- Constraint: AlmenoUnaCategoria
-- Technique: efficient views
CREATE GLOBAL TEMPORARY TABLE tu%tabladefinition%
ON COMMIT DELETE ROWS;
CREATE TRIGGER tAlmenoUnaCategoria
AFTER INSERT OR DELETE OR UPDATE ON %table% FOR EACH
ROW
BEGIN
INSERT INTO tuT_Libro
VALUES (:NEW.*);
END;
CREATE TRIGGER tAlmenoUnaCategoria_ASS_Categoria_Libro
AFTER INSERT OR DELETE OR UPDATE ON ASS_Categoria_Libro
FOR EACH ROW
BEGIN
INSERT INTO tuT_Libro
SELECT * FROM T_Libro
WHERE OID = :NEW.FK_Libro;
END;
create or replace view AlmenoUnaCategoria as
(select * from tuT_Libro SELF
where not (((select NVL(COUNT(*),0)
from OV_Categoria
where OID in (select OID from OV_Categoria where OID
in
(select FK_Categoria from ASS_Categoria_Libro where
FK_Libro in
(select OID from tuT_Libro where OID = SELF.OID)))) >
0)));
-- Constraint: AlmenoUnEditore
-- Technique: efficient views
CREATE GLOBAL TEMPORARY TABLE tu%tabladefinition%
ON COMMIT DELETE ROWS;
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 98 ~
CREATE TRIGGER tAlmenoUnEditore
AFTER INSERT OR DELETE OR UPDATE ON %table% FOR EACH
ROW
BEGIN
INSERT INTO tuT_Libro
VALUES (:NEW.*);
END;
CREATE TRIGGER tAlmenoUnEditore_ASS_Libro_CasaEditrice
AFTER INSERT OR DELETE OR UPDATE ON
ASS_Libro_CasaEditrice FOR EACH ROW
BEGIN
INSERT INTO tuT_Libro
SELECT * FROM T_Libro
WHERE OID = :NEW.FK_Libro;
END;
create or replace view AlmenoUnEditore as
(select * from tuT_Libro SELF
where not (((select NVL(COUNT(*),0)
from OV_CasaEditrice
where OID in (select OID from OV_CasaEditrice where
OID in
(select FK_CasaEditrice from ASS_Libro_CasaEditrice
where FK_Libro in
(select OID from tuT_Libro where OID = SELF.OID)))) >
0)));
-- Constraint: AlmenoUnAutore
-- Technique: efficient views
CREATE GLOBAL TEMPORARY TABLE tu%tabladefinition%
ON COMMIT DELETE ROWS;
CREATE TRIGGER tAlmenoUnAutore
AFTER INSERT OR DELETE OR UPDATE ON %table% FOR EACH
ROW
BEGIN
INSERT INTO tuT_Libro
VALUES (:NEW.*);
END;
CREATE TRIGGER tAlmenoUnAutore_ASS_Libro_Autore
AFTER INSERT OR DELETE OR UPDATE ON ASS_Libro_Autore
FOR EACH ROW
BEGIN
INSERT INTO tuT_Libro
SELECT * FROM T_Libro
WHERE OID = :NEW.FK_Libro;
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Esempio di utilizzo dell’applicazione
~ 99 ~
END;
create or replace view AlmenoUnAutore as
(select * from tuT_Libro SELF
where not (((select NVL(COUNT(*),0)
from OV_Autore
where OID in (select OID from OV_Autore where OID in
(select FK_Autore from ASS_Libro_Autore where
FK_Libro in
(select OID from tuT_Libro where OID = SELF.OID)))) >
0)));
-- Constraint: PrezzoCorretto
-- Technique: efficient views
CREATE GLOBAL TEMPORARY TABLE tu%tabladefinition%
ON COMMIT DELETE ROWS;
CREATE TRIGGER tPrezzoCorretto
AFTER INSERT OR DELETE OR UPDATE ON %table% FOR EACH
ROW
BEGIN
INSERT INTO tuT_Libro
VALUES (:NEW.*);
END;
create or replace view PrezzoCorretto as
(select * from tuT_Libro SELF
where not ((SELF.PrezzoDiCopertina > 0)));
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Conclusione
~ 100 ~
7. CONCLUSIONE
In questo documento è stato presentato un approccio alla gestione efficiente del
controllo d’integrità per applicazioni web. Il metodo si basa su ben note
strategie incrementali che lavorano tramite l’estrazione degli eventi strutturali
potenzialmente violanti e la definizione di strutture dati di supporto per la
verifica efficiente dei vincoli d’integrità. È stato definito e implementato un
algoritmo che permette al progettista di applicazioni web di integrare facilmente
la verifica d’integrità nell’applicazione finale.
È importante notare che l’utilizzo dei metodi incrementali non lede le
prestazioni delle query sulla base di dati, pertanto le applicazioni web basate
principalmente su query (come applicazioni di pubblicazione dati) non sono
soggette a un degrado di efficienza.
Il metodo automatico realizzato permette di implementare rapidamente e con il
minimo sforzo tutta la parte relativa alla verifica d’integrità nell’ambito della
progettazione di un’applicazione web tramite uno strumento quale WebRatio.
Questo consente un risparmio in termini di tempo e, di conseguenza, una
riduzione dei costi di sviluppo. Inoltre, trattandosi di un metodo automatico, la
possibilità di errori durante la scrittura del codice è molto ridotta.
L’implementazione è risultata sufficientemente semplice grazie alla presenza di
librerie quali PSERelevant e Dresden OCL Toolkit che svolgono la gran parte del
lavoro necessario. La difficoltà maggiore è risultata essere l’implementazione di
un metodo per la generazione dei metodi ottimizzati più complessi, come le
view efficienti e i trigger a causa della mancanza di supporto per le strutture dati
necessarie da parte del Dresden OCL Toolkit. I metodi implementati si sono
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Conclusione
~ 101 ~
comunque rivelati efficienti e corretti durante le prove di funzionamento
effettuate.
7.1. SVILUPPI FUTURI
Questa sezione illustra quali caratteristiche saranno implementate nelle versioni
successive di ICTuningGui.
7.1.1. SUPPORTO PER ALTRE TECNOLOGIE
Nell’ambito delle applicazioni web si sono affermate negli ultimi anni delle
tecnologie innovative, quali Hibernate o Apache Struts. Aggiungendo il
supporto a tali tecnologie si otterrebbe un sistema per l’ottimizzazione della
verifica dei vincoli d’integrità più versatile e longevo. Per proseguire in questa
direzione è inoltre necessario studiare nuove tecniche ottimizzate per
l’implementazione dei vincoli d’integrità nei nuovi ambienti di lavoro.
7.1.2. INTEGRAZIONE IN WEBRATIO
L’integrazione di ICTuningGui in WebRatio risolverebbe i problemi di
consistenza dei nomi delle tabelle e degli oggetti utilizzati. WebRatio al
momento della stesura di questo testo è in fase di transizione da una
piattaforma proprietaria alla piattaforma Eclipse, pertanto si è deciso di
attendere che tale transizione fosse completata prima di procedere
all’integrazione tra le due applicazioni.
L’integrazione comporta l’adozione del motore di generazione SQL utilizzato da
WebRatio, nonché il supporto per tutte le piattaforme di basi di dati supportate
da esso, rendendo pertanto necessaria la riscrittura di alcune classi. Grazie
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Conclusione
~ 102 ~
all’adozione della piattaforma Eclipse da parte di WebRatio però l’integrazione
viene grandemente semplificata grazie alla solida gestione dei plug-in esistente.
7.1.3. ELIMINAZIONE DELLA NECESSITÀ DEL FILE XMI
Il diagramma delle classi UML contenuto nel file XMI è necessario perché le
librerie del Dresden OCL Toolkit e di PSERelevant si basano su di esso per le
loro elaborazioni. In seguito all’integrazione dell’applicazione in WebRatio, il
Dresden OCL Toolkit verrebbe abbandonato, e con la sola riscrittura di parte del
codice di PSERelevant sarebbe possibile eseguire le stesse elaborazioni
basandosi solamente sul modello WebML.
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Bibliografia
~ 103 ~
8. BIBLIOGRAFIA
1. Baresi, L., Colazzo, S. and Mainetti, L., First Experiences on Constraining
Consistency and Adaptivity of W2000 Models. in SAC 2005, 1674-1678.
2. Cabot, J. and Teniente, E., Determining the Structural Events that May
Violate an Integrity Constraint. in UML 2004, LNCS, 3273, 173-187.
3. Ceri, S., Daniel, F., Demaldé, V. and Facca, F.M., An Approach to User-
Behavior-Aware Web Applications. in ICWE 2005, 417-428.
4. Ceri, S., Fraternali, P., Bongio, A., Brambilla, M., Comai, S. and Matera,
M. Designing Data-Intensive Web Applications. Morgan Kaufmann,
2002.
5. Ceri, S. and Widom, J., Deriving Production Rules for Constraint
Maintenance. in VLDB 1990, Morgan Kaufmann, 566-577.
6. Demuth, B., Hussmann, H. and Loecher, S., OCL as a Specification
Language for Business Rules in Database Applications. in UML 2001,
LNCS, 2185, 104-117.
7. Fernandez, M.F., Florescu, D., Levy, A.Y. and Suciu, D. Declarative
Specification of Web Sites with Strudel. VLDB Journal, 9 (1). 38-55.
8. Fons, J., Pelechano, V., Albert, M. and Pastor, Ó. Development of Web
Applications from Web Enhanced Conceptual Schemas. in ER 2003,
LNCS, 2813, 232-245.
9. Garrigós, I., Gómez, J. and Cachero, C., Modelling Dynamic
Personalization in Web Applications. in ICWE 2003, 472-475.
10. Gupta, A. and Mumick, I.S. Maintenance of materialized views:
problems, techniques, and applications. in Materialized Views
Ottimizzazione e implementazione della verifica d’integrità per applicazioni web.
Bibliografia
~ 104 ~
Techniques, Implementations, and Applications, The MIT Press, 1999,
145-157.
11. ISO/TC97/SC5/WG3. Concepts and Terminology for the Conceptual
Schema and Information Base, 1982.
12. Melton, J. and Simon, A.R. SQL:1999, Understanding Relational
Language Components. Morgan Kaufmann, 2002.
13. OMG. UML 2.0 OCL Specification, 2003.
14. OMG. UML 2.0 Superstructure Specification, 2003.
15. OMG. XML Metadata Interchange Specification, 2002.
16. Schwabe, D. and Rossi, G. The Object-Oriented Hypermedia Design
Model. Communications of the ACM, 38 (8). 45-46.
17. Türker, C. and Gertz, M. Semantic integrity support in SQL:1999 and
commercial (object-)relational database management systems. The
VLDB Journal, 10 (4). 241-269.Object Management Group (2004). UML
2.0 OCL Specification. OMG Document formal/2004-10-14.
18. The WebML Metamodel [homepage su Internet]; 2006. Disponibile a:
http://www.webml.org/webml/page5.do.
19. Technische Universität Dresden, D.o.C.S.: Dresden OCL Toolkit.
http://dresdenocl.sourceforge.net
20. Nathalie Moreno, Piero Fraternali, Antonio Vallecillo . WebML
Modeling in UML 2.0, IETJournal article.
21. Birgit Demuth, Heinrich Hussmann, Ansgar Konermann. Generation of
an OCL 2.0 Parser.