2017-03-13 22 views
0

Ich versuche, eine Datenbanksicherung für SQLite3 in meiner UWP-App zu erstellen. Basierend auf der Online Backup API von SQLite (https://www.sqlite.org/backup.html), habe ich die folgende Methode geschrieben. backup_init kehrt erweiterten Fehlercode 7. Definition von SQLite Dokumentation:SQLite-Sicherung in UWP C#

(7) SQLITE_NOMEM

Das Ergebnis zeigt an, dass Code SQLITE_NOMEM SQLite nicht in der Lage war alles zuzuteilen> der Speicher es erforderlich, um die Operation abzuschließen. Mit anderen Worten, ein interner> Aufruf von sqlite3_malloc() oder sqlite3_realloc() ist fehlgeschlagen, wenn der zuzuweisende Speicher benötigt wurde, um die Operation fortzusetzen.

Ich bin nicht vertraut mit Zeigern in C# und denke, ich habe einen Fehler mit ihnen. Jede Hilfe wird geschätzt.

public static string BackupDB() 
    { 
     IntPtr pDb = Marshal.StringToHGlobalUni(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "DB.sqlite")); //Database to backup 
     string zFilename = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "DBBACKUP.sqlite"); //destination db path 

     string debug = ""; 
     IntPtr pFile; //Database connection opened on zFilename 
     IntPtr pBackup; //Backup handle used to copy data 


     /* Open the database file identified by zFilename. */ 
     var rc = SQLite3.Open(zFilename, out pFile); 
     debug += rc.ToString(); 

     if (rc == SQLite.Net.Interop.Result.OK) 
     { 
      /* Open the sqlite3_backup object used to accomplish the transfer */ 
      pBackup = SQLite3.sqlite3_backup_init(pFile, "main", pDb, "main"); 

      if (pBackup != null) 
      { 
       /* Each iteration of this loop copies 5 database pages from database 
       ** pDb to the backup database. If the return value of backup_step() 
       ** indicates that there are still further pages to copy, sleep for 
       ** 250 ms before repeating. */ 
       do 
       { 
        rc = SQLite3.sqlite3_backup_step(pBackup, 5); 

        //xProgress(
        // sqlite3_backup_remaining(pBackup), 
        // sqlite3_backup_pagecount(pBackup) 
        //); 
        if (rc == SQLite.Net.Interop.Result.OK || rc == SQLite.Net.Interop.Result.Busy || rc == SQLite.Net.Interop.Result.Locked) 
        { 
         SQLite3.sqlite3_sleep(250); 
        } 
       } while (rc == SQLite.Net.Interop.Result.OK || rc == SQLite.Net.Interop.Result.Busy || rc == SQLite.Net.Interop.Result.Locked); 

       /* Release resources allocated by backup_init(). */ 
       SQLite3.sqlite3_backup_finish(pBackup); 
      } 

      debug += SQLite3.sqlite3_extended_errcode(pBackup); 
     } 

     /* Close the database connection opened on database file zFilename 
     ** and return the result of this function. */ 
     SQLite3.Close(pFile); 

     return debug; 
    } 

Antwort

1

Nach dem Code-Snippet, verwenden Sie die SQLite.Net-PCL nuget Paket.

Erstens, ich kann nicht reproduzieren Ihr Problem mit dem obigen Code, ich kann init und erhalten Sie die pBackup Objekt.

Zweitens brauchen Sie eigentlich keine so komplexe Möglichkeit, die SQLite-Datei in der uwp-App zu sichern. Die SQLite-Sicherung hat drei Möglichkeiten, und eine davon besteht darin, die Datenbankdatei mit einem externen Tool zu kopieren. In uwp gibt es APIs, die die Datei kopieren können. Sie können die CopyAsync-Methode der StorageFile-Klasse verwenden, um die Datenbankdatei zu sichern. Zum Beispiel:

public static async void BackupDBByCopy() 
{ 
    StorageFolder localfolder = ApplicationData.Current.LocalFolder;   
    StorageFile dboriginal = await localfolder.GetFileAsync("DB.sqlite");   
    await dboriginal.CopyAsync(localfolder, "DBBACKUP.sqlite", NameCollisionOption.ReplaceExisting); 
}