0

背景: 「スキーマ更新」ルーチンを持つアプリがあります。これは基本的に sqlite のプラグマ user_version をチェックし、ユーザーが古いスキーマを実行している場合は、それを現在の dB スキーマに更新し、スキーマの更新後にプラグマ バージョンを更新します。このコードは、dbManager コードを呼び出してスキーマの更新を実行することにより、起動時に (アプリ デリゲートによって) 実行されます。

問題: コード (以下) を更新して、次のリリースの変更を追加し、前述のように user_version を 3 に更新しました。問題は、アプリの新規インストール (以前のバージョンの削除) を行うときに、アプリを実行すると、以下のコードはエラーなしで実行されます (行ごとに何回もステップ実行しました) が、変更は行われていません。次に、アプリを終了し (ホーム ボタンを押します)、アプリ アイコンをタップすると、コードが再度実行されます (user_version が更新されていないため、古いスキーマが実行されていると見なされます)。今回は、すべての変更がコミットされます。

試したこと : データベースのパスを再確認して、それが正しいことを確認しました。同じデータベースを両方とも更新しました。行ごとに説明し、1 行のコードを抜き出そうとするコードを削除しました。変更をコミットしていないキャッシュがあるかどうかを確認しようとしましたが、フラッシュを強制する「ファイナライズ」呼び出しがあり、データベースを頻繁に閉じて、ハングアップしたままにしないようにしています。

このコードは、アプリの以前のすべてのバージョンで問題なく機能しました。私たちが行った唯一の変更は、以下の「Alter Table」コードを追加したことです。(私たちはそれを取り出しましたが、まだ上記の問題がありました). 数日間の行き詰まりの後、誰かがこれを見たのか、何かアイデアがあるのか​​ 疑問に思っていますか?

iOS 7 で XCode の最新リリースを実行しています。

どんなフィードバックでも大歓迎です。

私たちのコード...

....

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_v2と の両方sqlite3_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 に答える