/// <summary>
        /// Restores an entire database from a full database backup.
        /// </summary>
        /// <param name="connectionDefinition">Connection definition to the intended database server.</param>
        /// <param name="databaseName">Name of the database to restore.</param>
        /// <param name="restoreDetails">The details of how to perform the restore.</param>
        /// <param name="workingDirectory">Working path to take temporary output.</param>
        /// <param name="mongoUtilityDirectory">Path where mongo utilies are located on disk.</param>
        /// <param name="announcer">Optional announcer to log messages about what is happening.</param>
        /// <returns>Task to support async await calling.</returns>
        public static async Task RestoreFullAsync(
            MongoConnectionDefinition connectionDefinition,
            string databaseName,
            RestoreMongoDatabaseDetails restoreDetails,
            string workingDirectory,
            string mongoUtilityDirectory,
            Action <Func <object> > announcer = null)
        {
            new { connectionDefinition }.AsArg().Must().NotBeNull();
            new { databaseName }.AsArg().Must().NotBeNullNorWhiteSpace();
            new { restoreDetails }.AsArg().Must().NotBeNull();

            restoreDetails.ThrowIfInvalid();

            void NullAnnounce(Func <object> announcement)
            {
                /* no-op */
            }

            var localAnnouncer = announcer ?? NullAnnounce;

            localAnnouncer(() => new { Database = databaseName, RestoreDetails = restoreDetails });
            var backupFilePath         = restoreDetails.RestoreFrom.LocalPath;
            var inflatedBackupFilePath = BuildIndividualWorkingPath(workingDirectory, "Restore");
            var restoreFromPath        = Path.Combine(inflatedBackupFilePath, databaseName); // will put in a sub folder by database name that restore does not understand so just exclude

            var directoryArchiveKind   = DirectoryArchiveKind.DotNetZipFile;
            var archiveCompressionKind = ArchiveCompressionKind.Fastest;
            var archiver          = ArchiverFactory.Instance.BuildArchiver(directoryArchiveKind, archiveCompressionKind);
            var archivedDirectory = new ArchivedDirectory(directoryArchiveKind, archiveCompressionKind, backupFilePath, false, Encoding.UTF8.WebName, DateTime.UtcNow);

            localAnnouncer(() => Invariant($"Inflating backup file '{backupFilePath}' to '{inflatedBackupFilePath}'"));
            await archiver.RestoreDirectoryAsync(archivedDirectory, inflatedBackupFilePath);

            var exePath = Path.Combine(mongoUtilityDirectory, "mongorestore.exe");

            localAnnouncer(() => Invariant($"Restoring database '{databaseName}' from '{inflatedBackupFilePath}' using '{exePath}'"));

            var dropSwitchAddIn = restoreDetails.ReplaceOption == ReplaceOption.ReplaceExistingDatabase ? "--drop " : string.Empty;
            var output          = RunProcess(exePath, Invariant($"{dropSwitchAddIn}--host {connectionDefinition.Server} --db {databaseName} --authenticationDatabase {connectionDefinition.AuthenticationDatabaseName ?? databaseName} --username {connectionDefinition.UserName} --password {connectionDefinition.Password} {restoreFromPath}"));

            localAnnouncer(() => output);

            localAnnouncer(() => Invariant($"Cleaning up by removing temp directory '{inflatedBackupFilePath}'"));
            Directory.Delete(inflatedBackupFilePath, true);

            localAnnouncer(() => "Completed successfully.");
        }
Example #2
0
        public void RefreshObjects()
        {
            //Kill metadata thread
            if (metadataGeneratorThread != null)
            {
                metadataGeneratorThread.Abort();
            }

            //Clear objects
            objects.Clear();

            //Discover all
            root = ArchivedDirectory.GetRootDirectory(this, config.archives_dir);

            //Start metadata generator thread
            StartMetadataGeneratorThread();
        }