SQLite复制数据库时为什么会破坏原始数据库?

3

我有一个代码片段,可以将文件数据库复制到内存数据库。它可以工作,但会破坏原始文件数据库。(所谓的破坏是指将文件大小设置为零)

/**
 * 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; 
}

我已经看了一段时间,但似乎无法弄清楚为什么会发生这种情况。有建议吗?

1个回答

1

你的代码在我这里运行良好(在WinXP上检查过)。 我认为你应该尝试在不指定VFS对象的情况下运行它(如果可能),只需在sqlite3_open_v2调用中将NETBURNER_VFS_NAME替换为0。 这将显示问题是否在VFS定制中。


你是正确的,谢谢。如果你有兴趣,可以继续提问。https://dev59.com/RXA75IYBdhLWcg3wS3BA - Steven Smethurst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接