2010-07-29 2 views
3

이 코드 스 니펫을 통해 파일 데이터베이스를 메모리 데이터베이스에 복사했습니다. 그것은 작동하지만 원본 파일 데이터베이스를 파괴합니다. 나는 잠시 지금 그것을 찾고있다 내가 왜 이런 일 알아낼 수SQLite 복사 데이터베이스가 원본을 손상 시켰습니다. 이유가 무엇입니까?

/** 
* Exec an sql statement in values[0] against 
* the database in pData. 
*/ 
int process_ddl_row(void * pData, int nColumns, char **values, char **columns) 
{ 
    if (nColumns != 1) { 
     return 1; // Error 
    } 

    sqlite3 * db = (sqlite3*)pData; 
    if(SQLITE_OK != sqlite3_exec(db, values[0], NULL, NULL, NULL)) { 
     return 1; 
    } 
    return 0; 
} 
/** 
* Insert from a table named by backup.{values[0]} 
* into main.{values[0]} in database pData. 
*/ 
int process_dml_row(void *pData, int nColumns, char **values, char **columns) 
{ 
    if (nColumns != 1) { 
     return 1; // Error 
    } 

    sqlite3* db = (sqlite3*)pData; 

    char *stmt = sqlite3_mprintf("insert into main.%q " "select * from backup.%q", values[0], values[0]); 
    if(SQLITE_OK != sqlite3_exec(db, stmt, NULL, NULL, NULL)) { 
     return 1; 
    } 
    sqlite3_free(stmt); 
    return 0; 
} 


bool CDatabase::LoadFromFile(const char * databaseFile) 
{ 
    if(databaseFile == NULL || this->m_db == NULL) { 
     return false; 
    } 

    sqlite3 * memorydb = this->m_db->GetDb() ; // Gets the open memory database. 
    sqlite3 * backupdb = NULL ; 
    if(SQLITE_OK != sqlite3_open_v2(databaseFile, &backupdb, SQLITE_OPEN_READONLY, NETBURNER_VFS_NAME)) { 
     return false; 
    } 

    // Schema 
    // --------------------------------------------------------------------------- 
    // Create the in-memory schema from the backup 
    if(SQLITE_OK != sqlite3_exec(backupdb, "BEGIN", NULL, NULL, NULL)) { 
     return false; 
    } 
    if(SQLITE_OK != sqlite3_exec(backupdb, "SELECT sql FROM sqlite_master WHERE sql NOT NULL", &process_ddl_row, memorydb, NULL)) { 
     return false; 
    } 
    if(SQLITE_OK != sqlite3_exec(backupdb, "COMMIT", NULL, NULL, NULL)) { 
     return false; 
    } 
    sqlite3_close(backupdb); 

    // DATA 
    // --------------------------------------------------------------------------- 
    // Attach the backup to the in memory 

    char sql[255]; 
    sprintf(sql, "ATTACH DATABASE '%s' as backup", databaseFile); 
    // This after this line the file database is set to zero bytes. 
    if(SQLITE_OK != sqlite3_exec(memorydb, sql, NULL, NULL, NULL)) { 
     return false; 
    } 

    // Copy the data from the backup to the in memory 
    if(SQLITE_OK != sqlite3_exec(memorydb, "BEGIN", NULL, NULL, NULL)) { 
     return false; 
    } 


    if(SQLITE_OK != sqlite3_exec(memorydb, "SELECT name FROM backup.sqlite_master WHERE type='table'", &process_dml_row, memorydb, NULL)) { 
     return false; 
    } 
    if(SQLITE_OK != sqlite3_exec(memorydb, "COMMIT", NULL, NULL, NULL)) { 
     return false; 
    } 
    if(SQLITE_OK != sqlite3_exec(memorydb, "DETACH DATABASE backup", NULL, NULL, NULL)) { 
     return false; 
    } 

    return true; 
} 

(을 파괴함으로써 I 0으로 세트를 파일 크기를 의미한다). 제안?

답변

1

코드가 잘 작동했습니다 (WinXP에서 확인). VFS 개체 (가능한 경우)를 지정하지 않고 실행 해보십시오. sqlite3_open_v2 호출에서 NETBURNER_VFS_NAME을 0으로 바꿉니다. 문제가 VFS 사용자 정의에 있는지 여부를 표시합니다.

+0

정확합니다. 감사합니다. 당신이 관심이 있다면 질문을 후속 http://stackoverflow.com/questions/3373816/sqlite-vfs-implementation-guild-lines-with-fopen –

관련 문제