Автономный кеш на iOS-приложении sqlite3 поврежден - PullRequest
4 голосов
/ 23 февраля 2012

У меня есть база данных sqlite3 для приложения iOs, чтобы обеспечить автономную поддержку системы.

Она отлично работает.Но иногда файл .db становится поврежденным.И не возвращает результаты.

Если я проверяю инструкцию SELECT через командную строку, я получаю следующее сообщение об ошибке:

sqllite Error: database disk image is malformed

Хотя это нежелательно, оно становится поврежденным.База данных является всего лишь вспомогательной системой, и ее было бы достаточно, чтобы можно было из приложения iOS обнаружить, что файл поврежден, и перезапустить файл.

Но, используя операторы sqlite3, я не получил никаких исключений.Код выглядит следующим образом:

sqlRaw = @"SELECT ... ";
const char *sql = [sqlRaw cStringUsingEncoding:NSUTF8StringEncoding];
if (sqlite3_prepare_v2(database, sql, -1, &date_statement, NULL) != SQLITE_OK) {
    NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}

NSMutableArray *entities = [[NSMutableArray alloc] initWithCapacity:0];
while (sqlite3_step(date_statement) == SQLITE_ROW) {
    NSData *entityXml = [[NSData alloc] initWithBytes:sqlite3_column_blob(date_statement, 0) 
                                                   length:sqlite3_column_bytes(date_statement, 0)];
    [entities addObject:entityXml];
}
sqlite3_finalize(date_statement);

Когда приложение выполняет предыдущий код, просто возвращает пустой массив, исключение не выдается.

Кто-нибудь знает, как проверить из операторов sqlite3.db file status?

Может быть, лучше использовать другую систему хранения.Любая рекомендация?

1 Ответ

5 голосов
/ 24 февраля 2012

Наконец я решил проверить из приложения состояние базы данных, и если база данных была повреждена, просто замените новую пустую базу данных.

- (BOOL) isDatabaseCorrupted {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:cache_final_path];
    BOOL bResult = FALSE;
    if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {  
        @try {
            NSString *sqlRaw = @"PRAGMA integrity_check;";
            const char *sql = [sqlRaw cStringUsingEncoding:NSUTF8StringEncoding];
            if (sqlite3_prepare_v2(database, sql, -1, &check_statement, NULL) == SQLITE_OK) {
                int success = sqlite3_step(check_statement);
                NSLog(@"SQL integrity_check result is %d", success);
                NSString *response = nil;
                switch (success) {
                    case SQLITE_ERROR:
                        bResult = TRUE;
                        break;
                    case SQLITE_DONE:
                        NSLog(@"Result is simple DONE of the sqllite3 on isDatabaseCorrupted");
                        break;
                    case SQLITE_BUSY:
                        NSLog(@"Result is simple BUSY of the sqllite3 on isDatabaseCorrupted");
                        break;
                    case SQLITE_MISUSE:
                        NSLog(@"Bad utilization of the sqllite3 on isDatabaseCorrupted");
                        break;
                    case SQLITE_ROW:
                        response = [NSString stringWithUTF8String:(char *)sqlite3_column_text(check_statement, 0)];
                        if ([[[response lowercaseString] stringByTrimmingCharactersInSet:[NSCharacterSet 
                                                                                          whitespaceAndNewlineCharacterSet]] 
                             isEqualToString:@"ok"]){
                            bResult = FALSE;
                        } else {
                            NSLog(@"ATTENTION: integrity_check response %@", response);
                            bResult = TRUE;
                        }
                        break;
                    default:
                        break;
                }

                sqlite3_finalize(check_statement);
            }

        }
        @catch (NSException *exception) {
            [TSLogger log:[NSString stringWithFormat:@"Exception %@", [exception description]] 
             withSeverity:severity_error];
            return TRUE;
        }        
    }

    sqlite3_close(database);
    return bResult;
}

Результаты были определены в порядке ожидаемого ответа в документации sqlite3.

Спасибо,

Иван

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...