public bool PatchDatabase(SortedDictionary <string, Patch> patches, ICheckNotifier notifier, Func <Patch, bool> patchPreviewShouldIRunIt, bool backupDatabase = true) { if (!patches.Any()) { notifier.OnCheckPerformed(new CheckEventArgs("There are no patches to apply so skipping patching", CheckResult.Success, null)); return(true); } Version maxPatchVersion = patches.Values.Max(pat => pat.DatabaseVersionNumber); var db = new DiscoveredServer(_builder).GetCurrentDatabase(); if (backupDatabase) { try { notifier.OnCheckPerformed(new CheckEventArgs("About to backup database", CheckResult.Success, null)); db.CreateBackup("Full backup of " + _database); notifier.OnCheckPerformed(new CheckEventArgs("Database backed up", CheckResult.Success, null)); } catch (Exception e) { notifier.OnCheckPerformed(new CheckEventArgs( "Patching failed during setup and preparation (includes failures due to backup creation failures)", CheckResult.Fail, e)); return(false); } } try { int i = 0; foreach (KeyValuePair <string, Patch> patch in patches) { i++; bool shouldRun = patchPreviewShouldIRunIt(patch.Value); if (shouldRun) { RunSQL(db, patch.Value.EntireScript, patch.Key); notifier.OnCheckPerformed(new CheckEventArgs("Executed patch " + patch.Value, CheckResult.Success, null)); } else { throw new Exception("User decided not to execute patch " + patch.Key + " aborting "); } } UpdateVersionIncludingClearingLastVersion(db, notifier, maxPatchVersion); //all went fine notifier.OnCheckPerformed(new CheckEventArgs("All Patches applied, transaction committed", CheckResult.Success, null)); return(true); } catch (Exception e) { notifier.OnCheckPerformed(new CheckEventArgs("Error occurred during patching", CheckResult.Fail, e)); return(false); } }