Utilizzare SQLite Con il Cpp
From UIC
SqliteClass Usiamo SQLite con il c++
Contents |
| Infos | |
|---|---|
| Author: | Pnluck |
| Email: | pnluck@virgilio.it |
| Website: | http://pnluck.netsons.org |
| Date: | 06/10/2005 (dd/mm/yyyy) |
| Level: |
|
| Language: | Italian |
| Comments: | |
Introduzione
In questo articolo mostrerò come utilizzare SQLite tramite SqliteClass, un wrapper creato da Gianni Rossi e da me; vi mostrerò come creare un nuovo db, inserire e prelevare i field, etc...
PS: La lettura del tute richiede una conoscenza base dei comandi SQL.
Ristrutturato il 12/04/2007 da ValerioSoft
Tools usati
- Compilatore c++ (io ho usato il devcpp)
- SqliteClass
- SQLite
Essay
Per prima cosa, iniziamo dall'installazione dei componenti sui compilatori:
- Devcpp: Nel menu "Strumenti->Cerca Aggiornamenti", poi nella finestra cerchiamo tra i pacchetti sqlite3 e installiamolo.
- Visual c: Scaricate dal sito di SQLite lo zip con la dll e il file def, estraeli in una cartella e in conosole portiamoci in questa cartella e digitiamo "lib /def:sqlite.def", così ci ritroviamo un bel file sqlite.lib.
- SqliteClass: Basta estrarre lo zip nella cartella dove si vuol sviluppare un progetto.
Iniziamo col coding. Creamo un nuovo progratto c++, per poi nel devcpp aggiungere cm opzioni di linking: -lsqlite3, il file SqliteClass.a; mentre nel vc basta aggiungere cm dipendenza sqlite.lib e SqliteClass.a, ed infine inseriamo nella cartella sqlite.dll (servirà per le import). Ora inseriamo un nuovo file c++
//dico al compilatore di usare questo header
#include "SqliteConnection.h"
using namespace std;
//e di usare il namespace SqliteClass
using namespace SqliteClass;
int main()
{
//puntatore alla classe che serve per la connessione ad un db
SqliteConnection* aConn;
//alloca dinamicamente l'oggeto SqliteConnection
aConn = new SqliteConnection();
//Open(char*) se è presente apre il database, altrimenti lo crea
aConn->Open("test.sqlite3");
//Ora creamo una nuova tabella
try
{
//BeginTrans è usato per effetture i cambiamenti direttamente su file e non in memoria
aConn->BeginTrans();
//Execute(string): permette di usare i comandi sql
aConn->Execute("create table MiaTabella values(field1 text, field2 text)");
aConn->Execute("insert into MiaTabella (field1,field2) values ('ciao','bello')");
//Chiudiamo la transizione
aConn->CommitTrans();
}
catch (...)
{
cout << "Si è verificato un errore";
}
//Close(); chiude la connessione al databse
aConn->Close();
delete aConn;
system("PAUSE");
return 0;
}
Nel codice precedente abbiamo usato solo tre finzioni messe a disposizione dal wrapper(oltre a BeginTrans e CommintTrans): Open per creare un databese, Execute per creare una tabella ed inserirgli dei valori e Close per chiudere la connessione.
Il wrapper supporta due modi d'uso di Execute : Execute(string) e Execute(string, RecordSet). Il secondo modo serve quando si effettua un comando sql che ci deve restituire dei valori (es "select") e RecordSet è l'oggetto che andrà a contenere i record ricavati.
//dico al compilatore di usare questo header
#include "SqliteConnection.h"
using namespace std;
//e di usare il namespace SqliteClass
using namespace SqliteClass;
//Funzione che stampa a video gli errori
void printexception(SqliteException ex)
{
cout << "\nAN ERROR HAS OCCOURS...." << "\n" ;
cout << "STATEMENT : " << ex.GetStatement() << "\n" ;
cout << "ERROR NUMBER : " << ex.GetErrNumber() << "\n";
cout << "ERROR DESCRIPTION : " << ex.GetErrDescription() << "\n\n\n" ;
}
int main()
{
//puntatore alla classe per la connessione al db
SqliteConnection* aConn;
//Puntatore alla classe che andrà a contenere i Record
SqliteRecordSet* aRecordSet;
//alloca dinamicamente l'oggeto SqliteConnection
aConn = new SqliteConnection();
//Open(char*) se è presente apre il database, altrimenti lo crea
aConn->Open("test.sqlite3");
//Ora creamo una nuova tabella
try
{
//Execute(string,SqliteRecord)
aConn->Execute("select * from test",aRecordSet);
}
catch (...)
{
printexception(ex);
}
//###Ora andiamo prelevare tutti i record prelevati###
//IsEmpty verifica se sono stati prelevati dei record
if (!aRecordSet->IsEmpty())
{
//MoveFirst ci fa posizionare al primo record prelevato
aRecordSet->MoveFirst();
//Il ciclo avviene finchè non arriviamo all'ultimo record
while (!aRecordSet->EndOfRecordSet)
{
try
{
//FildValue(n) preleva il valore contenuto nella colonna
cout << aRecordSet->FieldValue(0) << " ";
cout << aRecordSet->FieldValue(1) << "\n";
} catch (SqliteException ex) { printexception(ex); }
//MoveNext ci sposta al prossimo record
aRecordSet->MoveNext();
}
}
else
{
cout << "No records found!!\n";
}
//Close(); chiude la connessione al databse
aConn->Close();
delete aConn;
system("PAUSE");
return 0;
}
Con questo codice apriamo il db precedentemente creato ed stampiamo a video tutti i suoi record. Le funzioni usate le ho già spigate nel source, vi informo solo che alla funzione FieldValue oltre ad int, si può passare anche il nome del field se lo conosciamo (in string). Ora vi mostro alcune funzioni che vi posso semplificare la vita, nel qual caso non sappiate il numero di field presenti:
for(int i=0;i < aRecordSet->ColumnsCount(); i++) { aRecordSet->FieldValue(i); }
Oltre a MoveNext e MoveFirst vi sono anche: MovePrev, MoveLast e MoveTo(n).
Come vedete è intuibile l'uso di ogni funzione messaci a disposizione dal Wrapper, cmq vi sono altre funzione non menzionate in questo breve articolo che servono ad effettuare il dump del database su file, la rimozione di una colonna da un tabella, ed alcune funzioni molto interessanti, qualora non si sappia la struttura del db (tipo numero e nomi delle tabelle presenti), e si voglia comunque aprirlo ed usarlo: GetTableInfo e AllTable. La lista di tutte le funzioni è al sito ed alcuni esempi al forum, oppure vi potete spulciare i file .h del wrapper :D
Note finali
Come vedete il wrapper è semplice ma allo stesso tempo ha funzioni molto avanzate.
Ringrazio Gianni per avermi permesso di sviluppare il wrapper con lui, e poi tutti quelli di Pmode e della Uic .
Disclaimer
I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.
Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.