SQLite Techniques

                              Ben Scheirman
                               @subdigital

               ...
SQLite is....

                 Single-user

                 File-based

                 Simple

                 Cross ...
SQLite API


                 Pure C API

                 Lots of strange-looking, hard to
                 debug code

 ...
SQLite Tools



                 SQLite Manager Add-in for Firefox

                 sqlite3 command line utility




Tues...
Writable Databases


                 Your app bundle is signed!

                 (That means the contents can't
        ...
Your App Sandbox




                              Your App Bundle


                                     Resources
      ...
Your App Sandbox




                              Your App Bundle


                                     Resources
      ...
Creating the
                            database


Tuesday, September 28, 2010
Getting Resource
                           Paths




Tuesday, September 28, 2010
Getting Resource
                           Paths

  //fetches	
  path	
  for	
  foo.db




Tuesday, September 28, 2010
Getting Resource
                           Paths

  //fetches	
  path	
  for	
  foo.db
  NSString	
  *resourcePath	
  =	
...
Getting Resource
                                   Paths

  //fetches	
  path	
  for	
  foo.db
  NSString	
  *resourcePat...
Getting Resource
                                   Paths

  //fetches	
  path	
  for	
  foo.db
  NSString	
  *resourcePat...
Finding the Documents
              Directory




Tuesday, September 28, 2010
Finding the Documents
              Directory

            NSArray	
  *paths	
  =	
  NSSearchPathForDirectoriesInDomains(	...
Finding the Documents
              Directory

            NSArray	
  *paths	
  =	
  NSSearchPathForDirectoriesInDomains(	...
Finding the Documents
              Directory

            NSArray	
  *paths	
  =	
  NSSearchPathForDirectoriesInDomains(	...
Finding the Documents
              Directory

            NSArray	
  *paths	
  =	
  NSSearchPathForDirectoriesInDomains(	...
Finding the Documents
              Directory

            NSArray	
  *paths	
  =	
  NSSearchPathForDirectoriesInDomains(	...
Copy a default
              database on startup




Tuesday, September 28, 2010
Copy a default
              database on startup
         //in applicationDidFinishLaunching

         NSString *sourcePat...
Copy a default
              database on startup
         //in applicationDidFinishLaunching

         NSString *sourcePat...
Copy a default
              database on startup
         //in applicationDidFinishLaunching

         NSString *sourcePat...
Copy a default
              database on startup
         //in applicationDidFinishLaunching

         NSString *sourcePat...
Copy a default
              database on startup
         //in applicationDidFinishLaunching

         NSString *sourcePat...
Copy a default
              database on startup
         //in applicationDidFinishLaunching

         NSString *sourcePat...
Copy a default
              database on startup
         //in applicationDidFinishLaunching

         NSString *sourcePat...
SQLite API Basics




Tuesday, September 28, 2010
Add the Framework




Tuesday, September 28, 2010
Add the Framework




Tuesday, September 28, 2010
Add the Framework




Tuesday, September 28, 2010
Add the Framework




Tuesday, September 28, 2010
SQLite API -
           Opening a connection




Tuesday, September 28, 2010
SQLite API -
           Opening a connection
     #import "sqlite3.h"




Tuesday, September 28, 2010
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;




Tuesday, September 28, 2010
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;

     int result = sqlite3_open(P...
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;

     int result = sqlite3_open(P...
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;

     int result = sqlite3_open(P...
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;

     int result = sqlite3_open(P...
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;

     int result = sqlite3_open(P...
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;

     int result = sqlite3_open(P...
SQLite API -
           Opening a connection
     #import "sqlite3.h"

     sqlite3 *db;

     int result = sqlite3_open(P...
SQLite API -
                   executing queries




Tuesday, September 28, 2010
SQLite API -
                   executing queries
     int sqlite3_exec(




Tuesday, September 28, 2010
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,




Tuesday, September 28, 2...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,




Tuesd...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
                   executing queries
     int sqlite3_exec(
        sqlite3 *db,
        char *sql,
        i...
SQLite API -
              Prepared Statements


           More Powerful

           Unfortunately much more code!




Tu...
SQLite API-Prepared Statements




Tuesday, September 28, 2010
SQLite API-Prepared Statements


        sqlite3 *db;




Tuesday, September 28, 2010
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);




Tuesday, Septem...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements


        sqlite3 *db;
        int result = sqlite3_open(DB_PATH, &db);
        if(result !...
SQLite API-Prepared Statements




Tuesday, September 28, 2010
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)




Tuesday, September 28, 2010
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements
      //INSERT INTO CARS(year, make) VALUES(?, ?)

      //PARAMETERS HAVE A 1-BASED INDEX!...
SQLite API-Prepared Statements




Tuesday, September 28, 2010
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {




Tuesd...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
SQLite API-Prepared Statements

-(void)processRow:(NSMutableDictionary *)row forStatement:
(sqlite3_stmt*)stmt {
  int col...
FMDB


                 http://github.com/ccgus/fmdb




Tuesday, September 28, 2010
FMDB Usage




Tuesday, September 28, 2010
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];




Tuesday, September 28, 2010
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])




Tuesda...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
FMDB Usage
           FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
           if (![db open])
          ...
What about updates?


                 Database is never copied over again

                 If we did, your customers wou...
Migrations

                 Concept from Ruby on Rails

                 Evolutionary database design

                 E...
Migrations

                              number        name
                                1      initial_schema
       ...
Migrations

                              number        name
                                1      initial_schema
       ...
Hand-rolled Database
                 Migrator


                 DEMO




Tuesday, September 28, 2010
FMDB Migration
                                  Manager


                 http://github.com/mocra/fmdb-
                ...
FMDB Migration
                                  Manager

 NSArray *migrations = [NSArray arrayWithObjects:
      [CreateS...
FMDB Migration
                                  Manager
 @interface CreateStudents : FmdbMigration
 {
 }
 @end

 @impleme...
ActiveRecord

             Person *p = [[Person alloc] init];
             p.name = @"Joe";
             p.occupation = @"...
Aptiva's ActiveRecord


                  http://github.com/aptiva/activerecord




                                 (YMMV...
Questions?




Tuesday, September 28, 2010
Upcoming SlideShare
Loading in...5
×

SQLite Techniques

1,814

Published on

Presentation by Ben Scheirman give at the september meeting of the Houston iPhone Developers Meetup (http://houstoniphone.com)

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

No Downloads
Views
Total Views
1,814
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
83
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "SQLite Techniques"

  1. 1. SQLite Techniques Ben Scheirman @subdigital Code / Slides: github.com/subdigital/iphonedevcon- sandiego Tuesday, September 28, 2010
  2. 2. SQLite is.... Single-user File-based Simple Cross Platform A subset of full ANSI SQL Tuesday, September 28, 2010
  3. 3. SQLite API Pure C API Lots of strange-looking, hard to debug code Best choice is to abstract it away Tuesday, September 28, 2010
  4. 4. SQLite Tools SQLite Manager Add-in for Firefox sqlite3 command line utility Tuesday, September 28, 2010
  5. 5. Writable Databases Your app bundle is signed! (That means the contents can't change) Tuesday, September 28, 2010
  6. 6. Your App Sandbox Your App Bundle Resources Documents Tuesday, September 28, 2010
  7. 7. Your App Sandbox Your App Bundle Resources Documents Tuesday, September 28, 2010
  8. 8. Creating the database Tuesday, September 28, 2010
  9. 9. Getting Resource Paths Tuesday, September 28, 2010
  10. 10. Getting Resource Paths //fetches  path  for  foo.db Tuesday, September 28, 2010
  11. 11. Getting Resource Paths //fetches  path  for  foo.db NSString  *resourcePath  =  [[NSBundle  mainBundle] Tuesday, September 28, 2010
  12. 12. Getting Resource Paths //fetches  path  for  foo.db NSString  *resourcePath  =  [[NSBundle  mainBundle]                                                          pathForResource:@"foo" Tuesday, September 28, 2010
  13. 13. Getting Resource Paths //fetches  path  for  foo.db NSString  *resourcePath  =  [[NSBundle  mainBundle]                                                          pathForResource:@"foo"                                                          ofType:@"db"]; Tuesday, September 28, 2010
  14. 14. Finding the Documents Directory Tuesday, September 28, 2010
  15. 15. Finding the Documents Directory NSArray  *paths  =  NSSearchPathForDirectoriesInDomains(   Tuesday, September 28, 2010
  16. 16. Finding the Documents Directory NSArray  *paths  =  NSSearchPathForDirectoriesInDomains(                                                        NSDocumentDirectory,   Tuesday, September 28, 2010
  17. 17. Finding the Documents Directory NSArray  *paths  =  NSSearchPathForDirectoriesInDomains(                                                        NSDocumentDirectory,                                                        NSUserDomainMask,   Tuesday, September 28, 2010
  18. 18. Finding the Documents Directory NSArray  *paths  =  NSSearchPathForDirectoriesInDomains(                                                        NSDocumentDirectory,                                                        NSUserDomainMask,                                                        YES); Tuesday, September 28, 2010
  19. 19. Finding the Documents Directory NSArray  *paths  =  NSSearchPathForDirectoriesInDomains(                                                        NSDocumentDirectory,                                                        NSUserDomainMask,                                                        YES); NSString  *documentsDirectory  =  [paths  objectAtIndex:0]; Tuesday, September 28, 2010
  20. 20. Copy a default database on startup Tuesday, September 28, 2010
  21. 21. Copy a default database on startup //in applicationDidFinishLaunching NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"db"]; NSString *targetPath = ... NSFileManager *fm = [NSFileManager defaultManager]; if(![fm fileExistsAtPath:targetPath]) { [fm copyItemAtPath:sourcePath toPath:targetPath error:&error]; } Tuesday, September 28, 2010
  22. 22. Copy a default database on startup //in applicationDidFinishLaunching NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"db"]; NSString *targetPath = ... NSFileManager *fm = [NSFileManager defaultManager]; if(![fm fileExistsAtPath:targetPath]) { [fm copyItemAtPath:sourcePath toPath:targetPath error:&error]; } Tuesday, September 28, 2010
  23. 23. Copy a default database on startup //in applicationDidFinishLaunching NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"db"]; NSString *targetPath = ... NSFileManager *fm = [NSFileManager defaultManager]; if(![fm fileExistsAtPath:targetPath]) { [fm copyItemAtPath:sourcePath toPath:targetPath error:&error]; } Tuesday, September 28, 2010
  24. 24. Copy a default database on startup //in applicationDidFinishLaunching NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"db"]; NSString *targetPath = ... NSFileManager *fm = [NSFileManager defaultManager]; if(![fm fileExistsAtPath:targetPath]) { [fm copyItemAtPath:sourcePath toPath:targetPath error:&error]; } Tuesday, September 28, 2010
  25. 25. Copy a default database on startup //in applicationDidFinishLaunching NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"db"]; NSString *targetPath = ... NSFileManager *fm = [NSFileManager defaultManager]; if(![fm fileExistsAtPath:targetPath]) { [fm copyItemAtPath:sourcePath toPath:targetPath error:&error]; } Tuesday, September 28, 2010
  26. 26. Copy a default database on startup //in applicationDidFinishLaunching NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"db"]; NSString *targetPath = ... NSFileManager *fm = [NSFileManager defaultManager]; if(![fm fileExistsAtPath:targetPath]) { [fm copyItemAtPath:sourcePath toPath:targetPath error:&error]; } Tuesday, September 28, 2010
  27. 27. Copy a default database on startup //in applicationDidFinishLaunching NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"db"]; NSString *targetPath = ... NSFileManager *fm = [NSFileManager defaultManager]; if(![fm fileExistsAtPath:targetPath]) { [fm copyItemAtPath:sourcePath toPath:targetPath error:&error]; } Tuesday, September 28, 2010
  28. 28. SQLite API Basics Tuesday, September 28, 2010
  29. 29. Add the Framework Tuesday, September 28, 2010
  30. 30. Add the Framework Tuesday, September 28, 2010
  31. 31. Add the Framework Tuesday, September 28, 2010
  32. 32. Add the Framework Tuesday, September 28, 2010
  33. 33. SQLite API - Opening a connection Tuesday, September 28, 2010
  34. 34. SQLite API - Opening a connection #import "sqlite3.h" Tuesday, September 28, 2010
  35. 35. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; Tuesday, September 28, 2010
  36. 36. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; int result = sqlite3_open(PATH, &db); Tuesday, September 28, 2010
  37. 37. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; int result = sqlite3_open(PATH, &db); if (result != SQLITE_OK) { Tuesday, September 28, 2010
  38. 38. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; int result = sqlite3_open(PATH, &db); if (result != SQLITE_OK) { [NSException raise:@"SQLITE ERROR" Tuesday, September 28, 2010
  39. 39. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; int result = sqlite3_open(PATH, &db); if (result != SQLITE_OK) { [NSException raise:@"SQLITE ERROR" format:@"Error %d", result]; Tuesday, September 28, 2010
  40. 40. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; int result = sqlite3_open(PATH, &db); if (result != SQLITE_OK) { [NSException raise:@"SQLITE ERROR" format:@"Error %d", result]; } Tuesday, September 28, 2010
  41. 41. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; int result = sqlite3_open(PATH, &db); if (result != SQLITE_OK) { [NSException raise:@"SQLITE ERROR" format:@"Error %d", result]; } //later Tuesday, September 28, 2010
  42. 42. SQLite API - Opening a connection #import "sqlite3.h" sqlite3 *db; int result = sqlite3_open(PATH, &db); if (result != SQLITE_OK) { [NSException raise:@"SQLITE ERROR" format:@"Error %d", result]; } //later sqlite3_close(db); Tuesday, September 28, 2010
  43. 43. SQLite API - executing queries Tuesday, September 28, 2010
  44. 44. SQLite API - executing queries int sqlite3_exec( Tuesday, September 28, 2010
  45. 45. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, Tuesday, September 28, 2010
  46. 46. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, Tuesday, September 28, 2010
  47. 47. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, Tuesday, September 28, 2010
  48. 48. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, Tuesday, September 28, 2010
  49. 49. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, char **errorMessage Tuesday, September 28, 2010
  50. 50. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, char **errorMessage ); Tuesday, September 28, 2010
  51. 51. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, char **errorMessage ); //callback signature Tuesday, September 28, 2010
  52. 52. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, char **errorMessage ); //callback signature int RowCallback(void * context, Tuesday, September 28, 2010
  53. 53. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, char **errorMessage ); //callback signature int RowCallback(void * context, int numColumns, Tuesday, September 28, 2010
  54. 54. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, char **errorMessage ); //callback signature int RowCallback(void * context, int numColumns, char** colValues, Tuesday, September 28, 2010
  55. 55. SQLite API - executing queries int sqlite3_exec( sqlite3 *db, char *sql, int (*callback)(void *, int, char**, char**) callbackFunc, void *context, char **errorMessage ); //callback signature int RowCallback(void * context, int numColumns, char** colValues, char ** colNames); Tuesday, September 28, 2010
  56. 56. SQLite API - Prepared Statements More Powerful Unfortunately much more code! Tuesday, September 28, 2010
  57. 57. SQLite API-Prepared Statements Tuesday, September 28, 2010
  58. 58. SQLite API-Prepared Statements sqlite3 *db; Tuesday, September 28, 2010
  59. 59. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); Tuesday, September 28, 2010
  60. 60. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { Tuesday, September 28, 2010
  61. 61. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error Tuesday, September 28, 2010
  62. 62. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } Tuesday, September 28, 2010
  63. 63. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } Tuesday, September 28, 2010
  64. 64. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; Tuesday, September 28, 2010
  65. 65. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); Tuesday, September 28, 2010
  66. 66. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); if(result != SQLITE_OK) { Tuesday, September 28, 2010
  67. 67. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); if(result != SQLITE_OK) { //handle error Tuesday, September 28, 2010
  68. 68. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); if(result != SQLITE_OK) { //handle error } Tuesday, September 28, 2010
  69. 69. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); if(result != SQLITE_OK) { //handle error } //... Tuesday, September 28, 2010
  70. 70. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); if(result != SQLITE_OK) { //handle error } //... Tuesday, September 28, 2010
  71. 71. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); if(result != SQLITE_OK) { //handle error } //... Tuesday, September 28, 2010
  72. 72. SQLite API-Prepared Statements sqlite3 *db; int result = sqlite3_open(DB_PATH, &db); if(result != SQLITE_OK) { //handle error } sqlite3_stmt *stmt; result = sqlite3_prepare_v2(db, sql_cstring, -1, &stmt, NULL); if(result != SQLITE_OK) { //handle error } //... Tuesday, September 28, 2010
  73. 73. SQLite API-Prepared Statements Tuesday, September 28, 2010
  74. 74. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) Tuesday, September 28, 2010
  75. 75. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! Tuesday, September 28, 2010
  76. 76. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); Tuesday, September 28, 2010
  77. 77. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); Tuesday, September 28, 2010
  78. 78. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); Tuesday, September 28, 2010
  79. 79. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); Tuesday, September 28, 2010
  80. 80. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) Tuesday, September 28, 2010
  81. 81. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! Tuesday, September 28, 2010
  82. 82. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! Tuesday, September 28, 2010
  83. 83. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; Tuesday, September 28, 2010
  84. 84. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { Tuesday, September 28, 2010
  85. 85. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; Tuesday, September 28, 2010
  86. 86. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; Tuesday, September 28, 2010
  87. 87. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; [self processRow:row forStatement:stmt]; Tuesday, September 28, 2010
  88. 88. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; [self processRow:row forStatement:stmt]; [results addObject:row]; Tuesday, September 28, 2010
  89. 89. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; [self processRow:row forStatement:stmt]; [results addObject:row]; result = sqlite3_step(stmt); Tuesday, September 28, 2010
  90. 90. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; [self processRow:row forStatement:stmt]; [results addObject:row]; result = sqlite3_step(stmt); } Tuesday, September 28, 2010
  91. 91. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; [self processRow:row forStatement:stmt]; [results addObject:row]; result = sqlite3_step(stmt); } sqlite_finalize(stmt); Tuesday, September 28, 2010
  92. 92. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; [self processRow:row forStatement:stmt]; [results addObject:row]; result = sqlite3_step(stmt); } sqlite_finalize(stmt); Tuesday, September 28, 2010
  93. 93. SQLite API-Prepared Statements //INSERT INTO CARS(year, make) VALUES(?, ?) //PARAMETERS HAVE A 1-BASED INDEX! sqlite3_bind_int(stmt, 1 /* idx */, 5); sqlite3_bind_text(stmt, 2 /* idx */,"value", -1, SQLITE_TRANSIENT); result = sqlite3_step(stmt); if(result == SQLITE_DONE) return [NSArray array]; //nothing to do! NSMutableArray *results = [NSMutableArray array]; while(result == SQLITE_ROW) { NSMutableDictionary *row = [NSMutableDictionary dictionary]; [self processRow:row forStatement:stmt]; [results addObject:row]; result = sqlite3_step(stmt); } sqlite_finalize(stmt); return results; Tuesday, September 28, 2010
  94. 94. SQLite API-Prepared Statements Tuesday, September 28, 2010
  95. 95. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { Tuesday, September 28, 2010
  96. 96. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); Tuesday, September 28, 2010
  97. 97. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { Tuesday, September 28, 2010
  98. 98. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! Tuesday, September 28, 2010
  99. 99. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); Tuesday, September 28, 2010
  100. 100. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); Tuesday, September 28, 2010
  101. 101. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; Tuesday, September 28, 2010
  102. 102. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { Tuesday, September 28, 2010
  103. 103. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; Tuesday, September 28, 2010
  104. 104. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { Tuesday, September 28, 2010
  105. 105. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); Tuesday, September 28, 2010
  106. 106. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; Tuesday, September 28, 2010
  107. 107. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; } else { Tuesday, September 28, 2010
  108. 108. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; } else { // more type handling Tuesday, September 28, 2010
  109. 109. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; } else { // more type handling } Tuesday, September 28, 2010
  110. 110. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; } else { // more type handling } [row setObject:value forKey: Tuesday, September 28, 2010
  111. 111. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; } else { // more type handling } [row setObject:value forKey: [NSString stringWithUTF8String:colName]]; Tuesday, September 28, 2010
  112. 112. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; } else { // more type handling } [row setObject:value forKey: [NSString stringWithUTF8String:colName]]; } Tuesday, September 28, 2010
  113. 113. SQLite API-Prepared Statements -(void)processRow:(NSMutableDictionary *)row forStatement: (sqlite3_stmt*)stmt { int columnCount = sqlite3_column_count(stmt); for(int i=0; i<columnCount; i++) { //0-based index! const char * colName = sqlite3_column_name(stmt, i); int type = sqlite3_column_type(stmt, i); id value = [NSNull null]; if(type == SQLITE_INTEGER) { value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)]; } else if (type == SQLITE_TEXT) { const unsigned char * text = sqlite3_column_text(stmt, i); value = [NSString stringWithFormat:@"%s", text]; } else { // more type handling } [row setObject:value forKey: [NSString stringWithUTF8String:colName]]; } } Tuesday, September 28, 2010
  114. 114. FMDB http://github.com/ccgus/fmdb Tuesday, September 28, 2010
  115. 115. FMDB Usage Tuesday, September 28, 2010
  116. 116. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"]; Tuesday, September 28, 2010
  117. 117. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open]) Tuesday, September 28, 2010
  118. 118. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db."); Tuesday, September 28, 2010
  119. 119. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"]; Tuesday, September 28, 2010
  120. 120. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];      Tuesday, September 28, 2010
  121. 121. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError]) Tuesday, September 28, 2010
  122. 122. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], Tuesday, September 28, 2010
  123. 123. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); Tuesday, September 28, 2010
  124. 124. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"]; Tuesday, September 28, 2010
  125. 125. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction]; Tuesday, September 28, 2010
  126. 126. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction];   int i = 0; Tuesday, September 28, 2010
  127. 127. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction];   int i = 0;   while (i++ < 20) { Tuesday, September 28, 2010
  128. 128. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction];   int i = 0;   while (i++ < 20) {   [db executeUpdate:@"insert into test (a, b) values (?, ?)" , Tuesday, September 28, 2010
  129. 129. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction];   int i = 0;   while (i++ < 20) {   [db executeUpdate:@"insert into test (a, b) values (?, ?)" ,        @"hi'", // look! I put in a ', and I'm not escaping it! Tuesday, September 28, 2010
  130. 130. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction];   int i = 0;   while (i++ < 20) {   [db executeUpdate:@"insert into test (a, b) values (?, ?)" ,        @"hi'", // look! I put in a ', and I'm not escaping it!        [NSNumber numberWithInt:i]]; Tuesday, September 28, 2010
  131. 131. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction];   int i = 0;   while (i++ < 20) {   [db executeUpdate:@"insert into test (a, b) values (?, ?)" ,        @"hi'", // look! I put in a ', and I'm not escaping it!        [NSNumber numberWithInt:i]];   } Tuesday, September 28, 2010
  132. 132. FMDB Usage   FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];   if (![db open])      NSLog(@"Could not open db.");   [db executeUpdate:@"blah blah blah"];        if ([db hadError])    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);   [db executeUpdate:@"create table test (a text, b integer)"];   [db beginTransaction];   int i = 0;   while (i++ < 20) {   [db executeUpdate:@"insert into test (a, b) values (?, ?)" ,        @"hi'", // look! I put in a ', and I'm not escaping it!        [NSNumber numberWithInt:i]];   }   [db commit]; Tuesday, September 28, 2010
  133. 133. What about updates? Database is never copied over again If we did, your customers would lose data Tuesday, September 28, 2010
  134. 134. Migrations Concept from Ruby on Rails Evolutionary database design Each database has a "version" App runs all migrations to the latest version Tuesday, September 28, 2010
  135. 135. Migrations number name 1 initial_schema 2 update_foo 3 implement_blah Tuesday, September 28, 2010
  136. 136. Migrations number name 1 initial_schema 2 update_foo 3 implement_blah Tuesday, September 28, 2010
  137. 137. Hand-rolled Database Migrator DEMO Tuesday, September 28, 2010
  138. 138. FMDB Migration Manager http://github.com/mocra/fmdb- migration-manager Tuesday, September 28, 2010
  139. 139. FMDB Migration Manager NSArray *migrations = [NSArray arrayWithObjects: [CreateStudents migration], // 1 [CreateStaffMembers migration], // 2 [AddStudentNumberToStudents migration], // 3 nil ]; [FmdbMigrationManager executeForDatabasePath:@"/tmp/tmp.db" withMigrations:migrations]; Tuesday, September 28, 2010
  140. 140. FMDB Migration Manager @interface CreateStudents : FmdbMigration { } @end @implementation CreateStudents - (void)up { [self createTable:@"students" withColumns:[NSArray arrayWithObjects: [FmdbMigrationColumn columnWithColumnName:@"first_name" columnType:@"string"], [FmdbMigrationColumn columnWithColumnName:@"age" columnType:@"integer" defaultValue:21], nil]; } - (void)down { [self dropTable:@"students"]; } @end Tuesday, September 28, 2010
  141. 141. ActiveRecord Person *p = [[Person alloc] init]; p.name = @"Joe"; p.occupation = @"Dishwasher"; [p save]; Person *p = [Person personWithId:5]; ==> Person {id:5, name:Joe, occupation:Dishwasher} Tuesday, September 28, 2010
  142. 142. Aptiva's ActiveRecord http://github.com/aptiva/activerecord (YMMV) Tuesday, September 28, 2010
  143. 143. Questions? Tuesday, September 28, 2010
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×