Search code examples
iphoneios5sqlitefmdb

iOS - FMDB database insert


To insert data into a database using sqlite requires copying of the database to make it writable. So I have this method in my class which every suggestion I've seen over stack overflow and many other sites:

-(void)createEditableCopyOfDatabaseIfNeeded 
{  
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"sample.db"];

    success = [fileManager fileExistsAtPath:writableDBPath];

    if (success) return;
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"sample.db"];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
        if (!success) {
            NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
        }

}

Of course I have this next codes to access my database:

FMDatabase *db; = [FMDatabase databaseWithPath:[[NSBundle mainBundle] pathForResource:@"sample" ofType:@"db"]];
if (![db open]) {
    NSLog(@"Error!");
}
else {
    NSLog(@"Database opened!!");
}

[self createEditableCopyOfDatabaseIfNeeded];
[db executeUpdate:@"Insert into user (name, phone, comment) values(?, ?, ?)", @"Name1", @"13548", @"This is a comment", nil];
NSLog(@"Inserted");

FMResultSet *s = [db executeQuery:@"SELECT * FROM user"];
while ([s next]) {
    NSLog(@"%@", [s stringForColumn:@"comment"]);
}

Now, I have a few questions:

  1. The insertion code worked perfectly in the simulator when being executed/ran. However, this didn't have an effect to the real sample.db which I concluded it must have a writable copy somewhere in the hard drive of my mac. That is acceptable. But when I ran these code on the iphone, it somewhat didn't recognize my createEditableCopyOfDatabaseIfNeeded method and gave this error: Unknown error finalizing or resetting statement > (8: attempt to write a readonly database). How do I make these codes work using FMDB?

  2. When running on the iPhone, where would the be copied database located? After copied, does the iPhone use that database again even if not connected to my mac?

I cannot insert something when ran on the device. Please help.

Thank you so much!


Solution

  • if you are reading this, then I have the explanation to your problem.

    1. If there is any file in Resource Bundle, then it is a READ-ONLY file. So, your database path to your resources directory is available for reading purposes only.

    2. According to the code that you have written to copy the database, the database will be created in the your application's document directory. This path will be unaffected even when you remove your iPhone from your Mac.