private async void ExecuteMoveDatabaseCommand() { var result = await ViewServices.Execute <IMoveDatabaseService, MoveDatabaseResult>(); if (string.IsNullOrWhiteSpace(result.Path)) { return; } if (result.OverwriteExisting || !File.Exists(result.Path)) { await ViewServices.Execute <IProgressService>(new ProgressServiceArgs( report => { SQLiteBackupCallback callback = (source, sourceName, destination, destinationName, pages, remainingPages, totalPages, retry) => { report.SetProgress(totalPages - remainingPages, totalPages); return(true); }; SQLiteConnectionStringBuilder sb = new SQLiteConnectionStringBuilder { DataSource = result.Path }; using (SQLiteConnection destConnection = new SQLiteConnection(sb.ToString())) { destConnection.Open(); var connection = App.Session.Connection as SQLiteConnection; Debug.Assert(connection != null, "connection != null"); connection.BackupDatabase(destConnection, "main", "main", -1, callback, 100); } } )); } Settings.Set(SettingKeys.DatabasePath, result.Path); Application.Current.Shutdown(); Process.Start(Assembly.GetExecutingAssembly().Location); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region Backup API Members /// <summary> /// Backs up the database, using the specified database connection as the /// destination. /// </summary> /// <param name="destination">The destination database connection.</param> /// <param name="destinationName">The destination database name.</param> /// <param name="sourceName">The source database name.</param> /// <param name="pages"> /// The number of pages to copy or negative to copy all remaining pages. /// </param> /// <param name="callback"> /// The method to invoke between each step of the backup process. This /// parameter may be null (i.e. no callbacks will be performed). /// </param> /// <param name="retryMilliseconds"> /// The number of milliseconds to sleep after encountering a locking error /// during the backup process. A value less than zero means that no sleep /// should be performed. /// </param> public void BackupDatabase( SQLiteConnection destination, string destinationName, string sourceName, int pages, SQLiteBackupCallback callback, int retryMilliseconds ) { CheckDisposed(); if (_connectionState != ConnectionState.Open) throw new InvalidOperationException( "Source database is not open."); if (destination == null) throw new ArgumentNullException("destination"); if (destination._connectionState != ConnectionState.Open) throw new ArgumentException( "Destination database is not open.", "destination"); if (destinationName == null) throw new ArgumentNullException("destinationName"); if (sourceName == null) throw new ArgumentNullException("sourceName"); SQLiteBase sqliteBase = _sql; if (sqliteBase == null) throw new InvalidOperationException( "Connection object has an invalid handle."); SQLiteBackup backup = null; try { backup = sqliteBase.InitializeBackup( destination, destinationName, sourceName); /* throw */ bool retry; while (sqliteBase.StepBackup(backup, pages, out retry)) /* throw */ { // // NOTE: If a callback was supplied by our caller, call it. // If it returns false, halt the backup process. // if ((callback != null) && !callback(this, sourceName, destination, destinationName, pages, sqliteBase.RemainingBackup(backup), sqliteBase.PageCountBackup(backup), retry)) { break; } // // NOTE: If we need to retry the previous operation, wait for // the number of milliseconds specified by our caller // unless the caller used a negative number, in that case // skip sleeping at all because we do not want to block // this thread forever. // if (retry && (retryMilliseconds >= 0)) System.Threading.Thread.Sleep(retryMilliseconds); // // NOTE: There is no point in calling the native API to copy // zero pages as it does nothing; therefore, stop now. // if (pages == 0) break; } } #if !PLATFORM_COMPACTFRAMEWORK catch (Exception e) { if ((_flags & SQLiteConnectionFlags.LogBackup) == SQLiteConnectionFlags.LogBackup) { SQLiteLog.LogMessage(0, String.Format( "Caught exception while backing up database: {0}", e)); } throw; } #endif finally { if (backup != null) sqliteBase.FinishBackup(backup); /* throw */ } }
/// <summary>Backs up the database, using the specified database connection as the destination.</summary> /// <param name="destination">The destination database connection.</param> /// <param name="destinationName">The destination database name (usually <c>"main"</c>).</param> /// <param name="sourceName">The source database name (usually <c>"main"</c>).</param> /// <param name="pages">The number of pages to copy, or negative to copy all remaining pages.</param> /// <param name="callback">The method to invoke between each step of the backup process. This /// parameter may be <c>null</c> (i.e., no callbacks will be performed).</param> /// <param name="retryMilliseconds">The number of milliseconds to sleep after encountering a locking error /// during the backup process. A value less than zero means that no sleep should be performed.</param> public void BackupDatabase(SQLiteConnection destination, string destinationName, string sourceName, int pages, SQLiteBackupCallback callback, int retryMilliseconds) { VerifyNotDisposed(); if (m_connectionState != ConnectionState.Open) { throw new InvalidOperationException("Source database is not open."); } if (destination == null) { throw new ArgumentNullException("destination"); } if (destination.m_connectionState != ConnectionState.Open) { throw new ArgumentException("Destination database is not open.", "destination"); } if (destinationName == null) { throw new ArgumentNullException("destinationName"); } if (sourceName == null) { throw new ArgumentNullException("sourceName"); } if (pages == 0) { throw new ArgumentException("pages must not be 0.", "pages"); } using (SqliteBackupHandle backup = NativeMethods.sqlite3_backup_init(destination.m_db, ToNullTerminatedUtf8(destinationName), m_db, ToNullTerminatedUtf8(sourceName))) { if (backup == null) { throw new SQLiteException(NativeMethods.sqlite3_errcode(m_db), m_db); } while (true) { SQLiteErrorCode error = NativeMethods.sqlite3_backup_step(backup, pages); if (error == SQLiteErrorCode.Done) { break; } else if (error == SQLiteErrorCode.Ok || error == SQLiteErrorCode.Busy || error == SQLiteErrorCode.Locked) { bool retry = error != SQLiteErrorCode.Ok; if (callback != null && !callback(this, sourceName, destination, destinationName, pages, NativeMethods.sqlite3_backup_remaining(backup), NativeMethods.sqlite3_backup_pagecount(backup), retry)) { break; } if (retry && retryMilliseconds > 0) { Thread.Sleep(retryMilliseconds); } } else { throw new SQLiteException(error, m_db); } } } }
public void BackupDatabase(SQLiteConnection destination, string destinationName, string sourceName, int pages = -1, SQLiteBackupCallback callback = null, int retryMilliseconds = -1) { MakeConnection(connection => { connection.BackupDatabase(destination, destinationName, sourceName, pages, callback, retryMilliseconds); return(true); }); }
/// <summary>Backs up the database, using the specified database connection as the destination.</summary> /// <param name="destination">The destination database connection.</param> /// <param name="destinationName">The destination database name (usually <c>"main"</c>).</param> /// <param name="sourceName">The source database name (usually <c>"main"</c>).</param> /// <param name="pages">The number of pages to copy, or negative to copy all remaining pages.</param> /// <param name="callback">The method to invoke between each step of the backup process. This /// parameter may be <c>null</c> (i.e., no callbacks will be performed).</param> /// <param name="retryMilliseconds">The number of milliseconds to sleep after encountering a locking error /// during the backup process. A value less than zero means that no sleep should be performed.</param> public void BackupDatabase(SQLiteConnection destination, string destinationName, string sourceName, int pages, SQLiteBackupCallback callback, int retryMilliseconds) { VerifyNotDisposed(); if (m_connectionState != ConnectionState.Open) throw new InvalidOperationException("Source database is not open."); if (destination == null) throw new ArgumentNullException("destination"); if (destination.m_connectionState != ConnectionState.Open) throw new ArgumentException("Destination database is not open.", "destination"); if (destinationName == null) throw new ArgumentNullException("destinationName"); if (sourceName == null) throw new ArgumentNullException("sourceName"); if (pages == 0) throw new ArgumentException("pages must not be 0.", "pages"); using (SqliteBackupHandle backup = NativeMethods.sqlite3_backup_init(destination.m_db, ToNullTerminatedUtf8(destinationName), m_db, ToNullTerminatedUtf8(sourceName))) { if (backup == null) throw new SQLiteException(NativeMethods.sqlite3_errcode(m_db), m_db); while (true) { SQLiteErrorCode error = NativeMethods.sqlite3_backup_step(backup, pages); if (error == SQLiteErrorCode.Done) { break; } else if (error == SQLiteErrorCode.Ok || error == SQLiteErrorCode.Busy || error == SQLiteErrorCode.Locked) { bool retry = error != SQLiteErrorCode.Ok; if (callback != null && !callback(this, sourceName, destination, destinationName, pages, NativeMethods.sqlite3_backup_remaining(backup), NativeMethods.sqlite3_backup_pagecount(backup), retry)) break; if (retry && retryMilliseconds > 0) Thread.Sleep(retryMilliseconds); } else { throw new SQLiteException(error, m_db); } } } }