Example #1
0
        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;
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }