iOS 应用程序 sqlite3 上的离线缓存已损坏

发布于 2025-01-08 04:29:06 字数 1111 浏览 0 评论 0原文

我有一个用于 iOs 应用程序的 sqlite3 数据库,以便为系统提供离线支持。

它工作完美。但有时 .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 文件状态吗?

也许使用其他存储系统更好。有什么推荐吗?

I've an sqlite3 database for an iOs application, in order to provide an offline support to the system.

It works perfectly. But sometimes the .db file becomes corrupted. And doesn't return results.

If I check the SELECT instruction throught the command line I get the next Error message:

sqllite Error: database disk image is malformed

Although is not desirable it becomes corrupt. The database is just an auxiliary system, would be enough to being able to detect from iOS application that the file is corrupted and restart the file.

But using the sqlite3 statements I didn't get any exception. The code looks like:

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);

When the application executes the previous code, simply returns an empty array, no exception is thrown.

Anybody knows how to check from the sqlite3 statements the .db file status?

Maybe is better to user other storage system. Any recommendation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

剪不断理还乱 2025-01-15 04:29:06

最后我决定从应用程序检查数据库状态,如果数据库已损坏,则只需替换为新的空数据库。

- (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 文档中预期响应的顺序定义的。

谢谢你,

伊万

Finally I decided to check from the application the database status, and if the database has become corrupted, the just replace for a new empty database.

- (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;
}

The results was defined in order of the expected response on the sqlite3 documentation.

Thank you,

Ivan

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文