FMDB - SLC-Cocoaheads

1,947 views

Published on

Short intro to FMDB, an Objective-C API or SQLite.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,947
On SlideShare
0
From Embeds
0
Number of Embeds
134
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

FMDB - SLC-Cocoaheads

  1. 1. FMDB <ul><li>SLC Cocoaheads, November 2011 </li></ul><ul><li>@dnstevenson </li></ul>
  2. 4. - ( NSMutableArray *) getStates{ NSMutableArray *states = [[ NSMutableArray alloc ] init ]; NSString *query = @&quot;SELECT id, name, latitude, longitude FROM states&quot; ; sqlite3_stmt *statement; int result = ( sqlite3_prepare_v2 ( database , [query UTF8String ], - 1 , &statement, nil )); if (result == SQLITE_OK ) { while ( sqlite3_step (statement) == SQLITE_ROW ) { State *state = [[ State alloc ] initWithId : sqlite3_column_int (statement, 0 ) withName :[ self checkForNull :( char *) sqlite3_column_text (statement, 1 )] withLatitude :[ self checkForNull :( char *) sqlite3_column_text (statement, 2 )] withLongitude :[ self checkForNull :( char *) sqlite3_column_text (statement, 3 )]]; [states addObject :state]; [state release ]; } sqlite3_finalize (statement); } return states; }
  3. 5. - ( NSMutableArray *) getStates { NSMutableArray *states = [[ NSMutableArray alloc ] init ]; NSString *query = @&quot;SELECT id, name, latitude, longitude FROM states&quot; ; FMResultSet *rs = [db executeQuery :query]; while ([rs next ]) { State *state = [[ State alloc ] initWithId :[rs intForColumnIndex : 0 ] withName :[rs stringForColumnIndex : 1 ] withLatitude :[rs stringForColumnIndex : 2 ] withLongitude :[rs stringForColumnIndex : 3 ]]; [states addObject :state]; [state release ]; } [rs close ]; return states; }
  4. 6. FMDB <ul><li>Makes working with SQLite C APIs bearable </li></ul><ul><li>It’s not an ORM framework </li></ul><ul><li>Works on iOS and Mac </li></ul>
  5. 7. Do This [db executeUpdate : @&quot;insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)&quot; , @&quot;hi'&quot; , // look! I put in a ', and I'm not escaping it! @&quot;number 10&quot; , [ NSNumber numberWithInt :i], [ NSDate date ], [ NSNumber numberWithFloat : 2.2f ]];
  6. 8. Not This char *errorMsg; char *update = &quot;INSERT INTO favorites (object_id) VALUES (?);&quot; ; sqlite3_stmt *stmt; if ( sqlite3_prepare_v2 ( database , update, - 1 , &stmt, nil ) == SQLITE_OK ) { sqlite3_bind_int (stmt, 1 , objectID); } if ( sqlite3_step (stmt) != SQLITE_DONE ) { NSAssert1 ( 0 , @&quot;Error updating table: %s&quot; , &errorMsg); } sqlite3_finalize (stmt);
  7. 10. Baby Steps <ul><li>Open Database: </li></ul><ul><ul><li>FMDatabase *db = [ FMDatabase databaseWithPath : @&quot;/tmp/tmp.db&quot; ] </li></ul></ul><ul><li>Do Something </li></ul><ul><ul><li>[db executeUpdate : @&quot;create table test (a text, b text, c integer, d double, e double)&quot; ]; </li></ul></ul><ul><ul><li>FMResultSet *rs = [db executeQuery : @&quot;select rowid,* from test where a = ?&quot; , @&quot;hi'&quot; ]; </li></ul></ul><ul><ul><li>NSString *a = [rs stringForColumnIndex : 0 ]; </li></ul></ul>
  8. 11. First Step <ul><li>Need to copy db from bundle to disk </li></ul><ul><ul><li>- ( NSString *) dbFilePath { </li></ul></ul><ul><li>// Check if the database already exists and if not, copy it over </li></ul><ul><li>NSFileManager *fileManager = [ NSFileManager defaultManager ]; </li></ul><ul><li>NSArray *paths = NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ); </li></ul><ul><li>NSString *documentsDirectory = [paths objectAtIndex : 0 ]; </li></ul><ul><li>NSString *dbFile = [documentsDirectory stringByAppendingPathComponent : @&quot;user_data.sql3&quot; ]; </li></ul><ul><li>NSError *error; </li></ul><ul><li>if ([fileManager fileExistsAtPath :dbFile] == NO ) { </li></ul><ul><li>NSString *pathToDefaultDB = [[ NSBundle mainBundle ] pathForResource : @&quot;user_data&quot; ofType : @&quot;sql3&quot; ]; </li></ul><ul><li>if ([fileManager copyItemAtPath :pathToDefaultDB toPath :dbFile error :&error] == NO ) { </li></ul><ul><li>NSAssert1 ( 0 , @&quot;Failed to copy data with error message '%@'.&quot; , [error localizedDescription]); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>return dbFile; </li></ul><ul><li>} </li></ul>
  9. 12. Next Steps <ul><li>Now you have a good path for: </li></ul><ul><ul><li>FMDatabase *db = [ FMDatabase databaseWithPath :[ self dbFilePath ]]; </li></ul></ul><ul><li>Open the db: </li></ul><ul><ul><li>[db open ]; </li></ul></ul>
  10. 13. Selecting Records FMResultSet *rs = [db executeQuery : @&quot;select * from test where a = ?&quot; , @&quot;hi’&quot; ]; while ([rs next ]) { NSLog ( @&quot;%d %@ %@ %f&quot; , [rs intForColumn : @&quot;c&quot; ], [rs stringForColumn : @&quot;b&quot; ], [rs dateForColumn : @&quot;d&quot; ], [rs doubleForColumn : @&quot;e&quot; ]); } [rs close ]; Note - the parameters passed into executeQuery are quote-safe (escaped)
  11. 14. Inserting Records int i = 0 ; while (i++ < 20 ) { [db executeUpdate : @&quot;insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)&quot; , @&quot;hi&quot; , [ NSString stringWithFormat : @&quot;number %d&quot; , i], [ NSNumber numberWithInt :i], [ NSDate date ], [ NSNumber numberWithFloat : 2.2f ]]; }
  12. 15. Reading Results <ul><li>while ([rs next ]) {} </li></ul><ul><li>[rs intForColumnIndex : 0 ] </li></ul><ul><li>[rs stringForColumnIndex : 1 ] </li></ul><ul><li>[rs stringForColumn : @&quot;scientific_name&quot; ]; </li></ul><ul><li>[rs doubleForColumnIndex : 1 ]; </li></ul><ul><li>[rs dataForColumnIndex : 1 ]; </li></ul><ul><li>[rs boolForColumnIndex : 1 ]; </li></ul><ul><li>[rs longForColumnIndex : 0 ]; </li></ul><ul><li>[rs objectForColumnIndex : 1 ]; </li></ul><ul><li>[rs columnIndexIsNull : 1 ]; </li></ul><ul><li>[rs close ]; </li></ul>
  13. 16. Transactions <ul><li>[db beginTransaction ]; </li></ul><ul><ul><ul><li><< some insertions >> </li></ul></ul></ul><ul><li>[db commit ]; </li></ul>Checking For Errors if ([db hadError ]) { NSLog ( @&quot;Err %d: %@&quot; , [db lastErrorCode ], [db lastErrorMessage ]); }
  14. 17. DEMO
  15. 19. More Info <ul><li>FMDB - https://github.com/ccgus/fmdb </li></ul><ul><ul><li>fmdb.m includes lots of examples </li></ul></ul><ul><li>Demo Code on GitHub - https://github.com/dnstevenson/US-Landmarks </li></ul><ul><li>Ask Me for Help on Twitter: @dnstevenson </li></ul>

×