Exemple #1
0
        private IEnumerable <BackupItemReference> GetReverseBackupSequence(
            DateTime?minBackupEndTime, DateTime?restoreTargetTime, SupportedBackupType backupType)
        {
            var reverseFileSequence = BackupFileCatalog.GetReverseBackupSequence(restoreTargetTime, backupType);

            return(GetReverseBackupSequence(minBackupEndTime, restoreTargetTime, reverseFileSequence));
        }
Exemple #2
0
        /// <summary>
        ///     Constructor of immutable instance.
        /// </summary>
        /// <param name="backupType">
        ///     Type of backups contained in this file.
        /// </param>
        /// <param name="startTime">
        ///     Explicitly defined start of the period in which backups were written into the file. If null, the start time will be taken from creation time.
        /// </param>
        /// <param name="endTime">
        ///     Explicitly defined end of the period in which backups were written into the file.
        /// </param>
        /// <param name="fileInfo">
        /// </param>
        /// <remarks>
        ///     Note that <see cref="StartTime"/> will always have a value while <see cref="EndTime"/> may be null. This is because start time is more important and
        ///     must be figured out in any case while EndTime is not essential and only beneficial for optimization.
        ///     If simultaneous log and database backups are allowed, without end time we only need to start from first log prior to last database backup.
        ///     However, if there is no simultaneous backup, things are much easier and we can work without end time.
        ///     What happens if diff backup is marked with the hour when it is made and single daily log backup is marked with start of day timestamp?
        ///     Then we need end time or have to start from first log backup file prior to the database backup.
        /// </remarks>
        public BackupFileInfo(SupportedBackupType backupType, DateTime?startTime, DateTime?endTime, FileInfo fileInfo)
        {
            Check.DoRequireArgumentNotNull(fileInfo, "fileInfo");
            Check.DoCheckArgument(backupType != SupportedBackupType.None, "Invalid file type");

            BackupType = backupType;

            FileInfo = fileInfo;

            PeriodStartDeclaredExplicitly = startTime.HasValue;
            StartTime = startTime ?? fileInfo.CreationTime;

            PeriodEndDeclaredExplicitly = endTime.HasValue;
            EndTime = endTime ?? fileInfo.LastWriteTime;
        }
Exemple #3
0
        /// <summary>
        ///     Add new backup type mapping.
        /// </summary>
        /// <param name="nameSuffix">
        ///     Suffix of backup files, including extension, case insensitive
        /// </param>
        /// <param name="backupType">
        ///     Backup type
        /// </param>
        /// <param name="timePeriodExtractor">
        ///     Object implementing extraction of relevant information from file name, such as time period.
        /// </param>
        public void AddType(string nameSuffix, SupportedBackupType backupType, ITimePeriodFromFilesystemNameExtractor timePeriodExtractor)
        {
            Check.DoRequireArgumentNotNull(nameSuffix, "nameSuffix");
            Check.DoRequireArgumentNotNull(timePeriodExtractor, "timePeriodExtractor");
            Check.DoCheckArgument(null == GetTypeInfo(backupType), string.Format("Parser for {0} already mapped", backupType));
            Check.DoCheckArgument(backupType != SupportedBackupType.None, "Invalid backup type (None)");

            var intersectedType = _backupTypes.Values.Where(
                i => i.FileNameSuffix.EndsWith(nameSuffix, StringComparison.InvariantCultureIgnoreCase) ||
                nameSuffix.EndsWith(i.FileNameSuffix, StringComparison.InvariantCultureIgnoreCase))
                                  .FirstOrDefault();

            Check.DoCheckArgument(
                intersectedType == null
                , () => string.Format("Suffix {0} for {1} conflicts with suffix {2} for type {3}"
                                      , nameSuffix, backupType, intersectedType.FileNameSuffix, intersectedType.BackupType));

            var newTypeInfo = new BackupTypeInfo()
            {
                FileNameSuffix = nameSuffix, BackupType = backupType, TimePeriodExtractor = timePeriodExtractor
            };

            _backupTypes.Add(backupType, newTypeInfo);
        }
Exemple #4
0
        /// <summary>
        ///     Get reverse sequence of backup files which started before <paramref name="pointInTime"/>.
        /// </summary>
        /// <param name="pointInTime">
        ///     Point in time before which the database backup to be found must have started; null for latest.
        /// </param>
        /// <param name="backupType">
        ///     Type of backup files to find.
        /// </param>
        /// <returns>
        ///     Sequence ordered by file start time <see cref="BackupFileInfo.StartTime"/> descending.
        /// </returns>
        /// <remarks>
        ///     Note that database backup (diff or full) restores database to a point at which reading from data files while performing backup finished,
        ///     which is in general some time after the backup start time. Thus in order to restore precisely to a point in time within the time period when
        ///     database backup Bn was being performed, one must go back and restore previous database backup followed by log backups up to and including
        ///     the one taken after the Bn backup. This is the reason to expose this method rather than provide just a method to retrieve the sequence
        ///     of files to use for restoration. One must analyze the contents of the database backup (diff or full) in order to understand whether
        ///     one can restore to a point in time within that file's time period. If not suitable, one must go back and check previous backup.
        ///     Passing <see cref="BackupFileInfo.StartTime"/> the caller shall never get the same file back; thus it is possible to iterate backwards.
        /// </remarks>
        public IEnumerable <BackupFileInfo> GetReverseBackupSequence(DateTime?pointInTime, SupportedBackupType backupType)
        {
            Check.DoCheckArgument(backupType != SupportedBackupType.None);

            foreach (var folder in GetPriorFolderSequence(pointInTime))
            {
                var files = folder.AllFiles
                            .Where(f => f.BackupType == backupType)
                            .Where(f => !pointInTime.HasValue || f.StartTime < pointInTime.Value)
                            .OrderByDescending(f => f.StartTime);

                foreach (var file in files)
                {
                    yield return(file);
                }
            }
        }
Exemple #5
0
        private BackupTypeInfo GetTypeInfo(SupportedBackupType backupType)
        {
            _backupTypes.TryGetValue(backupType, out var result);

            return(result);
        }