/// <exception cref="System.InvalidOperationException"> /// Thrown when the previous backup operation has not finished yet. /// </exception> /// <exception cref="System.NotImplementedException"> /// Thrown when the previous backup operation has not finished yet and it's marked to be resumed (`options.Resume` is `true`). /// The restore operation doesn't support resume. /// </exception> private RestoreOperation CreateRestoreOperation(Models.RestorePlan plan) { var dao = new RestoreRepository(); Models.Restore latest = dao.GetLatestByPlan(plan); MustResumeLastOperation = latest != null && latest.NeedsResume(); if (MustResumeLastOperation && Options.Resume) { throw new NotImplementedException("The restore operation still does not support resuming."); } if (MustResumeLastOperation && !Options.Resume) { string message = string.Format("The restore (#{0}) has not finished yet." + " If it's still running, please, wait until it finishes," + " otherwise you should resume it manually.", latest.Id); throw new InvalidOperationException(message); } // Create new restore or resume the last unfinished one. RestoreOperation obj = /* MustResumeLastOperation * ? new ResumeRestoreOperation(latest) as RestoreOperation * : */new NewRestoreOperation(plan) as RestoreOperation; obj.Updated += (sender2, e2) => RestoreUpdateStatsInfo(e2.Status, e2.TransferStatus); //obj.EventLog = ... //obj.TransferListControl = ... RestoreUpdateStatsInfo(RestoreOperationStatus.Unknown, TransferStatus.STOPPED); return(obj); }
public void Undo() { Assert.IsFalse(IsSaved); RestoreRepository daoRestore = new RestoreRepository(); daoRestore.Refresh(Restore); }
public async Task <FileVersionerResults> DoRestore(Models.Restore restore, LinkedList <CustomVersionedFile> files, bool newRestore) { Assert.IsNotNull(restore); Assert.AreEqual(TransferStatus.RUNNING, restore.Status); Assert.IsNotNull(files); Results.Reset(); await ExecuteOnBackround(() => { RestoreRepository daoRestore = new RestoreRepository(); Restore = daoRestore.Get(restore.Id); RestorePlanFileRepository daoRestorePlanFile = new RestorePlanFileRepository(); AllFilesFromPlan = daoRestorePlanFile.GetAllByPlan(restore.RestorePlan).ToDictionary <Models.RestorePlanFile, string>(p => p.Path); Execute(restore, files, newRestore); Save(); }, CancellationToken); return(Results); }
// // Summary: // 1. Create `RestorePlanFile`s and `RestoredFile`s as necessary and add them to the `Restore`. // 2. Insert/Update `Restore` and its `RestorededFile`s into the database, also saving // the `RestorePlanFile`s instances that may have been changed by step 1.2. // 3. Create versioned files and remove files that won't belong to this restore. // public void Save() { Assert.IsFalse(IsSaved); ISession session = NHibernateHelper.GetSession(); RestoreRepository daoRestore = new RestoreRepository(session); RestorePlanFileRepository daoRestorePlanFile = new RestorePlanFileRepository(session); RestoredFileRepository daoRestoredFile = new RestoredFileRepository(session); BackupPlanPathNodeRepository daoBackupPlanPathNode = new BackupPlanPathNodeRepository(session); var FilesToTrack = SuppliedFiles; var FilesToInsertOrUpdate = FilesToTrack; BlockPerfStats stats = new BlockPerfStats(); using (ITransaction tx = session.BeginTransaction()) { try { // ------------------------------------------------------------------------------------ stats.Begin("STEP 1"); // 1. Create `RestorePlanFile`s and `RestoredFile`s as necessary and add them to the `Restore`. foreach (Models.RestorePlanFile entry in FilesToInsertOrUpdate) { // Throw if the operation was canceled. CancellationToken.ThrowIfCancellationRequested(); // 1.1 - Insert/Update RestorePlanFile's and RestoredFile's if they don't exist yet. // IMPORTANT: It's important that we guarantee the referenced `RestorePlanFile` has a valid `Id` // before we reference it elsewhere, otherwise NHibernate won't have a valid value to put on // the `restore_plan_file_id` column. daoRestorePlanFile.InsertOrUpdate(tx, entry); // Guarantee it's saved Models.RestoredFile restoredFile = daoRestoredFile.GetByRestoreAndPath(Restore, entry.Path); if (restoredFile == null) // If we're resuming, this should already exist. { // Create `RestoredFile`. Models.BackupedFile backupedFile = entry.VersionedFile.UserData as Models.BackupedFile; restoredFile = new Models.RestoredFile(Restore, entry, backupedFile); } restoredFile.UpdatedAt = DateTime.UtcNow; daoRestoredFile.InsertOrUpdate(tx, restoredFile); Restore.Files.Add(restoredFile); //daoRestore.Update(tx, Restore); ProcessBatch(session); } ProcessBatch(session, true); stats.End(); // ------------------------------------------------------------------------------------ stats.Begin("STEP 2"); // 2. Insert/Update `Restore` and its `RestorededFile`s into the database, also saving // the `RestorePlanFile`s instances that may have been changed by step 1.2. { daoRestore.Update(tx, Restore); } ProcessBatch(session, true); stats.End(); // ------------------------------------------------------------------------------------ tx.Commit(); } catch (OperationCanceledException) { tx.Rollback(); // Rollback the transaction throw; } catch (Exception) { tx.Rollback(); // Rollback the transaction throw; } finally { //session.Close(); if (session.IsConnected) { session.Disconnect(); } } } IsSaved = true; // 3. Create versioned files and remove files that won't belong to this restore. TransferSet.Files = GetFilesToTransfer(Restore, SuppliedFiles); }
private void OnControlPlanQuery(object sender, ServerCommandEventArgs e) { string planType = e.Command.GetArgumentValue <string>("planType"); Int32 planId = e.Command.GetArgumentValue <Int32>("planId"); ValidatePlanType(planType); bool isRunning = IsPlanRunning(planType, planId); bool needsResume = false; bool isFinished = false; bool isBackup = planType.Equals(PlanTypeEnum.BACKUP.ToString().ToLowerInvariant()); bool isRestore = planType.Equals(PlanTypeEnum.RESTORE.ToString().ToLowerInvariant()); // Report to GUI. Commands.GuiReportPlanStatus report = new Commands.GuiReportPlanStatus(); if (isBackup) { BackupRepository daoBackup = new BackupRepository(); Models.Backup latest = daoBackup.GetLatestByPlan(new Models.BackupPlan { Id = planId }); needsResume = latest != null && latest.NeedsResume(); isFinished = latest != null && latest.IsFinished(); if (isRunning) { report.StartedAt = latest.StartedAt; } else if (isFinished) { report.FinishedAt = latest.FinishedAt; } } else if (isRestore) { RestoreRepository daoRestore = new RestoreRepository(); Models.Restore latest = daoRestore.GetLatestByPlan(new Models.RestorePlan { Id = planId }); needsResume = latest != null && latest.NeedsResume(); isFinished = latest != null && latest.IsFinished(); if (isRunning) { report.StartedAt = latest.StartedAt; } else if (isFinished) { report.FinishedAt = latest.FinishedAt; } } bool isInterrupted = !isRunning && needsResume; Commands.OperationStatus status; // The condition order below is important because more than one flag might be true. if (isInterrupted) { status = Commands.OperationStatus.INTERRUPTED; } else if (needsResume) { status = Commands.OperationStatus.RESUMED; } else if (isRunning) { status = Commands.OperationStatus.STARTED; } else { status = Commands.OperationStatus.NOT_RUNNING; } report.Status = status; Handler.Send(e.Context, Commands.GuiReportOperationStatus(planType, planId, report)); }