DATABASE - gestione mediante Microsoft ODBC Quando i dati da trattare diventano numerosi, bisogna schierare le "armate pesanti", cioè mettere in pratica tutto ciò che si è imparato sugli strumenti di connettività ai Database. È molto importante averne almeno i principali rudimenti. Non penserete di usare i file ad accesso random a vita! La serializzazione descritta nei precedenti articoli, cioè il processo che consente di memorizzare dentro un file un oggetto documento completo per poi ripristinarlo in un secondo momento, può essere vista come una forma "elementare" di archiviazione. I dati del documento vengono infatti passati dalla memoria al file ogni qual volta è necessario: all'apertura avviene il caricamento degli oggetti nella memoria virtuale e si ha il passaggio inverso alla chiusura per scrivere su file i dati aggiornati. Estendendo il concetto è possibile sfruttare il meccanismo per tenere una "collezione" di informazioni sempre a disposizione per l'applicazione. Possiamo ad esempio pensare di costruire un'agenda telefonica che quando è in esecuzione usi un vettore di record (oggetti contenenti il nome, il cognome, il numero di telefono, etc etc dei contatti) ordinato, e volendo "indicizzato" quando è possibile, per poter accedere rapidamente ai nominativi. Quando si vuole chiudere il programma, per non perdere i dati li si deve memorizzare da qualche parte. La prima cosa che viene in mente è di utilizzare il meccanismo di serializzazione; tutti i dati vengono tenuti in memoria di esecuzione quando l'applicazione li richiede per poi rimanare "aggiornati" all'interno dell'archivio di supporto. Beh, questa non è certamente la soluzione ottimale ma in questo caso potrebbe anche andare bene. Perché? La serializzazione adotta uno stile sequenziale per l'inserimento dei dati e per la loro estrazione: per poter accedere a un determinato record è quindi necessario scandire tutto il contenuto che lo precede. Quindi, se la ricerca viene effettuata in memoria di esecuzione è un discorso diverso dal caso di una ricerca diretta sull'archivio. Infatti, se si riesce ad implementare un sistema di indici per ridurre il costo di accesso, la ricerca diventa più veloce e meno onerosa in termini di risorse usate. Finché i dati trattati sono pochi, l'uso di un vettore in memoria può risultare conveniente, ma che succede se la mole aumenta? Parte della RAM verrebbe sottratta all'esecuzione per poter contenere tutti i record e le strutture di supporto usate per la ricerca "indicizzata". È quindi evidente che questa scelta non è sempre fattibile, quindi bisogna orientarsi verso altre soluzioni, come ad esempio i DataBase Management System (DBMS) cioè i gestori delle basi di dati. Quello che una base di dati fornisce è un supporto di archiviazione su disco con la potenzialità dell'indicizzazione e non solo. Vantaggi dei DBMS Per prima cosa questi sistemi di archiviazione consentono di accedere rapidamente ai dati attraverso indici di ricerca basati su chiavi, cioè valori univoci, con il risultato di velocizzare gli accessi e i recuperi. Un'altra proprietà non di poco conto è l'utilizzo di formati standard per implementare gli archivi seguendo un unico standard: l'indubbio vantaggio è quello che varie piattaforme di basi di dati hanno strumenti con il quale effettuare il passaggio da un formato ad un altro, dando quindi la possibilità di aprire l'archivio con programmi differenti. Un aspetto che ancora non è stato preso in considerazione è quello dell'integrità e della sicurezza dei dati contenuti. Molti DBMS commerciali garantiscono la corretta elaborazione della sequenza di operazioni richieste. Il motivo? Se una sequenza non può per qualche motivo essere eseguita completamente, viene annullata nel punto in cui si è bloccata e si torna indietro ripristinando lo stato precedente dei dati, preservando l'intregrità dell'archivio. Alla luce di tutto questo, provate ad implementare un DBMS personalizzato su file con le stesse proprietà! La mole di lavoro sarebbe veramente eccessiva, distogliendo risorse dallo sviluppo del resto dell'applicazione. Dal canto suo, Visual C++ ha tutti gli strumenti necessari per garantire lo sviluppo di applicazioni con accesso ai database. Visual C++ adotta due metodi principali per realizzare la connettività client a database, l'ODBC e il DAO. Open DataBase Connectivity L'Open DataBase Connectivity (ODBC) è uno standard Microsoft usato per l'accesso ai dati sfruttando come base l'SQL, in modo da garantire la comunicazione con gli RDBMS che operano in ambiente Windows. La sua potenzialità viene espressa attraverso un'API con cui poter accedere indifferentemente a sorgenti di dati in modalità client/server. Se ad esempio si dispone di un programma di accesso ai dati in un database SQL, l'ODBC consente l'utilizzo dello stesso programma per accedere ai dati in un database ad esempio Visual FoxPro. L'ODBC estrae in effetti l'interfaccia di programmazione delle applicazioni dalla natura stessa del DB che si sta utilizzando. Infatti, basando l'interfacciamento su di un linguaggio standard (come appunto è l'SQL) è possibile sviluppare applicazioni anche sofisticate senza doversi legare a un DBMS relazionale specifico. In questo modo, un'applicazione client/server funziona senza sapere cosa c'è esattamente "sotto" come archivio, né tanto meno dove sono dislocati questi dati. Quello che si ottiene è quindi un'interoperabilità tra piattaforme server eterogenee a cui l'applicazione può accedere. La connettività con la base di dati è supportata da opportuni driver che hanno il compito di eseguire le istruzioni SQL che stiamo inviando. Naturalmente ogni sviluppatore ha rilasciato una piattaforma DBMS relazionale usando una diversa "interpretazione" del set di funzioni. Ci possono essere quindi delle differenze sostanziali tra un'interfaccia e l'altra, dovute anche dal modo con cui vengono sviluppati i driver ODBC. Per questo motivo è stato necessario stabilire quali funzioni un driver ODBC deve necessariamente fornire: questo insieme di funzioni prende il nome di Conformità Core. Esistono diversi modi con cui un'applicazione può realizzare la connettività con un database. Generalmente viene definito una sorta di ponte tra l'applicazione e il database ODBC sfruttando il driver gestore; questo supporto prende il nome di Data Source Name o DSN. Un DSN è un insieme di informazioni "uniche" nel sistema in cui è stato registrato che può essere memorizzato su di un file (DSN su file), inserito nel registro di configurazione di Windows (DSN di sistema). Vediamo un po' come è possibile recuperare dei dati usando il modello ODBC. L'applicazione invia una particolare istruzione scritta in SQL all'interfaccia del driver gestore della sorgente dei dati (questo è un modo alternativo di definire il database); questi effettua la conversione della richiesta in un formato consono al DBMS e la rinvia al server e attende la risposta che verranno poi passati all'applicazione originaria. MFC Tra le librerie Microsoft Foundation Class sono disponibili due differenti gruppi di classi per gestire la connettività con i database, uno per ciascun modello appena visto. La scelta tra DAO e ODBC dipende dall'obiettivo da raggiungere: spesso, per applicazioni di tipo desktop si preferisce usare il primo e limitare il secondo al collegamento con database remoti tramite DSN. In effetti limitare il modello ODBC ai soli collegamenti remoti va contro allo scopo per il quale è stato sviluppato, cioè l'indipendenza (seppur limitata) dall'implementazione dell'RDBMS. Generare una connessione La prima operazione per creare un accesso al database è stabilire una connessione. Per fare ciò bisogna operare in due fasi: nella prima si deve creare un oggetto del database per poi "aprire" la connessione con esso. Le classi interessate sono CDatabase per ODBC e CDaoDatabase per DAO; il modo in cui operano è diverso: CDatabase::Open() richiede una stringa di connessione o l'indicazione di un DSN registrato, mentre CDaoDatabase::Open() invece ha bisogno del percorso relativo a un file "fisico" corrispondente alla sorgente dei dati. RecordView Questi oggetti vengono definiti come le classi di vista dei record. Esse vengono utilizzate per fornire uno strumento per stampare a video i record usando una finestra di dialogo. Infatti, sia CRecordView che CDaoRecordView sono derivate dalla classe CFormView che definisce una'area client basata su un modello a finestra di dialogo. Si origina quindi un legame tra i controlli della finestra e le variabili membro del recordset, regolando lo scambio di dati attraverso il meccanismo DDX/DDV. Ing. Antonino Panella