private IEnumerable <BackupItemReference> GetReverseBackupSequence( DateTime?minBackupEndTime, DateTime?restoreTargetTime, IEnumerable <BackupFileInfo> reverseBackupFileSequence) { BackupItemReference result = null; var sequence = reverseBackupFileSequence.GetEnumerator(); while (sequence.MoveNext() && result == null) { Check.DoCheckOperationValid(sequence.Current.IsDatabase); var header = ParseBackupHeader(sequence.Current.FileInfo); var suitableItems = header.ValidItems .OrderByDescending(i => i.BackupEndTime) .Where(b => !restoreTargetTime.HasValue || b.BackupEndTime < restoreTargetTime.Value) .Where(b => !minBackupEndTime.HasValue || b.BackupEndTime >= minBackupEndTime.Value); foreach (var item in suitableItems) { yield return(new BackupItemReference() { BackupItem = item, FileHeader = header }); } } }
public void Restore() { Check.DoCheckOperationValid(IsPrepared, "Restorer is not prepared"); Log.InfoFormat("Restoring {0}, Target Time: {1}" , DatabaseName, TargetTime.HasValue ? TargetTime.Value.ToString("yy-MM-dd HH:mm:ss:fff") : "Latest"); if (HaveItemsToRestore) { var originalUserAccess = DatabaseUserAccess.Multiple; if (_preExistingDatabase) { if (Database.Status == DatabaseStatus.Restoring) { ForceRecoveringDatabase(); } if (_preExistingDatabase) { originalUserAccess = Database.DatabaseOptions.UserAccess; Database.DatabaseOptions.UserAccess = DatabaseUserAccess.Single; Database.Alter(TerminationClause.RollbackTransactionsImmediately); } } try { foreach (var item in _backupItems) { Restore(item); LastRestoredBackup = item; } Server.ConnectionContext.ExecuteNonQuery($"restore database [{DatabaseName}] with recovery;"); Log.InfoFormat("Database {0} restored successfully", DatabaseName); } catch (Exception e) { Log.ErrorFormat("Exception restoring {0}: {1}", _databaseName, e); throw; } finally { if (_preExistingDatabase) { Log.InfoFormat("Setting {0} user access to original value {1}", DatabaseName, originalUserAccess); Database.DatabaseOptions.UserAccess = originalUserAccess; Database.Alter(); } } } }