/// <summary> /// would this patch file apply to the current installed version /// </summary> /// <param name="APatchZipFile"></param> /// <returns></returns> public Boolean PatchApplies(String APatchZipFile) { StringCollection versions = GetVersionsFromDiffZipName(APatchZipFile); TFileVersionInfo patchStartVersion = new TFileVersionInfo(versions[0]); return(patchStartVersion.Compare(this) == 0); }
/// Upgrade the database to the latest version public bool UpgradeDatabase() { bool upgraded = false; while (true) { TFileVersionInfo originalDBVersion = GetCurrentDBVersion(); TFileVersionInfo currentDBVersion = originalDBVersion; TLogging.LogAtLevel(1, "current DB version: " + currentDBVersion.ToStringDotsHyphen()); System.Type t = typeof(TDBUpgrade); foreach (MethodInfo m in t.GetMethods()) { if (m.Name.StartsWith( String.Format("UpgradeDatabase{0}{1}_", originalDBVersion.FileMajorPart.ToString("0000"), originalDBVersion.FileMinorPart.ToString("00")))) { TFileVersionInfo testDBVersion = new TFileVersionInfo( m.Name.Substring("UpgradeDatabase000000_".Length, 4) + "." + m.Name.Substring("UpgradeDatabase000000_".Length + 4, 2) + ".0-0"); // check if the exefileversion is below testDBVersion if (TSrvSetting.ApplicationVersion.Compare(testDBVersion) < 0) { TLogging.Log("Database Upgrade: ignoring method " + m.Name + " because the application version is behind: " + TSrvSetting.ApplicationVersion.ToString()); continue; } TLogging.Log("Database Upgrade: applying method " + m.Name); bool result = (bool)m.Invoke(null, BindingFlags.Static, null, null, null); if (result == true) { upgraded = true; currentDBVersion = testDBVersion; SetCurrentDBVersion(currentDBVersion); } break; } } // if the database version does not change anymore, then we are finished if (currentDBVersion.Compare(originalDBVersion) == 0) { break; } } return(upgraded); }
/// <summary> /// would this patch file apply to the current installed version /// </summary> static public Boolean PatchApplies(TFileVersionInfo ACurrentVersion, string APatchZipFile) { StringCollection versions = GetVersionsFromDiffZipName(APatchZipFile); TFileVersionInfo patchStartVersion = new TFileVersionInfo(versions[0]); // generic patch if (patchStartVersion.FilePrivatePart == 0) { TFileVersionInfo patchEndVersion = new TFileVersionInfo(versions[1]); return(patchEndVersion.Compare(ACurrentVersion) > 0); } return(patchStartVersion.Compare(ACurrentVersion) == 0); }
/// <summary> /// would this patch file apply to the current installed version /// </summary> /// <param name="APatchZipFile"></param> /// <param name="AMaxVersion">maximum version to upgrade to, usually this is the version of the exe files</param> /// <returns></returns> public Boolean PatchApplies(String APatchZipFile, TFileVersionInfo AMaxVersion) { try { StringCollection versions = GetVersionsFromDiffZipName(APatchZipFile); TFileVersionInfo patchStartVersion = new TFileVersionInfo(versions[0]); TFileVersionInfo patchEndVersion = new TFileVersionInfo(versions[1]); return(patchStartVersion.Compare(this) == 0 && patchEndVersion.Compare(AMaxVersion) <= 0); } catch (Exception) { return(false); } }
/// <summary> /// see if any patches are missing; is there a direct line between FCurrentlyInstalledVersion and FLatestAvailablePatch? /// </summary> /// <returns>return a list of all patches that should be applied. empty list if there is a problem</returns> public SortedList CheckPatchesConsistent(SortedList AOrderedListOfAllPatches) { SortedList ResultPatchList = new SortedList(); TFileVersionInfo testPatchVersion; // get the latest patch that is available FLatestAvailablePatch = new TFileVersionInfo(FCurrentlyInstalledVersion); foreach (string patch in AOrderedListOfAllPatches.GetValueList()) { testPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(patch); if (testPatchVersion.Compare(FLatestAvailablePatch) > 0) { FLatestAvailablePatch = testPatchVersion; } } // drop unnecessary patch files // ie. patch files leading to the same version, eg. 2.2.11-1 and 2.2.12-2 to 2.2.12-3 // we only want the biggest step testPatchVersion = new TFileVersionInfo(FCurrentlyInstalledVersion); bool patchesAvailable = true; while (patchesAvailable) { StringCollection applyingPatches = new StringCollection(); foreach (string patch in AOrderedListOfAllPatches.GetValueList()) { if (TPatchFileVersionInfo.PatchApplies(testPatchVersion, patch)) { applyingPatches.Add(patch); } } patchesAvailable = (applyingPatches.Count > 0); if (applyingPatches.Count > 0) { // see which of the applying patches takes us further string highestPatch = applyingPatches[0]; TFileVersionInfo highestPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(highestPatch); foreach (string patch in applyingPatches) { if (TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(patch).Compare(highestPatchVersion) > 0) { highestPatch = patch; highestPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(highestPatch); } } ResultPatchList.Add(highestPatch, highestPatch); testPatchVersion = highestPatchVersion; } } if (FLatestAvailablePatch.Compare(testPatchVersion) != 0) { // check for a generic patch file, starting from version 0.0.99.99 foreach (string patch in AOrderedListOfAllPatches.GetValueList()) { if (patch.Contains("0.0.99.99")) { testPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(patch); ResultPatchList.Clear(); ResultPatchList.Add(patch, patch); } } } if (FLatestAvailablePatch.Compare(testPatchVersion) != 0) { TLogging.Log("missing patchfile from version " + testPatchVersion.ToString() + " to " + FLatestAvailablePatch.ToString()); return(new SortedList()); } return(ResultPatchList); }
/// <summary> /// For standalone installations, we update the SQLite database on the fly. /// </summary> public void UpdateDatabase(TFileVersionInfo ADBVersion, TFileVersionInfo AExeVersion, string AHostOrFile, string ADatabasePort, string ADatabaseName, string AUsername, string APassword) { // we do not support updating standalone databases at the moment if (AExeVersion.FileMajorPart == 0) { DBAccess.GDBAccessObj.CloseDBConnection(); throw new EDBUnsupportedDBUpgradeException(String.Format(Catalog.GetString( "Unsupported upgrade: Please rename the file {0} so that we can start with a fresh database! " + "Please restart the OpenPetra Client after that."), AHostOrFile)); } string dbpatchfilePath = Path.GetDirectoryName(TAppSettingsManager.GetValue("Server.SQLiteBaseFile")); ADBVersion.FilePrivatePart = 0; AExeVersion.FilePrivatePart = 0; using (TDBTransaction transaction = DBAccess.GDBAccessObj.BeginTransaction()) { try { // run all available patches. for each release there could be a patch file string[] sqlFiles = Directory.GetFiles(dbpatchfilePath, "*.sql"); bool foundUpdate = true; // run through all sql files until we have no matching update files anymore while (foundUpdate) { foundUpdate = false; foreach (string sqlFile in sqlFiles) { if (!sqlFile.EndsWith("pg.sql") && (new TPatchFileVersionInfo(ADBVersion)).PatchApplies(sqlFile, AExeVersion)) { foundUpdate = true; StreamReader sr = new StreamReader(sqlFile); while (!sr.EndOfStream) { string line = sr.ReadLine().Trim(); if (!line.StartsWith("--")) { DBAccess.GDBAccessObj.ExecuteNonQuery(line, transaction); } } sr.Close(); ADBVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(sqlFile); } } } if (ADBVersion.Compare(AExeVersion) == 0) { // if patches have been applied successfully, update the database version string newVersionSql = String.Format("UPDATE s_system_defaults SET s_default_value_c = '{0}' WHERE s_default_code_c = 'CurrentDatabaseVersion';", AExeVersion.ToStringDotsHyphen()); DBAccess.GDBAccessObj.ExecuteNonQuery(newVersionSql, transaction); DBAccess.GDBAccessObj.CommitTransaction(); } else { DBAccess.GDBAccessObj.RollbackTransaction(); throw new Exception(String.Format(Catalog.GetString( "Cannot connect to old database (version {0}), there are some missing sql patch files"), ADBVersion)); } } catch (Exception) { DBAccess.GDBAccessObj.RollbackTransaction(); throw; } } }