ti034
ti034

Reputation: 301

SQLite Backup in UWP C#

I am trying to create a database backup for SQLite3 in my UWP app. Based on the Online Backup API from SQLite (https://www.sqlite.org/backup.html), I have written the method below. backup_init is returning extended error code 7. Definition from SQLite documentation:

(7) SQLITE_NOMEM

The SQLITE_NOMEM result code indicates that SQLite was unable to allocate all >the memory it needed to complete the operation. In other words, an internal >call to sqlite3_malloc() or sqlite3_realloc() has failed in a case where the >memory being allocated was required in order to continue the operation.

I am not familiar with pointers in C# and am thinking I have an error with them. Any help is appreciated.

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

Upvotes: 2

Views: 1119

Answers (1)

Sunteen Wu
Sunteen Wu

Reputation: 10627

According to your code snippet, you are using the SQLite.Net-PCL nuget package.

Firstly, I cannot reproduce your issue with the code above, I can init and get the pBackup object.

Secondly, actually you don't need such a complex way to back up the SQLite file in uwp app. SQLite back up has three ways and one of them is to copy the database file using an external tool . In uwp, there are APIs can copy the file. You can use the CopyAsync method of StorageFile class to back up the database file. For example:

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);
}

Upvotes: 2

Related Questions