FMDB數(shù)據(jù)庫加密問題---數(shù)據(jù)不顯示

參考文章:http://www.itdecent.cn/p/a849bf4858ad
本問題是直接對數(shù)據(jù)庫加密產(chǎn)生的問題

問題: 從未加密得數(shù)據(jù)庫升級到加密數(shù)據(jù)庫,則需要考慮到兼容問題
方案: 打開數(shù)據(jù)庫open -> 設置秘鑰 setkey -> 查看連接 goodConnection -> 新建數(shù)據(jù)庫并遷移數(shù)據(jù)

代碼

- (BOOL)openWithFlags:(int)flags vfs:(NSString *)vfsName {
#if SQLITE_VERSION_NUMBER >= 3005000
    if (_db) {
        return YES;
    }
    
    int err = sqlite3_open_v2([self sqlitePath], (sqlite3**)&_db, flags, [vfsName UTF8String]);
    if(err != SQLITE_OK) {
        NSLog(@"error opening!: %d", err);
        return NO;
    } else {
        [self setKey:DB_KEY];
    }
    
    if (![self goodConnection]) {
        if ([NSString stringWithCString:[self sqlitePath] encoding:NSUTF8StringEncoding]) {
            [self upgradeDatabase:[NSString stringWithCString:[self sqlitePath] encoding:NSUTF8StringEncoding]];
// 下面幾行是重點,很多不細心得程序員總是喜歡拷貝別人的文章粘貼成自己的博客,真是害人。
// 原因:原本是未加密得數(shù)據(jù)庫,設置setKey沒效果,需要遷移數(shù)據(jù)庫之后再設置一次才有效
// u can try: 把下面5行隱藏了實驗。從你從未加密數(shù)據(jù)庫升級過來,第一次打開App總是沒有數(shù)據(jù),只有第二次打開App才會有數(shù)據(jù)顯示。
            [self close];  
            BOOL reRes = [self openWithFlags:flags vfs:vfsName];
            if (reRes) {
                [self setKey:DB_KEY];
            }
        }
    }
    
    if (_maxBusyRetryTimeInterval > 0.0) {
        // set the handler
        [self setMaxBusyRetryTimeInterval:_maxBusyRetryTimeInterval];
    }
    
    return YES;
#else
    NSLog(@"openWithFlags requires SQLite 3.5");
    return NO;
#endif
}

- (void)upgradeDatabase:(NSString *)path{
    NSString *targetPath = [NSString stringWithFormat:@"%@.tmp.db", path];
    if(targetPath){
        const char* sqlQ = [[NSString stringWithFormat:@"ATTACH DATABASE '%@' AS encrypted KEY '%@';", targetPath, DB_KEY] UTF8String];
        
        sqlite3 *unencrypted_DB;
        if (sqlite3_open([path UTF8String], &unencrypted_DB) == SQLITE_OK) {
            char *errmsg;
            // Attach empty encrypted database to unencrypted database
            sqlite3_exec(unencrypted_DB, sqlQ, NULL, NULL, &errmsg);
            if (errmsg) {
                NSLog(@"%@", [NSString stringWithUTF8String:errmsg]);
                sqlite3_close(unencrypted_DB);
            }
            
            // export database
            sqlite3_exec(unencrypted_DB, "SELECT sqlcipher_export('encrypted');", NULL, NULL, &errmsg);
            if (errmsg) {
                NSLog(@"%@", [NSString stringWithUTF8String:errmsg]);
                sqlite3_close(unencrypted_DB);
            }
            
            // Detach encrypted database
            sqlite3_exec(unencrypted_DB, "DETACH DATABASE encrypted;", NULL, NULL, &errmsg);
            if (errmsg) {
                NSLog(@"%@", [NSString stringWithUTF8String:errmsg]);
                sqlite3_close(unencrypted_DB);
            }
            
            sqlite3_close(unencrypted_DB);
            
            //delete tmp database
            [self removeDatabasePath:targetPath targetPath:path];
        }
        else {
            sqlite3_close(unencrypted_DB);
            NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB));
        }
    }
}

- (void)removeDatabasePath:(NSString *)targetPath targetPath:(NSString *)sourcePath {
    NSFileManager *fm = [[NSFileManager alloc] init];
    [fm removeItemAtPath:sourcePath error:nil];
    [fm moveItemAtPath:targetPath toPath:sourcePath error:nil];
}

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容