0

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;
    }
mtwagner
  • 466
  • 6
  • 12

3 Answers3

0

How are you getting to loanBookTo? If the database is open and then you call loanBookTo, it may not throw an error of the open, however the database is holding the state from where you came.

Also, at times, the database retains the locked state upon closing and exiting the application, so you could be 'inheriting' a locked state from your previous failures. Deleting the app from the simulator should give you a clean copy.

Chris Hardaker
  • 105
  • 2
  • 13
0

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
  • 41,167
  • 16
  • 88
  • 103
0

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

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.

Community
  • 1
  • 1
Andiih
  • 12,285
  • 10
  • 57
  • 88