0

背景:我们有一个具有“模式更新”例程的应用程序。它基本上检查 sqLite 的 pragma user_version,如果用户正在运行较旧的模式,它会将其更新为当前的 dB 模式,然后在更新模式后更新 pragma 版本。该代码在启动时(由应用程序委托)通过调用我们的 dbManager 代码来执行模式更新来执行。

问题:我们更新了代码(如下)以添加下一个版本的更改,并如上所述将 user_version 更新为 3。我们的问题是,当我们重新安装应用程序(删除以前的版本)时,我们发现第一次运行应用程序,下面的代码执行没有任何错误(我们逐行执行了无数次),但没有进行任何更改。然后我们退出应用程序(点击主页按钮),点击应用程序图标,代码再次运行(它没有更新 user_version,因此它认为它正在运行旧模式),这次所有更改都已提交。

我们尝试了什么:我们已经仔细检查了数据库的路径以确保它是正确的并且它是正确的 - 我们两次更新同一个数据库。我们逐行浏览,我们删除了试图挑出一行代码的代码。我们试图弄清楚是否有一个缓存没有提交更改,但是我们有一个“finalize”调用来强制刷新,我们经常关闭我们的数据库以确保我们不会让它闲置。

该代码在该应用程序的所有先前版本中都可以正常工作。我们所做的唯一更改是在下面添加“Alter Table”代码。(我们把它拿出来,仍然有上面的问题)。经过几天的死胡同,我们想知道是否有人看到过这个或有任何想法?

我们在最新版本的 XCode 上运行 iOS 7。

任何反馈将不胜感激。

我们的代码...

……

if (currentlyInstalledDBScehmaVersion < 3) //升级3之前的dbSchema {

        /*
         Upgrade Description:

         All schemas prior to version 3, need to add the evolWarmUpTime and evolCoolDownTime columns to tblPlayerProfile
         */

        @try
        {
            if (sqlite3_open([sfcDatabasePath UTF8String], &dbSFC) == SQLITE_OK)
            {
                sqlite3_stmt *sqlStatement;

                sqlUpgradeCommands = @"ALTER TABLE tblPlayerProfile ADD evolWarmUpTime INTEGER(2) DEFAULT 4";
                const char *sqlQueryAddWarmUp = [sqlUpgradeCommands UTF8String];;

                if  (sqlite3_prepare_v2(dbSFC, sqlQueryAddWarmUp, -1, &sqlStatement, NULL) == SQLITE_OK)
                {
                    if(SQLITE_DONE != sqlite3_step(sqlStatement))NSAssert1(0, @"Error while updating. '%s'", sqlite3_errmsg(dbSFC));
                }
                sqlite3_finalize(sqlStatement);

                sqlUpgradeCommands = @"ALTER TABLE tblPlayerProfile ADD evolCoolDownTime INTEGER(2) DEFAULT 5";
                const char *sqlQueryAddCoolDown = [sqlUpgradeCommands UTF8String];;

                if  (sqlite3_prepare_v2(dbSFC, sqlQueryAddCoolDown, -1, &sqlStatement, NULL) == SQLITE_OK)
                {
                    if(SQLITE_DONE != sqlite3_step(sqlStatement))NSAssert1(0, @"Error while updating. '%s'", sqlite3_errmsg(dbSFC));
                }
                sqlite3_finalize(sqlStatement);
            }
        }
        @catch (NSException *exception)
        {
            upgradeErrorOccurred = YES;
            NSLog(@"dbManager_SFC:upgradeScheme exception occured: %@", [exception reason]);
        }

        sqlite3_close(dbSFC);
    }

    if (upgradeErrorOccurred == NO)
    {
        [self updateDBVersion:3]; //Upgrade the schema version number!
    }
    [self hideUpgradeAlertFromUser];

……

4

2 回答 2

0

两者sqlite3_prepare_v2sqlite3_step都可能失败,但您只为后者输出错误。

使用这样的东西:

if (sqlite3_prepare_v2(dbSFC, sql, -1, &sqlStatement, NULL) != SQLITE_OK ||
    sqlite3_step(sqlStatement) != SQLITE_DONE)
{
    NSAssert1(0, @"Error while updating: %s", sqlite3_errmsg(dbSFC));
}
sqlite3_finalize(sqlStatement);

将其放入辅助函数中可能很有用。

于 2013-09-27T07:09:05.260 回答
0

事实证明,这个问题与没有在正确的时间初始化对象有关。当代码第一次执行时,对象没有被初始化,但是通过退出和返回,对象被另一个例程激活,它创建了上述行为。

我们更新了代码以确保对象由上述例程初始化,并且不依赖于代码执行的顺序。

于 2013-09-28T13:29:20.310 回答