Reputation: 301
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
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