/// 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> /// set current database version /// </summary> private static bool SetCurrentDBVersion(TFileVersionInfo ANewVersion) { using (TDBTransaction transaction = DBAccess.GDBAccessObj.BeginTransaction()) { string newVersionSql = String.Format("UPDATE s_system_defaults SET s_default_value_c = '{0}' WHERE s_default_code_c = 'CurrentDatabaseVersion';", ANewVersion.ToStringDotsHyphen()); DBAccess.GDBAccessObj.ExecuteNonQuery(newVersionSql, transaction); DBAccess.GDBAccessObj.CommitTransaction(); } return(true); }
/// <summary> /// set current database version /// </summary> private static bool SetCurrentDBVersion(TFileVersionInfo ANewVersion, TDataBase ADataBase) { TDBTransaction transaction = new TDBTransaction(); bool SubmitOK = true; ADataBase.WriteTransaction(ref transaction, ref SubmitOK, delegate { string newVersionSql = String.Format("UPDATE s_system_defaults SET s_default_value_c = '{0}' WHERE s_default_code_c = 'CurrentDatabaseVersion';", ANewVersion.ToStringDotsHyphen()); ADataBase.ExecuteNonQuery(newVersionSql, transaction); }); return(true); }
/// <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; } } }