代码之家  ›  专栏  ›  技术社区  ›  Steven Smethurst

SQLite复制数据库破坏了原来的,为什么?

  •  3
  • Steven Smethurst  · 技术社区  · 14 年前

    我得到了这个代码片段来将文件数据库复制到内存数据库。它可以工作,但会破坏原始文件数据库(销毁是指将文件大小设置为零)

    /**
     * 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 回复  |  直到 14 年前
        1
  •  1
  •   Andrey    14 年前

    你的代码对我来说运行得很好(在WinXP上检查过)。 我认为您应该尝试在不指定VFS对象的情况下运行它(如果可能的话)-只需在sqlite3\u open\u v2调用中将NETBURNER\u VFS\u NAME替换为0即可。 这将显示问题是否在VFS定制中。