Skip to content

Set of block functions to wrap common SQLite operations on iOS in Objective-c

License

Notifications You must be signed in to change notification settings

nick22dev/SQLiteQueryUtil

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 

Repository files navigation

SQLiteQueryUtil

Set of block functions to wrap common SQLite operations on iOS in Objective-c

Dependencies: libsqlite3.dylib

(libsqlite3 is included in Xcode's iOS distribution. Select this lib from Xcode Project->Build Phases->Link Binary With Libraries)

example: init

NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSString *databasePath = [[docsDir stringByAppendingPathComponent:@"database"] stringByAppendingPathExtension:@"sqlite"];

SQLiteQueryUtil *queryUtil = [[SQLiteQueryUtil alloc] initWithDBPath:databasePath];

example: select

/* init SQLiteQueryUtil queryUtil instance with database path */

sqlite3_int64 fooIdToQuery = 100;
__block NSMutableArray *foos = nil;

NSString *query = @"select id,name from foo where id=?;";

[queryUtil queryDB:query withBindParamsCallback:^(sqlite3_stmt *queryStatement) {

    sqlite3_bind_int64(queryStatement, 1, fooIdToQuery); // bind params start at 1

} onNextRowCallback:^(sqlite3_stmt *queryStatement, NSUInteger currentRow) {
    if(currentRow == 0) {
        foos = [[NSMutableArray alloc] init];
    }

    sqlite_int64 fooId = sqlite3_column_int64(queryStatement, 0); // column results start at 0
    const unsigned char *fooNameChars = sqlite3_column_text(queryStatement, 1);

    NSString *fooName = fooNameChars != NULL ? [[NSString alloc] initWithUTF8String:fooNameChars] : nil;

    Foo *nextFoo = [[Foo alloc] init];
    nextFoo.id = fooId;
    nextFoo.name = fooName;

    [foos addObject:nextFoo];

} onQueryCompleteCallack:^{ }];

example: insert

/* init SQLiteQueryUtil queryUtil instance with database path */

__block sqlite3_int64 insertResultId = -1;
NSString *nameToInsert = "mike";

NSString *query = @"insert into foo (name) values(?);";

[queryUtil writeQueryInDB:insertSQL withBindParamsCallback:^(sqlite3_stmt *queryStatement) {
    sqlite3_bind_text(queryStatement, 1, [nameToInsert UTF8String], -1, SQLITE_TRANSIENT); // bind params start at 1
} onNextRowCallback:^(sqlite3_stmt *queryStatement, NSUInteger currentRow) {
    insertResultId = sqlite3_last_insert_rowid(database);
} onQueryCompleteCallack:^{ }];

example: delete

/* init SQLiteQueryUtil queryUtil instance with database path */

__block BOOL success = NO;
sqlite3_int64 idToDelete = 100;

NSString *query = @"delete from foo where id=?;";

[queryUtil writeQueryInDB:insertSQL withBindParamsCallback:^(sqlite3_stmt *queryStatement) {
    sqlite3_bind_int64(queryStatement, 1, idToDelete); // bind params start at 1
} onNextRowCallback:^(sqlite3_stmt *queryStatement, NSUInteger currentRow) {
    success = YES;
} onQueryCompleteCallack:^{ }];

example: transaction (multiple deletes atomically)

/* init SQLiteQueryUtil queryUtil instance with database path */

[self.queryUtil writeTransactionWithOperations:@[^BOOL(sqlite3 *db, NSMutableDictionary *contextData) {
    __block BOOL success = NO;
    /* see delete example */
    return success;
},^BOOL(sqlite3 *db, NSMutableDictionary *contextData) {
    __block BOOL success = NO;
    /* delete from index table by id */
    return success;
}]];

example: migration (add an index)

/* init SQLiteQueryUtil queryUtil instance with database path */

int32_t currentdbVersion = [queryUtil dbVersion];

int32_t rollbackDBVersion = 1;
int32_t targetDBVersion = 2;

__block sqlite3 *transactionDBConn = nil;
int openResult = [queryUtil openDBReadWrite:&transactionDBConn];

NSString *foo_name_index_create_sql_stmtString = "create index if not exists foo_name_index on foo(name);"

[queryUtil migrate:^BOOL{
    return currentdbVersion == 1 && openResult == SQLITE_OK;
} migrate:^{
    NSLog(@"[SQLITE_MIGRATOR] Migration from v%d to v%d", currentdbVersion, targetDBVersion);
    [queryUtil writeQueryInDB:foo_name_index_create_sql_stmtString withDB:&transactionDBConn withBindParamsCallback:nil onNextRowCallback:nil onQueryCompleteCallack:nil];
    
    // update the db user version so we know migration was successful going forward
    [queryUtil setdbVersion:targetDBVersion withDB:&transactionDBConn];
    
} didMigrationSucceed:^BOOL{
    return YES;
} rollback:^{
    NSLog(@"[SQLITE_MIGRATOR] Migration Rollback to v%d", rollbackDBVersion);
    
    if (sqlite3_exec(transactionDBConn, "ROLLBACK;", 0, 0, 0) != SQLITE_OK) {
        NSLog(@"[SQLITE_MIGRATOR] SQL Error: %s",sqlite3_errmsg(transactionDBConn));
    }
    [queryUtil setdbVersion:rollbackDBVersion withDB:&transactionDBConn];
} onMigrationComplete:^(BOOL didComplete) {
    int closeResult = sqlite3_close(transactionDBConn);
    if(closeResult != SQLITE_OK) {
        NSLog(@"[SQLITE] Error failed to close db %d %s", closeResult, sqlite3_errmsg(transactionDBConn));
    }
    NSLog(@"[SQLITE_MIGRATOR] Migration from v%d to v%d %@",currentdbVersion, targetDBVersion, didComplete ? @"SUCCESS" : @"FAIL");
}

About

Set of block functions to wrap common SQLite operations on iOS in Objective-c

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published