SQLite, iPhone и управление версиями

Я хочу включать обновленную базу данных SQLite с новой версией приложения. Мои копии приложений файл базы данных в каталог Documents на запуске. Что лучший способ состоит в том, чтобы сделать этот вид управления версиями (помимо использования Базовых Данных)?

Я предполагаю, что или специальная таблица 'версии' в файле SQLite или небольшой текстовый файл с номером версии являются способом пойти, но я хотел бы получить другие мнения народов.

5
задан nevan king 26 February 2010 в 03:01
поделиться

2 ответа

Я делаю это, просматривая метки файлов. Если дата изменения файла SQLite DB в пакете .app более поздняя, ​​чем дата в локальном каталоге документов, то я копирую его из пакета .app поверх ... Вот код, который я использую.

sqlite3 *dbh;           // Underlying database handle
NSString *name;         // Database name (this is the basename part, without the extension)
NSString *pathBundle;   // Path to SQLite DB in the .app folder
NSString *pathLocal;    // Path to SQLite DB in the documents folder on the device

- (BOOL)automaticallyCopyDatabase {                             // Automatically copy DB from .app bundle to device document folder if needed
    ES_CHECK(!dbh, NO, @"Can't autoCopy an already open DB")
    ES_CHECK(name!=nil, NO, @"No DB name specified")
    ES_CHECK(pathBundle!=nil, NO, @"No .app bundle path found, this is a cache DB")
    ES_CHECK(pathLocal!=nil, NO, @"No local document path found, this is a read-only DB")
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSDictionary *localAttr = [fileManager fileAttributesAtPath:pathLocal traverseLink:YES];
    BOOL needsCopy = NO;
    if (localAttr == nil) {
        needsCopy = YES;
    } else {
        NSDate *localDate;
        NSDate *appDBDate;
        if (localDate = [localAttr objectForKey:NSFileModificationDate]) {
            ES_CHECK([fileManager fileExistsAtPath:pathBundle], NO, @"Internal error: file '%@' does not exist in .app bundle", pathBundle)
            NSDictionary *appDBAttr = [fileManager fileAttributesAtPath:pathBundle traverseLink:YES];
            ES_CHECK(appDBAttr!=nil, NO, @"Internal error: can't get attributes for '%@'", pathBundle)
            appDBDate = [appDBAttr objectForKey:NSFileModificationDate];
            ES_CHECK(appDBDate!=nil, NO, @"Internal error: can't get last modification date for '%@'", pathBundle)
            needsCopy = [appDBDate compare:localDate] == NSOrderedDescending;
        } else {
            needsCopy = YES;
        }
    }
    if (needsCopy) {
        NSError *error;
        BOOL success;
        if (localAttr != nil) {
            success = [fileManager removeItemAtPath:pathLocal error:&error];
            ES_CHECK(success, NO, @"Can't delete file '%@'" ,pathLocal)
        }
        success = [fileManager copyItemAtPath:pathBundle toPath:pathLocal error:&error];
        ES_CHECK(success, NO, @"Can't copy database '%@' to '%@': %@", pathBundle, pathLocal, [error localizedDescription])
        ES_TRACE(@"Copied DB '%@' to '%@'", pathBundle, pathLocal)
        return success;
    }
    return YES;
}

ES_CHECK - это просто макросы, которые не раскрываются в режиме выпуска и вызывают исключение в режиме отладки ... Они выглядят так:

#if ES_DEBUG
#define ES_ASSERT(cond) assert(cond);
#define ES_LOG(msg...) NSLog(msg);
#define ES_TRACE(msg...) NSLog(msg);
#else
#define ES_ASSERT(cond)
#define ES_LOG(msg...)
#define ES_TRACE(msg...)
#endif
#define ES_CHECK(cond, ret, msg...) if (!(cond)) { ES_LOG(msg) ES_ASSERT(cond) return (ret); }      // Check with specified return value (when condition fails)
0
ответ дан 15 December 2019 в 00:59
поделиться

Нет необходимости в специализированный стол. В SQLite для этого есть прагма user_version . SQLite ни для чего не использует это значение, это полностью оставлено на усмотрение приложения.

Чтобы прочитать версию:

#pragma user_version;

Чтобы установить версию:

#pragma user_version=1;
4
ответ дан 15 December 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: