3 Stimmen

SQLite-Kopie der Datenbank zerstört Original, warum?

Ich habe dieses Codeschnipsel, um eine Datei-Datenbank in eine Speicher-Datenbank zu kopieren. es funktioniert, aber es zerstört die ursprüngliche Datei-Datenbank. (Mit zerstört meine ich setzt die Dateigröße auf Null)

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

Ich habe mir das jetzt eine Weile angeschaut und kann nicht herausfinden, warum das passiert. Vorschläge?

1voto

Andrey Punkte 4051

Ihr Code funktionierte bei mir einwandfrei (geprüft unter WinXP). Ich denke, Sie sollten versuchen, ihn ohne Angabe des VFS-Objekts auszuführen (falls möglich) - ersetzen Sie einfach NETBURNER_VFS_NAME durch 0 im sqlite3_open_v2-Aufruf. Dies wird zeigen, ob das Problem in der VFS-Anpassung liegt oder nicht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X