views:

37

answers:

1

Until now all my database access has been reading, but now I need to update (and after this insert)

I have a database containing 'shows' in the app directory (read-only) and that's ok for me (I don't want to copy it to the documents folder as it's rather big and I don't need to change stuff in it.

But I want the user to select some shows as his favorite. Therefore I created a database with a table 'favorite_shows' in the documents folder. It contains 4 fields: ID (prim key) show_id is_favorite remarks (currently not yet in use)

The user is able to toggle the 'is_favorite' status ONCE, after that I'm getting an error when trying to update:

SQLITE_BUSY 5 /* The database file is locked */

This is my code:

if (sqlite3_open([databasePath UTF8String],&database) == SQLITE_OK){
    sqlStatement = "select * from favorite_shows WHERE (show_id = ?)";
    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
        sqlite3_bind_int(compiledStatement, 1, self.ID);
        // search for a show
        if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
            // if we can find one, toggle the status
            favID       = sqlite3_column_int(compiledStatement, 0); // we need the primary key to update it
            isFav       = (sqlite3_column_int(compiledStatement, 2) == 1); // let's store the favorite status

            sqlStatement = "update favorite_shows SET is_favorite = ? WHERE (ID = ?)";
            if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
                sqlite3_bind_int(compiledStatement, 1, !isFav );                
                sqlite3_bind_int(compiledStatement, 2, favID);
                int error = sqlite3_step(compiledStatement);
                if (SQLITE_DONE != error) {
                    NSLog(@"error while updating favorite status");
                }
            }   
        }
        //else :  no records found indicating that this show hasn't been a favorite yet, so insert one as favorite

sqlite3_finalize(compiledStatement);        
sqlite3_close(database);
}

What is the reason that it's locked the second time ? Is there some other instruction to give besides : sqlite3_finalize(compiledStatement);
sqlite3_close(database); to close everything ?

+1  A: 

EDIT:

The BUSY is a result of re-using compiledStatement without deleting the previously compiled statment. You need to free resources properly using finalize and close functions. Refer to the docs here. http://sqlite.org/c3ref/stmt.html

const char * select = "select * from favorite_shows WHERE (show_id = ?)";
const char * update = "update favorite_shows SET is_favorite = ? WHERE (ID = ?)";

sqlite3_stmt *selectStmt;
sqlite3_stmt *updateStmt;


if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    if(sqlite3_prepare_v2(database, select, -1, &selectStmt, NULL) == SQLITE_OK) {
        sqlite3_bind_int(selectStmt, 1, self.ID);
        // search for a show
        if(sqlite3_step(selectStmt) == SQLITE_ROW) {
            // if we can find one, toggle the status
            favID       = sqlite3_column_int(selectStmt, 0); // we need the primary key to update it
            isFav       = (sqlite3_column_int(selectStmt, 2) == 1) ? 0 : 1; // Flip is_favorite value
            sqlite3_finalize(selectStmt); // Delete the statement OR create a new one

            if(sqlite3_prepare_v2(database, update, -1, &updateStmt, NULL) == SQLITE_OK) {
                sqlite3_bind_int(updateStmt, 1, isFav );                
                sqlite3_bind_int(updateStmt, 2, favID);
                int error = sqlite3_step(updateStmt);
                if (SQLITE_DONE != error) {
                    NSLog(@"error while updating favorite status");
                } else {
                sqlite3_finalize(updateStmt);
                }
            }
    } //else :  no records found indicating that this show hasn't been a favorite yet, so insert one as favorite
 }
    sqlite3_close(database);
}
falconcreek
this really did the trick ! Thx a lot !
Glenn
Why don't you mark it correct then?
Rudiger