/// <summary> /// When overridden in the derived class, runs the test. /// </summary> /// <param name="errorMessage">When the method returns false, contains an error message as to why /// the test failed. Otherwise, contains an empty string.</param> /// <returns> /// True if the test passed; false if the test failed. /// </returns> protected override bool RunTest(ref string errorMessage) { var schemaFile = MySqlHelper.DbSchemaFile; if (!File.Exists(schemaFile)) { const string errmsg = "The database schema file could not be found at path `{0}`, so this program will not be" + " able to check your database schema to see if it is up-to-date."; errorMessage = string.Format(errmsg, schemaFile); return false; } try { var schema = SchemaReader.Load(schemaFile); _schema = schema; } catch (Exception ex) { errorMessage = AppendErrorDetails(string.Format(_failMessage, schemaFile), ex.ToString()); return false; } return true; }
/// <summary> /// Saves the schema to file. /// </summary> /// <param name="path">The file path to save to. If null, the default path will be used.</param> public static void Save(string path = null) { if (string.IsNullOrEmpty(path)) path = Paths.Root + MySqlHelper.DbSchemaFile; // Load the database settings var dbSettings = new DbConnectionSettings(Paths.Root + MySqlHelper.DbSettingsFile, true); // Get the schema var schema = new SchemaReader(dbSettings); // Save schema.Save(path); }
/// <summary> /// Compares two <see cref="SchemaReader"/>s. /// </summary> /// <param name="main">The first <see cref="SchemaReader"/>.</param> /// <param name="sub">The other <see cref="SchemaReader"/>.</param> /// <returns>Text describing the difference between the two <see cref="SchemaReader"/>s.</returns> public static IEnumerable <string> Compare(SchemaReader main, SchemaReader sub) { var missingColumns = new List <ColumnSchema>(); var mismatchColumns = new List <ColumnSchema>(); foreach (var table in main.TableSchemas) { var t = table; var t2 = sub.TableSchemas.FirstOrDefault(x => x.TableName == t.TableName); if (t2 == null) { // Table not found yield return(string.Format("TABLE `{0}`: MISSING", t.TableName)); } else { // Table found missingColumns.Clear(); mismatchColumns.Clear(); foreach (var column in t.Columns) { var c = column; var c2 = t2.Columns.FirstOrDefault(x => x.Name == c.Name); if (c2 == null) { missingColumns.Add(c); } else if (!c.EqualValues(c2)) { mismatchColumns.Add(c); } } // List of missing and mismatches if (missingColumns.Count > 0) { yield return(string.Format("TABLE `{0}`: COLUMNS MISSING: {1}", t.TableName, Concat(missingColumns))); } if (mismatchColumns.Count > 0) { yield return(string.Format("TABLE `{0}`: DIFFERENT COLUMNS: {1}", t.TableName, Concat(mismatchColumns))); } } } }
/// <summary> /// Compares two <see cref="SchemaReader"/>s. /// </summary> /// <param name="main">The first <see cref="SchemaReader"/>.</param> /// <param name="sub">The other <see cref="SchemaReader"/>.</param> /// <returns>Text describing the difference between the two <see cref="SchemaReader"/>s.</returns> public static IEnumerable<string> Compare(SchemaReader main, SchemaReader sub) { var missingColumns = new List<ColumnSchema>(); var mismatchColumns = new List<ColumnSchema>(); foreach (var table in main.TableSchemas) { var t = table; var t2 = sub.TableSchemas.FirstOrDefault(x => x.TableName == t.TableName); if (t2 == null) { // Table not found yield return string.Format("TABLE `{0}`: MISSING", t.TableName); } else { // Table found missingColumns.Clear(); mismatchColumns.Clear(); foreach (var column in t.Columns) { var c = column; var c2 = t2.Columns.FirstOrDefault(x => x.Name == c.Name); if (c2 == null) missingColumns.Add(c); else if (!c.EqualValues(c2)) mismatchColumns.Add(c); } // List of missing and mismatches if (missingColumns.Count > 0) yield return string.Format("TABLE `{0}`: COLUMNS MISSING: {1}", t.TableName, Concat(missingColumns)); if (mismatchColumns.Count > 0) yield return string.Format("TABLE `{0}`: DIFFERENT COLUMNS: {1}", t.TableName, Concat(mismatchColumns)); } } }
/// <summary> /// Actually runs the test. /// </summary> /// <returns>If false, call <see cref="MySqlHelper.AskToImportDatabase"/>.</returns> static bool TestInternal(out string errmsg) { var schema = LoadSchemaFile.Schema; if (schema == null) { errmsg = "Could not run test since the database schema file failed to load."; return true; } SchemaReader userSchema; try { userSchema = new SchemaReader(MySqlHelper.ConnectionSettings); } catch (MySqlException ex) { errmsg = AppendErrorDetails("Failed to read the database schema from MySql. Error: " + ex.Message, ex.ToString()); return false; } var diffs = SchemaComparer.Compare(schema, userSchema); const string failmsg2 = "\nOne or more differences were found in your database schema in comparison to" + " the release's database schema. If you have manually altered your database's schema (such as add" + " fields or alter field types), you can ignore this message. Otherwise, this likely means that you" + " are using the wrong database dump file for this version of NetGore. Often times, this is because" + " you have the database from an older version of NetGore that is not compatible with this version." + "\nTo resolve this issue, please use the database dump (db.sql) from this version of NetGore." + " Make sure to back up your database if you want to save any of the contents!" + "\n\nThe following is a list of all the differences found in your database schema: \n{0}"; errmsg = string.Format(failmsg2, ToNewLines(diffs)); return diffs == null || diffs.Count() == 0; }