代码之家  ›  专栏  ›  技术社区  ›  Thomas Joulin

iPhone应用商店更新系统及其对数据库的影响

  •  1
  • Thomas Joulin  · 技术社区  · 14 年前

    像你们许多人一样,我必须删除模拟器中的应用程序,以便重新安装一个新版本,在那里我更新我的数据库。否则,它会在有或没有调试日志的情况下崩溃(如果它是核心数据,则调试日志非常简单)。

    我的问题是:因为用户在通过应用商店更新之前可能不会删除他们的应用程序,而且在升级之后他们肯定会想要他们的“旧”数据,

    我们是否必须开发数据库迁移脚本,或者在每次启动时签入applicationidlaunch(如果数据库已更改)?

    谢谢!

    2 回复  |  直到 14 年前
        1
  •  1
  •   aepryus    14 年前

    我个人没有使用过CoreData,所以不知道它是否有专门的工具来处理这个问题。但是,一般来说是的,您需要创建和存储SQL脚本,这些脚本将从应用程序的每个版本迁移到下一个版本。

    例如,如果您已经向AppStore提交了4个版本。从版本1到2、从2到3和从3到4需要一个delta脚本。

    每次应用程序启动时,它都会对照所需的可执行文件版本检查数据模型的当前版本。例如,如果设备上安装了版本4,但用户从未安装版本3,则应用程序将启动。检查模型的当前版本,即2。将其与可执行文件的版本(4)进行比较。然后应用2到3脚本,然后应用3到4脚本。

    版本号本身可以存储在数据库中,并且应该在应用增量之后递增,可以从增量本身,也可以在处理代码中自动递增。

    增量可以作为常量字符串存储在代码文件中,也可以作为资源文件存储在项目中。

    编辑:(这是我的迁移代码)

    + (NSArray*) chop:(NSString*)sql {
        NSMutableArray* list = [[NSMutableArray alloc] init];
        NSMutableString* sb = [[NSMutableString alloc] init];
        BOOL inside = FALSE;
    
        for (int i=0;i<[sql length];i++) {
            if ([sql characterAtIndex:i] == '\n') continue;
            if ([sql characterAtIndex:i] == '\r') continue;
    
            [sb appendFormat:@"%c",[sql characterAtIndex:i]];
            if (!inside) {
                if ([sql characterAtIndex:i] == '\'')
                    inside = TRUE;
                else if ([sql characterAtIndex:i] == ';') {
                    [sb deleteCharactersInRange:NSMakeRange([sb length]-1,1)];
                    [list addObject:sb];
                    [sb release];
                    sb = [[NSMutableString alloc] init];
                }
            } else {
                if ([sql characterAtIndex:i] == '\'')
                    inside = FALSE;
                else if ([sql characterAtIndex:i] == '\\') {
                    i++;
                    [sb appendFormat:@"%c",[sql characterAtIndex:i]];
                }
            }
        }
        [sb release];
        return [list autorelease];
    }
    
    + (void) updateObjectModel {
        [Log output:@"[migration]"];
    
        int version;
        @try {
            int exist = [SQL queryLong:@"SELECT COUNT(*) FROM Variables WHERE Key='objectModelVersion'"];
            if (exist)
                version = [SQL retrieveInt:@"objectModelVersion"]+1;
            else {
                [Log output:@"[bootstrapping]"];
                [SQL storeInt:@"objectModelVersion" as:1];
                version = 2;
            }
        } @catch (NSException* e) {
            [Log output:@"[initializing]"];
            version = 0;
        }
    
        while (TRUE) {
            NSString* filename = [NSString stringWithFormat:@"SQLite-%04d",version];
            NSString* file = [[NSBundle mainBundle] pathForResource:filename ofType:@"sql"];
            if (file) {
                [Log output:[NSString stringWithFormat:@"[%d]",version]];
                NSArray* commands = [SQL chop:[NSString stringWithContentsOfFile:file encoding:NSASCIIStringEncoding error:NULL]];
                for (NSString* command in commands)
                    [SQL update:command];
                [SQL storeInt:@"objectModelVersion" as:version];
            } else break;
    
            version++;
        }
        [Log output:@"[/migration]\n"];
    }
    
        2
  •  3
  •   Community leo1    7 年前


    核心数据版本控制和迁移将在几分钟内完成,至少是轻量级部分。

    看看这个 answer