///<summary>Uses reflection to invoke private methods of the ConvertDatabase class in order from least to greatest if needed. ///The old way of converting the database was to manually daisy chain methods together. ///The new way is to just add a method that follows a strict naming pattern which this method will invoke when needed.</summary> public static void InvokeConvertMethods() { DataConnection.CommandTimeout = 43200; //12 hours, because conversion commands may take longer to run. ConvertDatabases.To2_8_2(); //begins going through the chain of conversion steps Logger.DoVerboseLoggingArgs doVerboseLogging = Logger.DoVerboseLogging; ODException.SwallowAnyException(() => { //Need to run queries here because PrefC has not been initialized. string command = "SELECT ValueString FROM preference WHERE PrefName='HasVerboseLogging'"; string valueString = Db.GetScalar(command); if (valueString.ToLower().Split(',').ToList().Exists(x => x == Environment.MachineName.ToLower())) { Logger.DoVerboseLogging = () => true; //Switch logger to a directory that won't have permissions issues. Logger.UseMyDocsDirectory(); } Logger.LogVerbose("Starting convert script"); }); //Continue going through the chain of conversion methods starting at v17.1.1 via reflection. //Loop through the list of convert databases methods from front to back because it has already been sorted (least to greatest). foreach (ConvertDatabasesMethodInfo convertMethodInfo in ListConvertMethods) { //This pattern of using reflection to invoke our convert methods started in v17.1 so we will skip all methods prior to that version. if (convertMethodInfo.VersionCur < new Version(17, 1)) { continue; } //Skip all methods that are below or equal to our "from" version. if (convertMethodInfo.VersionCur <= FromVersion) { continue; } //This convert method needs to be invoked. ODEvent.Fire(ODEventType.ConvertDatabases, "Upgrading database to version: " //No translations in convert script. + convertMethodInfo.VersionCur.ToString(3)); //Only show the major, minor, build (preserves old functionality). try { //Use reflection to invoke the private static method. convertMethodInfo.MethodInfoCur.Invoke(null, new object[] { }); } catch (Exception ex) { string message = Lans.g("ClassConvertDatabase", "Convert Database failed "); try { string methodName = convertMethodInfo.MethodInfoCur.Name; if (!string.IsNullOrEmpty(methodName)) { message += Lans.g("ClassConvertDatabase", "during: ") + methodName + "() "; } string command = Db.LastCommand; if (!string.IsNullOrEmpty(command)) { message += Lans.g("ClassConvertDatabase", "while running: ") + command + ";"; } } catch (Exception e) { e.DoNothing(); //If this fails for any reason then just continue. } throw new Exception(message + " " + ex.Message + " " + ex.InnerException.Message, ex.InnerException); } //Update the preference that keeps track of what version Open Dental has successfully upgraded to. //Always require major, minor, build, revision. Will throw an exception if the revision was not explicitly set (which we always set). Prefs.UpdateStringNoCache(PrefName.DataBaseVersion, convertMethodInfo.VersionCur.ToString(4)); } ODException.SwallowAnyException(() => { Logger.LogVerbose("Ending convert script"); Logger.DoVerboseLogging = doVerboseLogging; }); DataConnection.CommandTimeout = 3600; //Set back to default of 1 hour. }