///<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> private void InvokeConvertMethods() { DataConnection.CommandTimout = 7200; //2 hours, because conversion commands may take longer to run. //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(new ODEventArgs("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(this, new object[] { }); } catch (Exception ex) { string message = Lan.g(this, "Convert Database failed "); try { string methodName = convertMethodInfo.MethodInfoCur.Name; if (!string.IsNullOrEmpty(methodName)) { message += Lan.g(this, "during: ") + methodName + "() "; } string command = Db.LastCommand; if (!string.IsNullOrEmpty(command)) { message += Lan.g(this, "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)); } DataConnection.CommandTimout = 3600; //Set back to default of 1 hour. }