Exemple #1
0
        /// <summary>
        /// Sets prunable backups in set.
        /// </summary>
        /// <param name="set">The set of backups for a given database.</param>
        /// <returns></returns>
        public void FlagPrunableBackupsInSet(IEnumerable <BakModel> set)
        {
            // Ignore set with 0 or 1 entries
            if (set.Count() < 2)
            {
                foreach (var backup in set)
                {
                    backup.Prunable = false;
                }

                return;
            }

            // Make sure the set is ordered (and most recent first)
            set = set.OrderByDescending(x => x.Created);

            var mostRecentBackupDate = set.First().Created;

            var startOfWeek = mostRecentBackupDate.Date.StartOfWeek(DayOfWeek.Sunday);

            var twoWeeksFromStart      = mostRecentBackupDate.AddDays(-2 * 7).Date;
            var eightWeeksFromStart    = startOfWeek.AddDays(-2 * 4 * 7).Date;
            var fiftyTwoWeeksFromStart = startOfWeek.AddDays(-52 * 7).Date;

            var keepOneDaily                   = new List <BakModel>();
            var keepFirstSundayWeekly          = new List <BakModel>();
            var keepFirstAndThridSundayMonthly = new List <BakModel>();
            var keepFirstSundayYearly          = new List <BakModel>();

            string databaseName = null;

            foreach (var backup in set)
            {
                // Make sure there is only one database
                if (databaseName != backup.DatabaseName)
                {
                    if (databaseName != null && databaseName != backup.DatabaseName)
                    {
                        throw new ArgumentException("More than one database name in the set", "set");
                    }

                    databaseName = backup.DatabaseName;
                }

                if (backup.Created.Date >= twoWeeksFromStart)
                {
                    keepOneDaily.Add(backup);
                }
                else if (backup.Created.Date >= eightWeeksFromStart && backup.Created.Date >= fiftyTwoWeeksFromStart)
                {
                    keepFirstSundayWeekly.Add(backup);
                }
                else if (backup.Created.Date >= fiftyTwoWeeksFromStart.Date)
                {
                    keepFirstAndThridSundayMonthly.Add(backup);
                }
                else
                {
                    keepFirstSundayYearly.Add(backup);
                }
            }

            // Keep all backups made in the last 7 days
            foreach (var backup in keepOneDaily)
            {
                backup.Prunable = false;
            }

            var calendar = new JulianCalendar();

            // Keep Sundays for a month
            var weekGrouping =
                keepFirstSundayWeekly.GroupBy(
                    x =>
                    new
            {
                x.Created.Year,
                WeekNumber = calendar.GetWeekOfYear(x.Created, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)
            });

            foreach (var week in weekGrouping)
            {
                if (week.Count() > 1)
                {
                    KeepDayOccurences(week, DayOfWeek.Sunday, 0);
                }
                else
                {
                    week.First().Prunable = false;
                }
            }

            // Keep first and third Sunday of month
            var monthGrouping = keepFirstAndThridSundayMonthly.GroupBy(x => new { x.Created.Year, x.Created.Month });

            foreach (var month in monthGrouping)
            {
                if (month.Count() > 1)
                {
                    KeepDayOccurences(month, DayOfWeek.Sunday, new[] { 0, 2 });
                }
                else
                {
                    month.First().Prunable = false;
                }
            }

            // Keep first backup of each year
            var yearGrouping = keepFirstSundayYearly.GroupBy(x => new { x.Created.Year });

            foreach (var year in yearGrouping)
            {
                if (year.Count() > 1)
                {
                    // Order year set ascending
                    KeepDayOccurences(year, DayOfWeek.Sunday, 0);
                }
                else
                {
                    // Last of ordered by DESC = first
                    year.Last().Prunable = false;
                }
            }

            // Make sure only the most recent backup of 'Keeper' days is kept.
            KeepOnePerDay(set);
        }