public static void Add(BackupModel model) { using var dbContext = new BackupDbContext(dbOptions); var col = new BackupCollection { Title = model.Title }; dbContext.BackupCollections.Add(col); dbContext.SaveChanges(); model.Id = col.BackupCollectionId; }
public static BackupModel Get(string title) { using var dbContext = new BackupDbContext(dbOptions); var col = dbContext.BackupCollections.SingleOrDefault(col => col.Title == title); if (col == null) { return(null); } var model = new BackupModel { Id = col.BackupCollectionId, Title = col.Title }; model.SourceDirectory = col.SourceDirectory; model.Started = col.Started?.ToLocalTime(); model.Finished = col.Finished?.ToLocalTime(); model.AutomaticBackup = col.AutomaticBackup; model.IncludePattern = col.IncludePattern; model.ExcludePattern = col.ExcludePattern; var sourceFiles = dbContext.SourceFiles.Where(sf => sf.BackupCollectionId == model.Id); foreach (var sf in sourceFiles) { model.SourceFiles.Add(sf.PathName); } var destDirs = dbContext.DestinationDirectories.Where(dd => dd.BackupCollectionId == model.Id); model.Copied = 0; model.Failed = 0; foreach (var dd in destDirs) { model.DestinationDirectories.Add(dd.PathName); var status = new BackupStatus(); status.Started = dd.Started; status.Finished = dd.Finished; status.Copied = dd.Copied; status.Failed = dbContext.CopyFailures .Where(cf => cf.DestinationDirectoryId == dd.DestinationDirectoryId) .Count(); model.Status[dd.PathName] = status; model.Copied += status.Copied; model.Failed += status.Failed; } return(model); }
public static DateTime?Backup(BackupModel model, IProgress <double> progress, CancellationToken cancellationToken) { progress?.Report(0.0); DateTime?nextBackup = null; using var dbContext = new BackupDbContext(dbOptions); string dateFolder = DateTime.Now.ToString(DATE_FOLDER_FOMRAT); var col = dbContext.BackupCollections.SingleOrDefault(col => col.Title == model.Title); if (col == null) { throw new ArgumentException($"Backup collection '{model.Title}' not found."); } col.Started = DateTime.UtcNow; dbContext.Entry(col) .Collection(col => col.DestinationDirectories) .Load(); dbContext.Entry(col) .Collection(col => col.SourceFiles) .Load(); int total = col.SourceFiles.Count * col.DestinationDirectories.Count; int current = 0; foreach (var dd in col.DestinationDirectories) { if (cancellationToken.IsCancellationRequested) { break; } dbContext.Entry(dd) .Collection(dd => dd.DestinationFiles) .Load(); dbContext.Entry(dd) .Collection(dd => dd.CopyFailures) .Load(); foreach (var cf in dd.CopyFailures) { dbContext.CopyFailures.Remove(cf); } dd.Started = DateTime.UtcNow; dd.Copied = 0; dd.CopyFailures.Clear(); if (!Directory.Exists(dd.PathName) && col.SourceFiles.Count > 0) { current += col.SourceFiles.Count; double percent = total > 0 ? current * 100.0 / total : 0.0; progress?.Report(percent); dd.CopyFailures.Add(new CopyFailure { SourceFileId = col.SourceFiles[0].SourceFileId, ErrorMessage = $"Destination directory '{dd.PathName}' does not exist or cannot be accessed." }); dd.Finished = DateTime.UtcNow; continue; } var baseDir = GetBaseDirectory(col.SourceFiles); if (!string.IsNullOrEmpty(baseDir) && !string.IsNullOrEmpty(col.BaseDirectory) && baseDir != col.BaseDirectory) { MoveDestinationFilesToHistoryDirectory(dbContext, dd, dateFolder); } col.BaseDirectory = baseDir; var usedSourceFileIds = new HashSet <long>(); foreach (var sf in col.SourceFiles) { if (cancellationToken.IsCancellationRequested) { break; } if (File.Exists(sf.PathName)) { BackupToDestinationDirectory(sf, baseDir, dd, dateFolder, cancellationToken); usedSourceFileIds.Add(sf.SourceFileId); } current++; double percent = total > 0 ? current * 100.0 / total : 0.0; progress?.Report(percent); } if (cancellationToken.IsCancellationRequested) { break; } MoveDestinationFilesToHistoryDirectory(dbContext, dd, dateFolder, usedSourceFileIds); dd.Finished = DateTime.UtcNow; } col.Finished = DateTime.UtcNow; if (col.AutomaticBackup > 0) { nextBackup = col.Started.Value.AddMinutes(col.AutomaticBackup).ToLocalTime(); } dbContext.SaveChanges(); progress?.Report(100.0); model.Copied = 0; model.Failed = 0; foreach (var dd in col.DestinationDirectories) { model.Copied += dd.Copied; model.Failed += dd.CopyFailures.Count; } return(nextBackup); }
public static DateTime?Update(BackupModel model) { bool changed = false; DateTime?nextBackup = null; using var dbContext = new BackupDbContext(dbOptions); var col = dbContext.BackupCollections .SingleOrDefault(col => col.BackupCollectionId == model.Id); if (col == null) { throw new ArgumentException($"Backup collection with ID {model.Id} not found."); } if (col.Title != model.Title || col.AutomaticBackup != model.AutomaticBackup || col.SourceDirectory != model.SourceDirectory || col.IncludePattern != model.IncludePattern || col.ExcludePattern != model.ExcludePattern) { changed = true; } col.Title = model.Title; col.AutomaticBackup = model.AutomaticBackup; col.SourceDirectory = model.SourceDirectory; col.IncludePattern = model.IncludePattern; col.ExcludePattern = model.ExcludePattern; dbContext.Entry(col) .Collection(col => col.SourceFiles) .Load(); dbContext.Entry(col) .Collection(col => col.DestinationDirectories) .Load(); var existingSourceFiles = new List <string>(); foreach (var sf in col.SourceFiles) { existingSourceFiles.Add(sf.PathName); } var existingDestinationDirectores = new List <string>(); foreach (var dd in col.DestinationDirectories) { existingDestinationDirectores.Add(dd.PathName); } var delDirectories = existingDestinationDirectores .Except(model.DestinationDirectories) .ToList(); foreach (var dd in col.DestinationDirectories) { if (delDirectories.Contains(dd.PathName)) { changed = true; dbContext.Entry(dd) .Collection(dd => dd.CopyFailures) .Load(); foreach (var cf in dd.CopyFailures) { dbContext.CopyFailures.Remove(cf); } dbContext.Entry(dd) .Collection(dd => dd.DestinationFiles) .Load(); foreach (var df in dd.DestinationFiles) { dbContext.DestinationFiles.Remove(df); } dbContext.DestinationDirectories.Remove(dd); } } var delSourceFiles = existingSourceFiles .Except(model.SourceFiles) .ToList(); foreach (var sf in col.SourceFiles) { if (delSourceFiles.Contains(sf.PathName)) { changed = true; dbContext.SourceFiles.Remove(sf); } } var addDirectories = model.DestinationDirectories.Except(existingDestinationDirectores).ToList(); changed |= addDirectories.Any(); foreach (var dname in addDirectories) { col.DestinationDirectories.Add(new DestinationDirectory { PathName = dname }); } var addSourceFiles = model.SourceFiles .Except(existingSourceFiles) .ToList(); changed |= addSourceFiles.Any(); foreach (var fname in addSourceFiles) { col.SourceFiles.Add(new SourceFile { PathName = fname }); } if (col.AutomaticBackup > 0 && col.Started.HasValue) { nextBackup = col.Started.Value.AddMinutes(col.AutomaticBackup).ToLocalTime(); } if (changed) { dbContext.SaveChanges(); } return(nextBackup); }