Я разрабатываю приложение для iPhone, которое использует библиотеку sqlite напрямую, а не CoreData. Я пытался сбросить стол, но как бы я ни пытался, я всегда получал SQLITE_LOCKED
вместо SQLITE_DONE
.
Я искал stackoverflow.com, но не смог найти подобных проблем. Вот мой код:
-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;
}
Контрольный пример
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.");
Некоторые дополнительные объяснения:
DTModeelHelper
- это вспомогательный класс singleton, который содержит все операции с БД.
SLDBAccess
также является одноэлементным вспомогательным классом, который инициирует БД и устанавливает соединение или закрывает соединение.
isTableExistWith:
- это другой метод, который будет запрашивать у БД, существует ли указанная таблица или нет. Теперь работает нормально.
Кто-нибудь имеет представление об этой проблеме?