views:

426

answers:

2

So I have been working on this project for a short while now. I have no problems with reading data from the DB, and formatting it into UITableViews and what not. But now I am wanting also to write to the DB as well. The problem is I keep getting a "Database is Locked" error from sqlite. After messing around with the original version I had the face-palm moment by realizing my database was in the bundle and therefore not writable. So I relocated the DB to the Apps Documents folder, which is writeable. But now I still get the same "Database is Locked" sql error. I only open and close the DB when necessary. And as far as I can tell, I don't leave it open anywhere. Below is the code where I am wanting to do updates. Any thoughts?

    - (BOOL) loanBookTo:(NSString *)newborrower{
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"books.sqlite"]; 

        if([[NSFileManager defaultManager] fileExistsAtPath:path]){
         NSLog(@"File Exists at: %@", path);
        }


        if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) { 
         NSString *mySQL = @"UPDATE BOOKS SET LOANED = 1, BORROWER = \"<BORROWER>\" where ISBN = \"<ISBN>\"";
         mySQL = [mySQL stringByReplacingOccurrencesOfString:@"<ISBN>" withString:self.isbn];
         mySQL = [mySQL stringByReplacingOccurrencesOfString:@"<BORROWER>" withString:newborrower];
         const char *sql = [mySQL UTF8String];
         char* errmsg;
         sqlite3_exec(database, sql, NULL, NULL, &errmsg);

         // Q. Database is locked. Why?
         // A. Because it is in the Bundle and is ReadOnly.
         //    Need to write a copy to the Doc folder.

            // Database is Locked error gets spit out here. 
         printf(errmsg);
         sqlite3_close(database);
        } 
        return NO;
    }
A: 

Open the database once at the start of your app, then close it in applicationWillTerminate of the AppDelegate.

After every exec you will want to do a reset to clear the connection state.

Take a look at the SQLiteBooks sample app, it is coded this way.

joshperry
A: 

How do you move the DB to the documents folder from the bundle? You need to check that it is there, and if not copy it. I get the feeling that either you have copied it some other way, but retained a read-only attribute, or more likely, you are still referencing the original in the bundle.

For details see

http://stackoverflow.com/questions/717108/where-would-you-place-your-sqlite-database-file-in-an-iphone-app

or as joshperry says, the SQLiteBooks sample has all the code you need.

Andiih