In questo articolo vedremo come muovere i primi passi nell’utilizzo del noto motore db SQLite all’interno delle nostre applicazioni iPad / iPhone.
Nota.Per iniziare sarà necessario importare la libreria nativa “libsqlite3.dylib” al nostro progetto, e per farlo basta posizionarsi, in XCode, sul folder “Framework” e aggiungere il framework esistente denominato libsqlite3.dylib, che non è nient’altro che un link alla versione più recente della libreria SQLite presente sul vostro dispositivo.
Nell’header file del controller (partiamo sempre dal View – Based template di XCode) imortiuamo l’headerfile di di sqlite e definiamo una variabile riferita al nostro database SQLite e un metodo che ci restituisca il percorso del nostro db (ci riferiamo sempre alla cartella Documenti) come segue:
#import <UIKit/UIKit.h>
#import “sqlite3.h”
@interface databasesViewController : UIViewController {
sqlite3 *db;
}
-(NSString *) filePath;
@end
Nel file implementazione del controller avremo scriveremo i seguenti metodi per accedere al db:
// Recupera il percorso del file all’interno della cartella documenti
-(NSString *) filePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:@"database.sql"];
}
-(void) openDB {
//—creiamo o aprimo il database—
if (sqlite3_open([[self filePath] UTF8String], &db) != SQLITE_OK ) {
sqlite3_close(db);
NSAssert(0, @”Errore apertura DB.”);
}
}
-(void) createTableNamed:(NSString *) tableName
withField1:(NSString *) field1
withField2:(NSString *) field2 {
char *err;
NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('%@' TEXT PRIMARY KEY, '%@' TEXT);",tableName, field1, field2];
// Se non esiste crea la tabella indicata in tableName con i campi field1 e field2 (di tipo testo)
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) {
sqlite3_close(db);
NSAssert(0, @”Errore nella creazione della tabella.”);
}
}
// procedura inserimento Record nella tabella “tableName” nei campi field1 e field2
-(void) insertRecordIntoTableNamed:(NSString *) tableName
withField1:(NSString *) field1
field1Value:(NSString *) field1Value
andField2:(NSString *) field2
field2Value:(NSString *) field2Value {
NSString *sql = [NSString stringWithFormat:
@"INSERT OR REPLACE INTO '%@' ('%@', '%@') VALUES ('%@','%@')",tableName, field1, field2, field1Value, field2Value];
char *err;
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) {
sqlite3_close(db);
NSAssert(0, @”Errore Aggiornamento Tabella”);
}
}
// Procedura di recupero record dalla tabella “tableName”
-(void) getAllRowsFromTableNamed: (NSString *) tableName {
//—recuperiamo le nostre rows—
NSString *qsql = @”SELECT * FROM CONTACTS”;
sqlite3_stmt *statement;
if (sqlite3_prepare_v2( db, [qsql UTF8String], -1, &statement, nil) == SQLITE_OK) {
// Cicliamo nel loop per recuperare tutte le righe
while (sqlite3_step(statement) == SQLITE_ROW) {
char *field1 = (char *) sqlite3_column_text(statement, 0);
NSString *field1Str = [[NSString alloc] initWithUTF8String: field1];
char *field2 = (char *) sqlite3_column_text(statement, 1);
NSString *field2Str = [[NSString alloc] initWithUTF8String: field2];
NSString *str = [[NSString alloc] initWithFormat:@”%@ – %@”,field1Str, field2Str];
// Stampiano nella consolle la stringa formattata
NSLog(@”%@”,str);
// Liberiamo memoria
[field1Str release];
[field2Str release];
[str release];
}
//— Cancelliamo l’istruzione compilata SQLIte dalla memoria—
sqlite3_finalize(statement);
}
}
Ora per provare il tutto, nel delegate “viewDidLoad” del controller, chiamiamo in sequenza e analizziamo i messaggi mostrati da NSLog:
- (void)viewDidLoad {
// Apre il DB o lo crea
[self openDB];
// Crea la Tabella se non esiste
[self createTableNamed:@"Contacts" withField1:@"email" withField2:@"name"];
//effettua inserimento di 2 record
for (int i=0; i<=2; i++) {
NSString *email = [[NSString alloc] initWithFormat:@”user%d@laziomatica.com”,i];
NSString *name = [[NSString alloc] initWithFormat: @”user %d”,i];
[self insertRecordIntoTableNamed:@"Contacts" withField1:@"email" field1Value:email andField2:@"name" field2Value:name];
[email release];
[name release];
}
// Effettua il recupero dei record
[self getAllRowsFromTableNamed:@"Contacts" ];
sqlite3_close(db);
[super viewDidLoad];
}
Al fine di monitorare il comportamento delle istruzioni eseguite dalla libreria SQLite, di seguito sono riportate le codifiche dei “Result Code” definite nell’interfaccia C della libreria SQLite come riportato sul sito ufficiale http://www.sqlite.org/c3ref/c_abort.html
#define SQLITE_OK 0 /* Successful result */
#define SQLITE_ERROR 1 /* SQL error or missing database */
#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
#define SQLITE_PERM 3 /* Access permission denied */
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
#define SQLITE_BUSY 5 /* The database file is locked */
#define SQLITE_LOCKED 6 /* A table in the database is locked */
#define SQLITE_NOMEM 7 /* A malloc() failed */
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */
#define SQLITE_EMPTY 16 /* Database is empty */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
#define SQLITE_MISMATCH 20 /* Data type mismatch */
#define SQLITE_MISUSE 21 /* Library used incorrectly */
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
#define SQLITE_AUTH 23 /* Authorization denied */
#define SQLITE_FORMAT 24 /* Auxiliary database format error */
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
Al prossimo articolo…..