ePrometeusCorsoJavaJava
testi articoli
Testi Articoli  Download
Home | Eshop | Java | Tools | Web | 
CorsoJava è ora Video! Free for all!
Clicca Qui!

JBUILDER JDBCL
Applicazioni data-oriented con Borland JBuilder e JBCL
Caratteristiche della JBCL
GUI con JBuilder
Dataset e Columns
Risoluzione delle query

<<< Risoluzione delle query

Nella fase di providing un dataset interroga un database (o legge un file) caricando i dati in memoria; nella fase di resolving invece si salvano le modifiche indietro nel database. La fase di resolving è più complessa del providing, e comprende un certo lavoro che viene svolto “dietro le quinte”. Quando l’utente modifica il dataset, per esempio tramite una interfaccia utente, il dataset tiene traccia di tutte le modifiche fatte. Quando causa il salvataggio delle modifiche (il modo canonico è invocare il metodo DataSet.saveChanges()), vengono generati i comandi SQL necessari per riportare i cambiamenti indietro nel database. La cosa importante da capire è che questo non è sempre possibile. Vediamo di capire che cosa succede esaminando il caso di una query SQL. Se costruiamo, per esempio, un QueryDataset con query SELECT NOME, INDIRIZZO FROM AGENDA, non è detto che il dataset sia in grado di aggiornare il database. Il problema principale sono le chiavi primarie. Se modifico il campo NOME di un record, per aggiornare il database è necessario utilizzare qualcosa come UPDATE AGENDA SET NOME = ‘nuovonome’ WHERE ID = 123. Notare che ho aggiunto un WHERE ID=123: una clausola come questa è necessaria per individuare dove deve avvenire l’aggiornamento. Quando si specifica una query come proprietà di un dataset, se la query non contiene abbastanza informazioni per l’aggiornamento, JBuilder tenta di modificarla per aggiungere abbastanza informazioni da riuscire a riportare indietro le modifiche nel database: tipicamente aggiunge nella SELECT un campo chiave primaria, se c’è nella tabella. Per questo motivo è buona norma avere in ogni tabella una chiave primaria, e effettuare delle SELECT che includano la chiave primaria. Se il dataset non riesce a modificare la query opportunamente (per esempio perché la tabella comprende alcuna chiave primaria) il DataSet risultante sarà in sola lettura.

Il processo di risoluzione di una query può essere personalizzato utilizzando un apposito componente resolver. I dataset infatti hanno una proprietà resolver che serve a collegarli ad un componente di questo tipo. I resolver sono event driven: infatti vengono chiamati i loro event handler nelle fasi cruciali di risoluzione della query. Consideriamo il caso di un QueryResolver che gestisce la risoluzione di una query SQL. Il resolver viene invocato prima e dopo le operazioni di inserzione, aggiornamento e cancellazione di righe, e in caso di errore. Facciamo un esempio di uso del resolver; supponiamo di voler evitare che un utente non autorizzato cancelli delle righe da un database. Possiamo ottenere questo risultato semplicemente aggiungendo un resolver, collegandolo al dataset e gestiendo l’evento deletingRow come segue:

void resolver_deletingRow(
  ReadWriteRow readWriteRow, 
  ResolverResponse resolverResponse
) throws DataSetException {
  if(<UTENTE_NON_AUTORIZZATO>) 
    resolverResponse.skip();
  else 
    resolverResponse.resolve();
}


L’event handler verrà chiamato prima di eseguire l’operazione, e il resolver potrà dire al dataset di ignorare l’operazione (skip) se l’utente non è autorizzato, oppure di eseguirla (resolve). Un’altra possibile risposta è abort() per interrompere la risoluzione. I resolver sono indicati oltre che per intervenire in casi come questo, anche per gestire errori o eseguire operazioni contemporanee all’aggiornamento del database.

ePrometeus s.r.l. - Web Software House & Open Source System Integrator
MILANO - SAN BENEDETTO DEL TRONTO(AP)
Contatti: info@eprometeus.com