/// <summary> /// Given a guid and either the default or user configured lifetime of an index, remove all indexes that meet the following /// conditions: (1) the index's age is equal to or greater than the given lifetime, (2) the index is not for the most /// recent full backup or a full backup that non-expired incremental backups depend on, and (3) the index is not for /// an incremental backup that other backups depend on (4) the index is for a backup initiated by the source host /// identified by the given guid /// </summary> /// <param name="guid">A unique string that identifies a specific source host.</param> /// <param name="indexLifeTime">The lifetime of an index in months</param> public void CleanIndexes(string guid, int indexLifeTime) { //Get a list of date/times for backups initiated by the node with the given guid List<String> indexList = new List<String>(GetIndexList(guid)); List<dateTimeLevel> cleanList = new List<dateTimeLevel>(); //Compile a list of backup indexes to be cleaned, identified by date/time and backup level foreach (string currentDateTime in indexList) { int backupLevel = 0; string levelQuery = "SELECT backup_level from Backup_Indexes WHERE source_guid = @pGUID AND date_of_backup = @pDateOfBackup"; SQLiteCommand levelCmd = new SQLiteCommand(levelQuery, conn); SQLiteParameter pguid = new SQLiteParameter("@pGUID", guid); SQLiteParameter pdateOfBackup = new SQLiteParameter("@DateOfBackup", currentDateTime); levelCmd.Parameters.Add(pguid); levelCmd.Parameters.Add(pdateOfBackup); try { conn.Open(); backupLevel = Convert.ToInt16(levelCmd.ExecuteScalar()); conn.Close(); } catch (SQLiteException ex) { //if anything is wrong with the sql statement or the database, //a SQLiteException will show information about it. Debug.Print(ex.Message); //always make sure the database connection is closed. if (conn.State == ConnectionState.Open) { conn.Close(); } } dateTimeLevel currentIndex = new dateTimeLevel(Convert.ToDateTime(currentDateTime), backupLevel); cleanList.Add(currentIndex); } //Sort into descending order by date/time of backup cleanList.Sort((index1, index2) => index2.dateTime.CompareTo(index1.dateTime)); DateTime? mostRecentFullBackup = null; int currentIncrementalCount = 0; // keep track of incremental backups that other backups will depend on //Remove from the list indexes that do not qualify for removal from the database foreach (dateTimeLevel currentIndex in cleanList) { TimeSpan indexAge = DateTime.Now - currentIndex.dateTime; double indexAgeMonths = indexAge.TotalDays / 31.0; if (!mostRecentFullBackup.HasValue && currentIndex.backupLevel > 0) //index is for incremental backups dependent on the most recent full backup { cleanList.Remove(currentIndex); } else if (!mostRecentFullBackup.HasValue) //index is for the most recent full backup { mostRecentFullBackup = currentIndex.dateTime; cleanList.Remove(currentIndex); } else { if (indexAgeMonths < indexLifeTime) // is the index expired { cleanList.Remove(currentIndex); if (currentIndex.backupLevel > 0) { currentIncrementalCount++; } } else if (currentIncrementalCount > 0) // is the index for a backup that incremental backups depend on { cleanList.Remove(currentIndex); if (currentIndex.backupLevel == 0) { currentIncrementalCount = 0; } } } } //All indexes in the list at this point qualify for removal from the database //Remove all indexes in the list from the database foreach (dateTimeLevel currentIndex in cleanList) { List<key> blockKeys = new List<key>(); string dateTimeOfBackup = currentIndex.dateTime.ToString("yyyy-MM-dd HH:mm:ss"); //Remove entries from Backup_Indexes table key indexPrimaryKey = RemoveBackupIndex(guid, dateTimeOfBackup); //Remove entries from Index_to_Block table blockKeys = RemoveIndexToBlocks(indexPrimaryKey); //Remove entries from Block_Storage table RemoveBlocks(blockKeys); } }
/// <summary> /// Given a guid and either the default or user configured lifetime of an index, remove all indexes that meet the following /// conditions: (1) the index's age is equal to or greater than the given lifetime, (2) the index is not for the most /// recent full backup or a full backup that non-expired incremental backups depend on, and (3) the index is not for /// an incremental backup that other backups depend on (4) the index is for a backup initiated by the source host /// identified by the given guid /// </summary> /// <param name="guid">A unique string that identifies a specific source host.</param> /// <param name="indexLifeTime">The lifetime of an index in months</param> public void CleanIndexes(string guid, int indexLifeTime) { //Get a list of date/times for backups initiated by the node with the given guid List <String> indexList = new List <String>(GetIndexList(guid)); List <dateTimeLevel> cleanList = new List <dateTimeLevel>(); //Compile a list of backup indexes to be cleaned, identified by date/time and backup level foreach (string currentDateTime in indexList) { int backupLevel = 0; string levelQuery = "SELECT backup_level from Backup_Indexes WHERE source_guid = @pGUID AND date_of_backup = @pDateOfBackup"; SQLiteCommand levelCmd = new SQLiteCommand(levelQuery, conn); SQLiteParameter pguid = new SQLiteParameter("@pGUID", guid); SQLiteParameter pdateOfBackup = new SQLiteParameter("@DateOfBackup", currentDateTime); levelCmd.Parameters.Add(pguid); levelCmd.Parameters.Add(pdateOfBackup); try { conn.Open(); backupLevel = Convert.ToInt16(levelCmd.ExecuteScalar()); conn.Close(); } catch (SQLiteException ex) { //if anything is wrong with the sql statement or the database, //a SQLiteException will show information about it. Debug.Print(ex.Message); //always make sure the database connection is closed. if (conn.State == ConnectionState.Open) { conn.Close(); } } dateTimeLevel currentIndex = new dateTimeLevel(Convert.ToDateTime(currentDateTime), backupLevel); cleanList.Add(currentIndex); } //Sort into descending order by date/time of backup cleanList.Sort((index1, index2) => index2.dateTime.CompareTo(index1.dateTime)); DateTime?mostRecentFullBackup = null; int currentIncrementalCount = 0; // keep track of incremental backups that other backups will depend on //Remove from the list indexes that do not qualify for removal from the database foreach (dateTimeLevel currentIndex in cleanList) { TimeSpan indexAge = DateTime.Now - currentIndex.dateTime; double indexAgeMonths = indexAge.TotalDays / 31.0; if (!mostRecentFullBackup.HasValue && currentIndex.backupLevel > 0) //index is for incremental backups dependent on the most recent full backup { cleanList.Remove(currentIndex); } else if (!mostRecentFullBackup.HasValue) //index is for the most recent full backup { mostRecentFullBackup = currentIndex.dateTime; cleanList.Remove(currentIndex); } else { if (indexAgeMonths < indexLifeTime) // is the index expired { cleanList.Remove(currentIndex); if (currentIndex.backupLevel > 0) { currentIncrementalCount++; } } else if (currentIncrementalCount > 0) // is the index for a backup that incremental backups depend on { cleanList.Remove(currentIndex); if (currentIndex.backupLevel == 0) { currentIncrementalCount = 0; } } } } //All indexes in the list at this point qualify for removal from the database //Remove all indexes in the list from the database foreach (dateTimeLevel currentIndex in cleanList) { List <key> blockKeys = new List <key>(); string dateTimeOfBackup = currentIndex.dateTime.ToString("yyyy-MM-dd HH:mm:ss"); //Remove entries from Backup_Indexes table key indexPrimaryKey = RemoveBackupIndex(guid, dateTimeOfBackup); //Remove entries from Index_to_Block table blockKeys = RemoveIndexToBlocks(indexPrimaryKey); //Remove entries from Block_Storage table RemoveBlocks(blockKeys); } }