SqliteClass Usiamo
SQLite con il c++
|
Data
|
by "Pnluck"
|
|
06/10/05
|
UIC's Home Page
|
Published by Quequero
|
Si prega la gentile clientela di donare qualcosa alla UIC
|
Bello il wrapper!
|
Si prega la gentile clientela di donare qualcosa alla UIC
|
....
|
- Home page (se
presente): http://pnluck.altervista.org
- E-mail: [email protected]
- Nick, UIN, canale
IRC/EFnet frequentato
|
....
|
Difficoltà
|
(x)NewBies (x)Intermedio (x)Avanzato (x)Master
|
|
- 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.
- Compilatore
c++ (io ho usato il devcpp)
- SqliteClass
- SQLite
- 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++
-
-
-
#include <iostream>
//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.
- #include <iostream>
//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:
ColumnsCount(): restituisce il numero di field. Ecco un esempio che può essere usato nel ciclo while:
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
- Pnluck
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 .
Vorrei
ricordare che il software va comprato e non rubato, dovete
registrare il vostro prodotto dopo il periodo di valutazione. Non mi
ritengo responsabile per eventuali danni causati al vostro computer
determinati dall'uso improprio di questo tutorial. Questo documento
è stato scritto per invogliare il consumatore a registrare
legalmente i propri programmi, e non a fargli fare uso dei tantissimi
file crack presenti in rete, infatti tale documento aiuta a comprendere
lo sforzo che ogni sviluppatore ha dovuto portare avanti per fornire ai
rispettivi consumatori i migliori prodotti possibili.
Reversiamo
al solo scopo informativo e per migliorare la nostra conoscenza del
linguaggio Assembly.