2012-02-23 72 views
4

我有一個用於iOs應用程序的sqlite3數據庫,以便爲系統提供脫機支持。iOS應用程序的脫機緩存sqlite3變得損壞

它完美的作品。但有時.db文件損壞。並不返回結果。

如果我檢查SELECT指令throught在命令行中,我得到一個錯誤信息:

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文件狀態?

也許對用戶其他存儲系統更好。任何建議?

+0

您使用觸發器?我最近在同一個問題上發了一個帖子,結果證明了責備是觸發器的改變。 SQLite是愚蠢的地獄:( – holographix 2012-02-23 11:03:43

+0

啊,我發現線程,你走了。看看它,也許你會發現一些有用的東西http://sqlite.phxsoftware.com/forums/t/650.aspx – holographix 2012-02-23 11:06:05

+0

不,沒有觸發器,只是INDEX對我來說,實際上並不重要,如果文件損壞了,但我需要檢查它:-( – 2012-02-23 11:07:03

回答

5

最後我決定從應用程序中檢查數據庫狀態,並且如果數據庫已經損壞,只需替換一個新的空數據庫。

- (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文檔的預期響應順序定義。

謝謝

伊萬

+0

輝煌。感謝代碼! – 2012-12-19 12:32:20

+0

很好理解爲什麼它是g正在破壞。顯然不應該發生。 – Dad 2012-12-25 06:54:49

相關問題