protected void RegisterResultsEventHandlers(Models.Restore restore, TransferResults results) { RestoredFileRepository daoRestoredFile = new RestoredFileRepository(); BackupedFileRepository daoBackupedFile = new BackupedFileRepository(); results.Failed += (object sender, TransferFileProgressArgs args) => { Models.RestoredFile restoredFile = daoRestoredFile.GetByRestoreAndPath(restore, args.FilePath); restoredFile.TransferStatus = TransferStatus.FAILED; restoredFile.UpdatedAt = DateTime.UtcNow; daoRestoredFile.Update(restoredFile); var message = string.Format("Failed {0} - {1}", args.FilePath, args.Exception != null ? args.Exception.Message : "Unknown reason"); Warn(message); //StatusInfo.Update(BackupStatusLevel.ERROR, message); OnUpdate(new RestoreOperationEvent { Status = RestoreOperationStatus.Updated, Message = message, TransferStatus = TransferStatus.FAILED }); }; results.Canceled += (object sender, TransferFileProgressArgs args) => { Models.RestoredFile restoredFile = daoRestoredFile.GetByRestoreAndPath(restore, args.FilePath); restoredFile.TransferStatus = TransferStatus.CANCELED; restoredFile.UpdatedAt = DateTime.UtcNow; daoRestoredFile.Update(restoredFile); var message = string.Format("Canceled {0} - {1}", args.FilePath, args.Exception != null ? args.Exception.Message : "Unknown reason"); Warn(message); //StatusInfo.Update(BackupStatusLevel.ERROR, message); OnUpdate(new RestoreOperationEvent { Status = RestoreOperationStatus.Updated, Message = message, TransferStatus = TransferStatus.CANCELED }); }; results.Completed += (object sender, TransferFileProgressArgs args) => { Models.RestoredFile restoredFile = daoRestoredFile.GetByRestoreAndPath(restore, args.FilePath); restoredFile.TransferStatus = TransferStatus.COMPLETED; restoredFile.UpdatedAt = DateTime.UtcNow; daoRestoredFile.Update(restoredFile); // Only set original modified date if the restored file is the latest version whose transfer is completed, // otherwise, keep the date the OS/filesystem gave it. bool isLatestVersion = daoBackupedFile.IsLatestVersion(restoredFile.BackupedFile); if (isLatestVersion) { // Set original LastWriteTime so this file won't be erroneously included in the next Backup. FileManager.SafeSetFileLastWriteTimeUtc(restoredFile.File.Path, restoredFile.BackupedFile.FileLastWrittenAt); } else { // Keep the original LastWriteTime so this file will be included in the next backup. } var message = string.Format("Completed {0}", args.FilePath); Info(message); OnUpdate(new RestoreOperationEvent { Status = RestoreOperationStatus.Updated, Message = message, TransferStatus = TransferStatus.COMPLETED }); }; results.Started += (object sender, TransferFileProgressArgs args) => { Models.RestoredFile restoredFile = daoRestoredFile.GetByRestoreAndPath(restore, args.FilePath); restoredFile.TransferStatus = TransferStatus.RUNNING; restoredFile.UpdatedAt = DateTime.UtcNow; daoRestoredFile.Update(restoredFile); var message = string.Format("Started {0}", args.FilePath); Info(message); OnUpdate(new RestoreOperationEvent { Status = RestoreOperationStatus.Updated, Message = message }); }; results.Progress += (object sender, TransferFileProgressArgs args) => { #if DEBUG var message = string.Format("Progress {0}% {1} ({2}/{3} bytes)", args.PercentDone, args.FilePath, args.TransferredBytes, args.TotalBytes); //Info(message); #endif OnUpdate(new RestoreOperationEvent { Status = RestoreOperationStatus.Updated, Message = null }); }; }
// // 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); }