I'm developing an iPhone开发者_开发百科 app which is using sqlite library directly instead of CoreData. I tried to drop a table, but no matter how I tried, I always got a SQLITE_LOCKED
instead of SQLITE_DONE
.
I had searched stackoverflow.com, but could not find any similar problems. Here is my code:
-DropTable:
- (BOOL) dropTable:(NSString *)tableName{ NSString* queryBase = [NSString stringWithFormat:@"drop table if exists %@;", tableName]; const char* query = [queryBase UTF8String]; sqlite3_stmt* stmt = nil; if (sqlite3_prepare_v2([SLDBAccess sharedSLDBAccess].database, query, -1, &stmt, NULL) != SQLITE_OK){ NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg([SLDBAccess sharedSLDBAccess].database)); } //transaction start sqlite3_exec([SLDBAccess sharedSLDBAccess].database, "BEGIN;", NULL, NULL, NULL); /* The following line returns SQLITE_LOCKED, which the value is 6. */ int dropOperationResult = sqlite3_step(stmt); sqlite3_reset(stmt); sqlite3_finalize(stmt); BOOL operationSucceeded = NO; if(dropOperationResult == SQLITE_DONE) { operationSucceeded = YES; } //transaction end if (operationSucceeded) { sqlite3_exec([SLDBAccess sharedSLDBAccess].database, "COMMIT;", NULL, NULL, NULL); }else { sqlite3_exec([SLDBAccess sharedSLDBAccess].database, "ROLLBACK;", NULL, NULL, NULL); } // No means failed. return operationSucceeded; }
-initTable:
- (BOOL) initTimelineTableWith:(NSString *)tableName{ NSString* queryBase = [NSString stringWithFormat:@"CREATE TABLE %@ ( id INTEGER PRIMARY KEY AUTOINCREMENT, timeline_id BIGINT UNSIGNED UNIQUE, in_reply_to_screen_name TEXT, in_reply_to_status_id INTEGER UNSIGNED, in_reply_to_user_id BIGINT UNSIGNED, source TEXT, text TEXT, favorited BOOLEAN, truncated BOOLEAN, retweeted_status BIGINT UNSIGNED, retweeted BOOLEAN, user BIGINT UNSIGNED, status INTEGER UNSIGNED, create_at DATETIME, update_on DATETIME );", tableName]; const char* query = [queryBase UTF8String]; sqlite3_stmt* stmt = nil; if (sqlite3_prepare_v2([SLDBAccess sharedSLDBAccess].database, query, -1, &stmt, NULL) != SQLITE_OK){ NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg([SLDBAccess sharedSLDBAccess].database)); } //transaction start sqlite3_exec([SLDBAccess sharedSLDBAccess].database, "BEGIN;", NULL, NULL, NULL); int createOperationResult = sqlite3_step(stmt); sqlite3_reset(stmt); sqlite3_finalize(stmt); BOOL operationSucceeded = NO; if(createOperationResult == SQLITE_DONE) { operationSucceeded = YES; } //transaction end if (operationSucceeded) { sqlite3_exec([SLDBAccess sharedSLDBAccess].database, "COMMIT;", NULL, NULL, NULL); SLLog(@"create table successfully!"); }else { sqlite3_exec([SLDBAccess sharedSLDBAccess].database, "ROLLBACK;", NULL, NULL, NULL); SLLog(@"create table failed!"); } // No means failed. return operationSucceeded; }
Test case
NSString *newTableName = @"tonny_test"; STAssertFalse([[DTModelHelper sharedDTModelHelper] isTableExistWith:newTableName], @"new table should not exsit."); STAssertTrue([[DTModelHelper sharedDTModelHelper] initTimelineTableWith:newTableName], @"init with new table."); STAssertTrue([[DTModelHelper sharedDTModelHelper] isTableExistWith:newTableName], @"new table should exsit after we created it."); /* The following 2 test cases always failed. */ STAssertTrue([[DTModelHelper sharedDTModelHelper] dropTable:newTableName], @"drop table operation should return OK."); STAssertFalse([[DTModelHelper sharedDTModelHelper] isTableExistWith:newTableName], @"new table should not exsit after being dropped.");
Some additional explanations:
DTModeelHelper
is a singleton helper class which contains all the DB operations.SLDBAccess
is also a singleton helper class which will init the DB and establish the connection or close the connection.isTableExistWith:
is another method that will query the DB for whether a specified table exists or not. It works fine now.
Does anybody have any idea about this issue?
精彩评论