Example #1
0
        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);
                    }
                }
            }
        }
Example #4
0
 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);
					}
				}
			}
		}