开发者

tried "DROP TABLE/DROP TABLE IF EXISTS tablename", but got a SQLITE_LOCKED, instead of SQLITE_DONE

开发者 https://www.devze.com 2023-01-19 19:35 出处:网络
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 SQL

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?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号