I have an app that allows you to add items to a list, (From a tableview), when the user clicks on the add button next to the corresponding item, it calls the following +(void)addItem method. Everything works fine, but after heavy testing (60-70 back to back inserts causes it to return the SQL error code “Unable to open database file” and the app has to be restarted. Any ideas? Thanks!
+(void)addItem:(NSString *)dbPath{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *oldTrip = [prefs objectForKey:@"selectedList"];
NSString *table = @"The Table";
NSString *name = [prefs objectForKey:@"SelectedAddItem"];
NSString *countStr = @"1";
NSString *doneStr = @"No";
NSString *noteStr = @"None";
NSString *orderStr = @"15";
sqlite3 *database;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sqlStr = [[NSString stringWithFormat:@"Insert into '%@' Values (null,?,?,?,?,?,?)",oldTrip]UTF8String];
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStr, -1, &compiledStatement, NULL) == SQLITE_OK){
sqlite3_bind_text(compiledStatement, 0,[oldTrip UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 1,[name UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 2,[table UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 3,[countStr UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 4,[doneStr UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 5,[noteStr UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 6,[orderStr UTF8String], -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(compiledStatement) != SQLITE_DONE ) {
NSString* messageString = [NSString stringWithFormat: @"%s\n\nPlease contact the developer if this error persists", sqlite3_errmsg(database)];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error inserting" message:messageString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
} else {
sqlite3_reset(compiledStatement);
sqlite3_finalize(compiledStatement);
}
}
sqlite3_close(database);
}
To get the DB Information, I use:
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:@"ListDatabase.sql"];
}
If it happens only under heavy load, you may want to try leaving the database file open rather than opening and closing it for every operation. I’m not very familiar with SQLite, but you may also be able to reuse the compiled statement just by resetting its bindings each time around (and you don’t need to call
resetbeforefinalizeif you don’t intend to reuse the statement).Perhaps you can open and close your database in your view controller’s
viewDidLoadandviewDidUnloadmethods?