Example #1
0
 [InlineData("Backup_12Nov2013_2043")]              // Wrong timestamp format (missing trailing "Z")
 public void ReturnsNullForNonMatchingDatabaseName(string name)
 {
     Assert.Null(DatabaseBackup <SqlDatabase> .Create(new SqlDatabase()
     {
         name = name
     }));
 }
Example #2
0
        public void ParsesMatchingNameCorrectly(string name, string prefix, string expectedTimestamp)
        {
            var parsed = DatabaseBackup <SqlDatabase> .Create(new SqlDatabase()
            {
                name = name
            });

            Assert.NotNull(parsed);
            Assert.Equal(prefix, parsed.Prefix);
            Assert.Equal(expectedTimestamp, parsed.Timestamp.ToString("s"));
        }
Example #3
0
        protected internal override async Task <JobContinuation> Execute()
        {
            ServerName = String.IsNullOrEmpty(ServerName) ? Utils.GetSqlServerName(Config.Sql.Legacy.DataSource) : ServerName;

            // Capture the current time in case the date changes during invocation
            DateTimeOffset now = DateTimeOffset.UtcNow;

            // Resolve the connection if not specified explicitly
            Log.PreparingToClean(ServerName);

            // Connect to the master database
            using (var sql = CloudContext.Clients.CreateSqlManagementClient(Azure.GetCredentials(throwIfMissing: true)))
            {
                // Get online databases
                Log.GettingDatabaseList(ServerName);
                var dbs = (await sql.Databases.ListAsync(ServerName)).ToList();
                Log.GotDatabases(dbs.Count, ServerName);

                // Determine which of these are backups
                var backups = dbs
                              .Select(d => DatabaseBackup <Database> .Create(d))
                              .Where(b => b != null && String.Equals(NamePrefix, b.Prefix, StringComparison.OrdinalIgnoreCase))
                              .ToList();

                // Start collecting a list of backups we're going to keep
                var keepers = new HashSet <DatabaseBackup <Database> >();

                // Group backups by UTC Day
                var backupsByDate = backups
                                    .GroupBy(b => b.Timestamp.UtcDateTime.Date)
                                    .OrderByDescending(g => g.Key);

                // Keep the last backup from today and the max daily backups if any
                var dailyBackups = backupsByDate
                                   .Take(MaxDailyCopies ?? 1)
                                   .Select(g => g.OrderBy(db => db.Timestamp).Last());
                foreach (var keeper in dailyBackups)
                {
                    keepers.Add(keeper);
                }

                // Keep the most recent backups based on MaxRunningBackups
                foreach (var keeper in backups.OrderByDescending(b => b.Timestamp).Take(MaxRunningCopies ?? 1))
                {
                    keepers.Add(keeper);
                }

                // Report keepers
                foreach (var keeper in keepers)
                {
                    Log.KeepingBackup(keeper.Db.Name);
                }

                // Delete the others!
                foreach (var db in backups.Select(b => b.Db.Name).Except(keepers.Select(b => b.Db.Name), StringComparer.OrdinalIgnoreCase))
                {
                    Log.DeletingBackup(db);
                    if (!WhatIf)
                    {
                        await sql.Databases.DeleteAsync(ServerName, db);
                    }
                    Log.DeletedBackup(db);
                }

                // Clean out CopyTemp databases older than 3 hours
                var copytemps = dbs
                                .Where(db =>
                                       db.Name.StartsWith("copytemp", StringComparison.OrdinalIgnoreCase) &&
                                       db.CreationDate < DateTime.UtcNow.AddHours(-3));
                foreach (var copytemp in copytemps)
                {
                    Log.DeletingBackup(copytemp.Name);
                    if (!WhatIf)
                    {
                        await sql.Databases.DeleteAsync(ServerName, copytemp.Name);
                    }
                    Log.DeletedBackup(copytemp.Name);
                }
            }
            return(Complete());
        }