static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: <definitionsdir>"); Environment.Exit(1); } var definitionDir = args[0]; var rewrite = true; foreach (var file in Directory.GetFiles(definitionDir)) { var dbName = Path.GetFileNameWithoutExtension(file); var reader = new DBDReader(); definitionCache.Add(dbName, reader.Read(file, true)); Console.WriteLine("Read " + definitionCache[dbName].versionDefinitions.Length + " versions and " + definitionCache[dbName].columnDefinitions.Count + " columns for " + dbName); if (rewrite) { var writer = new DBDWriter(); writer.Save(definitionCache[dbName], Path.Combine(definitionDir, dbName + ".dbd")); } } Console.WriteLine("Read " + definitionCache.Count + " database definitions!"); var foreignKeys = 0; foreach (var definition in definitionCache) { foreach (var columnDefinition in definition.Value.columnDefinitions) { if (!string.IsNullOrEmpty(columnDefinition.Value.foreignTable) || !string.IsNullOrEmpty(columnDefinition.Value.foreignColumn)) { if (definitionCache.ContainsKey(columnDefinition.Value.foreignTable) && definitionCache[columnDefinition.Value.foreignTable].columnDefinitions.ContainsKey(columnDefinition.Value.foreignColumn)) { Console.ForegroundColor = ConsoleColor.Green; //Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn); } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn + " WHICH DOES NOT EXIST!"); } foreignKeys++; Console.ResetColor(); } } } Console.WriteLine("Checked " + foreignKeys + " foreign keys!"); Console.WriteLine("Done, press enter to exit"); Console.ReadLine(); }
static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: <firstdir> <seconddir> <outdir>"); Environment.Exit(1); } var firstDir = args[0]; var secondDir = args[1]; var targetDir = args[2]; var firstDirFiles = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name).ToList(); var secondDirFiles = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name).ToList(); var newDefinitions = new Dictionary <string, DBDefinition>(); var reader = new DBDReader(); foreach (var file in secondDirFiles) { var dbName = Path.GetFileNameWithoutExtension(file); if (firstDirFiles.Contains(file)) { // Both directories have this file. Merge! var firstFile = reader.Read(Path.Combine(firstDir, file)); var secondFile = reader.Read(Path.Combine(secondDir, file)); var newDefinition = firstFile; // Merge column definitions foreach (var columnDefinition2 in secondFile.columnDefinitions) { var foundCol = false; foreach (var columnDefinition1 in firstFile.columnDefinitions) { if (Utils.NormalizeColumn(columnDefinition2.Key).ToLower() == Utils.NormalizeColumn(columnDefinition1.Key).ToLower()) { foundCol = true; if (columnDefinition2.Value.type != columnDefinition1.Value.type) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Types are different for (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and (2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", using type " + columnDefinition2.Value.type + " from 2"); // If this is an uncommon conversion (not uint -> int or vice versa) throw an error if ((columnDefinition1.Value.type == "uint" && columnDefinition2.Value.type == "int") || (columnDefinition1.Value.type == "int" && columnDefinition2.Value.type == "uint")) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", ignoring.."); } else { throw new Exception("bad type difference, refusing to handle"); } Console.ResetColor(); } if (columnDefinition2.Key != columnDefinition1.Key) { if (Utils.NormalizeColumn(columnDefinition2.Key, true) == columnDefinition1.Key) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Automagically fixed casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key); for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { secondFile.versionDefinitions[i].definitions[j].name = Utils.NormalizeColumn(columnDefinition2.Key, true); break; } } } } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Unable to automagically fix casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key + ", falling back to (1) naming"); for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { secondFile.versionDefinitions[i].definitions[j].name = columnDefinition1.Key; break; } } } } Console.ResetColor(); } break; } } if (!foundCol) { // Column was not found, add it Console.WriteLine(dbName + "::" + columnDefinition2.Key + " was not found found in first file!"); newDefinition.columnDefinitions.Add(columnDefinition2.Key, columnDefinition2.Value); } } // Merge version definitions foreach (var versionDefinition2 in secondFile.versionDefinitions) { var foundVersion = false; foreach (var versionDefinition1 in firstFile.versionDefinitions) { foreach (var layoutHash2 in versionDefinition2.layoutHashes) { if (versionDefinition1.layoutHashes.Contains(layoutHash2)) { foundVersion = true; break; } } // If layouthash was found, don't check builds if (foundVersion) { break; } // Check builds foreach (var build2 in versionDefinition2.builds) { foreach (var build1 in versionDefinition1.builds) { if (build1.Equals(build2)) { foundVersion = true; break; } } foreach (var buildranges1 in versionDefinition1.buildRanges) { if (build2.expansion == buildranges1.minBuild.expansion && build2.major == buildranges1.minBuild.major && build2.minor == buildranges1.minBuild.minor) { if (build2.build >= buildranges1.minBuild.build && build2.build <= buildranges1.maxBuild.build) { //Console.WriteLine("Build match? Build " + Utils.BuildToString(build2) + " seem to match with " + Utils.BuildToString(buildranges1.minBuild) + "-" + Utils.BuildToString(buildranges1.maxBuild)); foundVersion = true; break; } } } } } if (!foundVersion) { // TODO: Only for secondFile, not firstFile! var mergedWithPreviousBuild = false; var newVersions = newDefinition.versionDefinitions.ToList(); for (var i = 0; i < newVersions.Count; i++) { if (newVersions[i].definitions.SequenceEqual(versionDefinition2.definitions)) { Console.WriteLine("Looks like these two definition arrays are the same!"); // Make list from current builds var curBuilds = newVersions[i].builds.ToList(); curBuilds.AddRange(versionDefinition2.builds.ToList()); // Make list of current layouthashes var curLayouthashes = newVersions[i].layoutHashes.ToList(); curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList()); // Create temporary version object based of newVersion var tempVersion = newVersions[i]; // Override builds with new list tempVersion.builds = curBuilds.Distinct().ToArray(); // Override layoutHashes with new list tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray(); // Override newVersion with temporary version object newVersions[i] = tempVersion; mergedWithPreviousBuild = true; } } if (!mergedWithPreviousBuild) { // Version was not found/merged, add it! newVersions.Add(versionDefinition2); } newDefinition.versionDefinitions = newVersions.ToArray(); } else { // Version exists, compare stuff and add build if needed, TODO make less bad var newVersions = newDefinition.versionDefinitions.ToList(); for (var i = 0; i < newVersions.Count; i++) { foreach (var layoutHash2 in versionDefinition2.layoutHashes) { if (newVersions[i].layoutHashes.Contains(layoutHash2)) { // Make list from current builds var curBuilds = newVersions[i].builds.ToList(); curBuilds.AddRange(versionDefinition2.builds.ToList()); // Make list of current layouthashes var curLayouthashes = newVersions[i].layoutHashes.ToList(); curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList()); // Create temporary version object based of newVersion var tempVersion = newVersions[i]; // Override builds with new list tempVersion.builds = curBuilds.Distinct().ToArray(); // Override layoutHashes with new list tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray(); for (var j = 0; j < versionDefinition2.definitions.Count(); j++) { // Merge signedness from second file if it is different from current if (versionDefinition2.definitions[j].isSigned != tempVersion.definitions[j].isSigned) { tempVersion.definitions[j].isSigned = versionDefinition2.definitions[j].isSigned; } } // Override newVersion with temporary version object newVersions[i] = tempVersion; } } } newDefinition.versionDefinitions = newVersions.ToArray(); } } newDefinitions.Add(dbName, newDefinition); } else { // Only 2nd dir has this file, use that newDefinitions.Add(dbName, reader.Read(Path.Combine(secondDir, file))); } } foreach (var file in firstDirFiles) { if (!secondDirFiles.Contains(file)) { // Only 1st dir has this file, use that newDefinitions.Add(Path.GetFileNameWithoutExtension(file), reader.Read(Path.Combine(firstDir, file))); } } var writer = new DBDWriter(); foreach (var entry in newDefinitions) { writer.Save(entry.Value, Path.Combine(targetDir, entry.Key + ".dbd")); } //Console.ReadLine(); }
static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: <firstdir> <seconddir> <outdir>"); Environment.Exit(1); } var numLayoutsAdded = 0; var firstDir = args[0]; var secondDir = args[1]; var targetDir = args[2]; var firstDirFiles = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name).ToList(); var secondDirFiles = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name).ToList(); var firstDirFilesLC = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name.ToLower()).ToList(); var secondDirFilesLC = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name.ToLower()).ToList(); var newDefinitions = new Dictionary <string, DBDefinition>(); var reader = new DBDReader(); foreach (var file in secondDirFiles) { var dbName = Path.GetFileNameWithoutExtension(file); if (firstDirFilesLC.Contains(file.ToLower())) { // Both directories have this file. Merge! var firstFileName = Path.Combine(firstDir, firstDirFiles.ElementAt(firstDirFilesLC.IndexOf(file.ToLower()))); var firstFile = reader.Read(firstFileName); var secondFile = reader.Read(Path.Combine(secondDir, file)); var newDefinition = firstFile; // Merge column definitions foreach (var columnDefinition2 in secondFile.columnDefinitions) { var foundCol = false; foreach (var columnDefinition1 in firstFile.columnDefinitions) { if (Utils.NormalizeColumn(columnDefinition2.Key).ToLower() == Utils.NormalizeColumn(columnDefinition1.Key).ToLower()) { foundCol = true; if (columnDefinition2.Value.type != columnDefinition1.Value.type) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Types are different for (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and (2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", using type " + columnDefinition2.Value.type + " from 2"); // If this is an uncommon conversion (not uint -> int or vice versa) throw an error if ((columnDefinition1.Value.type == "uint" && columnDefinition2.Value.type == "int") || (columnDefinition1.Value.type == "int" && columnDefinition2.Value.type == "uint")) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", ignoring.."); } else { throw new Exception("bad type difference, refusing to handle"); } Console.ResetColor(); } if (columnDefinition2.Key != columnDefinition1.Key) { if (Utils.NormalizeColumn(columnDefinition2.Key, true) == columnDefinition1.Key) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Automagically fixed casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key); for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { secondFile.versionDefinitions[i].definitions[j].name = Utils.NormalizeColumn(columnDefinition2.Key, true); break; } } } } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Unable to automagically fix casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key + ", falling back to (1) naming"); for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { secondFile.versionDefinitions[i].definitions[j].name = columnDefinition1.Key; break; } } } } Console.ResetColor(); } // Merge comments if (columnDefinition2.Value.comment != columnDefinition1.Value.comment) { for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { var colDef = newDefinition.columnDefinitions[columnDefinition1.Key]; if (columnDefinition2.Value.comment == null) { colDef.comment = columnDefinition1.Value.comment; } else if (columnDefinition1.Value.comment == null) { colDef.comment = columnDefinition2.Value.comment; } else { throw new Exception("Do not support merging 2 comments yet!"); } newDefinition.columnDefinitions[columnDefinition1.Key] = colDef; } } } } // Merge foreignTable/foreignKey if (columnDefinition2.Value.foreignTable != columnDefinition1.Value.foreignTable || columnDefinition2.Value.foreignColumn != columnDefinition1.Value.foreignColumn) { for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { var colDef = newDefinition.columnDefinitions[columnDefinition1.Key]; if (columnDefinition2.Value.foreignTable == null && columnDefinition2.Value.foreignColumn == null) { colDef.foreignTable = columnDefinition1.Value.foreignTable; colDef.foreignColumn = columnDefinition1.Value.foreignColumn; } else if (columnDefinition1.Value.foreignTable == null && columnDefinition1.Value.foreignColumn == null) { colDef.foreignTable = columnDefinition2.Value.foreignTable; colDef.foreignColumn = columnDefinition2.Value.foreignColumn; } else { throw new Exception("Do not support merging 2 FKs yet!"); } newDefinition.columnDefinitions[columnDefinition1.Key] = colDef; } } } } break; } } if (!foundCol) { // Column was not found, add it newDefinition.columnDefinitions.Add(columnDefinition2.Key, columnDefinition2.Value); } } // Merge version definitions foreach (var versionDefinition2 in secondFile.versionDefinitions) { var foundVersion = false; foreach (var versionDefinition1 in firstFile.versionDefinitions) { foreach (var layoutHash2 in versionDefinition2.layoutHashes) { if (versionDefinition1.layoutHashes.Contains(layoutHash2)) { foundVersion = true; break; } } // If layouthash was found, don't check builds if (foundVersion) { break; } // Check builds foreach (var build2 in versionDefinition2.builds) { foreach (var build1 in versionDefinition1.builds) { if (build1.Equals(build2)) { foundVersion = true; break; } } // Stop checking if build already exists if (foundVersion) { break; } foreach (var buildranges1 in versionDefinition1.buildRanges) { if (buildranges1.Contains(build2)) { Console.WriteLine(build2.ToString() + " is in build range " + buildranges1.ToString()); foundVersion = true; break; } } // Stop checking if build exists in ranges if (foundVersion) { break; } } } if (!foundVersion) { // TODO: Only for secondFile, not firstFile! var mergedWithPreviousBuild = false; var newVersions = newDefinition.versionDefinitions.ToList(); for (var i = 0; i < newVersions.Count; i++) { if (newVersions[i].definitions.SequenceEqual(versionDefinition2.definitions)) { Console.WriteLine("Looks like these two definition arrays are the same!"); // Make list from current builds var curBuilds = newVersions[i].builds.ToList(); curBuilds.AddRange(versionDefinition2.builds.ToList()); // Make list from current build ranges var curBuildRanges = newVersions[i].buildRanges.ToList(); curBuildRanges.AddRange(versionDefinition2.buildRanges.ToList()); // Make list of current layouthashes var curLayouthashes = newVersions[i].layoutHashes.ToList(); curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList()); // Create temporary version object based of newVersion var tempVersion = newVersions[i]; // Override builds with new list tempVersion.builds = curBuilds.Distinct().ToArray(); // Override buildranges with new list tempVersion.buildRanges = curBuildRanges.Distinct().ToArray(); // Override layoutHashes with new list tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray(); // Override newVersion with temporary version object newVersions[i] = tempVersion; mergedWithPreviousBuild = true; } } if (!mergedWithPreviousBuild) { // Version was not found/merged, add it! newVersions.Add(versionDefinition2); numLayoutsAdded++; } newDefinition.versionDefinitions = newVersions.ToArray(); } else { // Version exists, compare stuff and add build if needed, TODO make less bad var newVersions = newDefinition.versionDefinitions.ToList(); for (var i = 0; i < newVersions.Count; i++) { foreach (var layoutHash2 in versionDefinition2.layoutHashes) { if (newVersions[i].layoutHashes.Contains(layoutHash2)) { // Make list from current builds var curBuilds = newVersions[i].builds.ToList(); curBuilds.AddRange(versionDefinition2.builds.ToList()); // Make list from current build ranges var curBuildRanges = newVersions[i].buildRanges.ToList(); curBuildRanges.AddRange(versionDefinition2.buildRanges.ToList()); // Make list of current layouthashes var curLayouthashes = newVersions[i].layoutHashes.ToList(); curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList()); // Create temporary version object based of newVersion var tempVersion = newVersions[i]; // Override builds with new list tempVersion.builds = curBuilds.Distinct().ToArray(); // Override buildranges with new list tempVersion.buildRanges = curBuildRanges.Distinct().ToArray(); // Override layoutHashes with new list tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray(); for (var j = 0; j < versionDefinition2.definitions.Count(); j++) { // Merge signedness from second file if it is different from current if (versionDefinition2.definitions[j].isSigned != tempVersion.definitions[j].isSigned) { tempVersion.definitions[j].isSigned = versionDefinition2.definitions[j].isSigned; } } // Override newVersion with temporary version object newVersions[i] = tempVersion; } } } newDefinition.versionDefinitions = newVersions.ToArray(); } } newDefinitions.Add(Path.GetFileNameWithoutExtension(firstFileName), newDefinition); } else { // Only 2nd dir has this file, use that newDefinitions.Add(dbName, reader.Read(Path.Combine(secondDir, file))); } } foreach (var file in firstDirFiles) { if (!secondDirFilesLC.Contains(file.ToLower())) { // Only 1st dir has this file, use that newDefinitions.Add(Path.GetFileNameWithoutExtension(file), reader.Read(Path.Combine(firstDir, file))); } } var writer = new DBDWriter(); foreach (var entry in newDefinitions) { var definitionCopy = entry.Value; var versionDefinitionCopy = definitionCopy.versionDefinitions.ToList(); for (var i = 0; i < versionDefinitionCopy.Count(); i++) { for (var j = 0; j < versionDefinitionCopy.Count(); j++) { if (i == j) { continue; // Do not compare same entry } if (versionDefinitionCopy[i].definitions.SequenceEqual(versionDefinitionCopy[j].definitions)) { if (versionDefinitionCopy[i].layoutHashes.Length > 0 && versionDefinitionCopy[j].layoutHashes.Length > 0 && !versionDefinitionCopy[i].layoutHashes.SequenceEqual(versionDefinitionCopy[j].layoutHashes)) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(Path.GetFileNameWithoutExtension(entry.Key) + " has 2 identical version definitions (" + (i + 1) + " and " + (j + 1) + ") but two different layouthashes, ignoring..."); Console.ResetColor(); } else { // Make list from current builds var curBuilds = versionDefinitionCopy[i].builds.ToList(); curBuilds.AddRange(versionDefinitionCopy[j].builds.ToList()); // Make list from current build ranges var curBuildRanges = versionDefinitionCopy[i].buildRanges.ToList(); curBuildRanges.AddRange(versionDefinitionCopy[j].buildRanges.ToList()); // Make list of current layouthashes var curLayouthashes = versionDefinitionCopy[i].layoutHashes.ToList(); curLayouthashes.AddRange(versionDefinitionCopy[j].layoutHashes.ToList()); // Create temporary version object based of newVersion var tempVersion = versionDefinitionCopy[i]; // Override builds with new list tempVersion.builds = curBuilds.Distinct().ToArray(); // Override buildranges with new list tempVersion.buildRanges = curBuildRanges.Distinct().ToArray(); // Override layoutHashes with new list tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray(); // Override newVersion with temporary version object versionDefinitionCopy[i] = tempVersion; versionDefinitionCopy.RemoveAt(j); definitionCopy.versionDefinitions = versionDefinitionCopy.ToArray(); } } } } // Run through column definitions to see if there's any unused columns var columnDefinitionsCopy = definitionCopy.columnDefinitions.ToList(); foreach (var columnDefinition in columnDefinitionsCopy) { var columnUsed = false; foreach (var versionDefinition in definitionCopy.versionDefinitions) { foreach (var definition in versionDefinition.definitions) { if (definition.name == columnDefinition.Key) { columnUsed = true; } } } if (!columnUsed) { definitionCopy.columnDefinitions.Remove(columnDefinition.Key); } } writer.Save(definitionCopy, Path.Combine(targetDir, entry.Key + ".dbd"), true); } Console.WriteLine("Done, " + numLayoutsAdded + " new layouts added!"); //Console.ReadLine(); }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: <definitionsdir>"); Environment.Exit(1); } var definitionDir = args[0]; var rewrite = false; var verbose = true; if (args.Length >= 2 && args[1] == "true") { rewrite = true; } if (args.Length >= 3 && args[2] == "false") { verbose = false; } var errorEncountered = new List <string>(); foreach (var file in Directory.GetFiles(definitionDir)) { var dbName = Path.GetFileNameWithoutExtension(file); var reader = new DBDReader(); try { definitionCache.Add(dbName, reader.Read(file, true)); if (verbose) { Console.WriteLine("Read " + definitionCache[dbName].versionDefinitions.Length + " versions and " + definitionCache[dbName].columnDefinitions.Count + " columns for " + dbName); } if (rewrite) { var writer = new DBDWriter(); writer.Save(definitionCache[dbName], Path.Combine(definitionDir, dbName + ".dbd")); } } catch (Exception ex) { errorEncountered.Add(dbName); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Failed to read " + dbName + ": " + ex); Console.ResetColor(); } } Console.WriteLine("Read " + definitionCache.Count + " database definitions!"); var foreignKeys = 0; foreach (var definition in definitionCache) { foreach (var columnDefinition in definition.Value.columnDefinitions) { if (!string.IsNullOrEmpty(columnDefinition.Value.foreignTable) || !string.IsNullOrEmpty(columnDefinition.Value.foreignColumn)) { if (definitionCache.ContainsKey(columnDefinition.Value.foreignTable) && definitionCache[columnDefinition.Value.foreignTable].columnDefinitions.ContainsKey(columnDefinition.Value.foreignColumn)) { Console.ForegroundColor = ConsoleColor.Green; //Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn); } else { errorEncountered.Add(definition.Key); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn + " WHICH DOES NOT EXIST!"); } foreignKeys++; Console.ResetColor(); } } } Console.WriteLine("Checked " + foreignKeys + " foreign keys!"); if (errorEncountered.Count != 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("There have been errors in the following dbds:"); foreach (var dbName in errorEncountered) { Console.WriteLine(" - " + dbName); } Environment.Exit(1); } else { Console.WriteLine("Done"); } }
static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: <firstdir> <seconddir> <outdir>"); Environment.Exit(1); } var firstDir = args[0]; var secondDir = args[1]; var targetDir = args[2]; var firstDirFiles = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name).ToList(); var secondDirFiles = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name).ToList(); var newDefinitions = new Dictionary <string, DBDefinition>(); var reader = new DBDReader(); foreach (var file in secondDirFiles) { var dbName = Path.GetFileNameWithoutExtension(file); if (firstDirFiles.Contains(file)) { // Both directories have this file. Merge! var firstFile = reader.Read(Path.Combine(firstDir, file)); var secondFile = reader.Read(Path.Combine(secondDir, file)); var newDefinition = firstFile; // Merge column definitions foreach (var columnDefinition2 in secondFile.columnDefinitions) { var foundCol = false; foreach (var columnDefinition1 in firstFile.columnDefinitions) { if (columnDefinition2.Key.ToLower() == columnDefinition1.Key.ToLower()) { foundCol = true; var typeOverride = ""; if (columnDefinition2.Value.type != columnDefinition1.Value.type) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Types are different for (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and (2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", using type " + columnDefinition2.Value.type + " from 2"); typeOverride = columnDefinition2.Value.type; // If this is an uncommon conversion (not uint -> int) override the version's column type if ((columnDefinition1.Value.type == "uint" && columnDefinition2.Value.type == "int") || (columnDefinition1.Value.type == "int" && columnDefinition2.Value.type == "uint")) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", ignoring.."); } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Unexpected type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type); Console.WriteLine("Adding override to type " + columnDefinition2.Value.type + " for the column in this version!"); for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { secondFile.versionDefinitions[i].definitions[j].typeOverride = columnDefinition2.Value.type; break; } } } } // Only change type in column definitions if we're not already overriding it if (string.IsNullOrWhiteSpace(typeOverride)) { var tempDefs = newDefinition.columnDefinitions; newDefinition.columnDefinitions = new Dictionary <string, ColumnDefinition>(); // TODO: Figure out a better way to "rebuild" column dictionary foreach (var columnDef1 in tempDefs) { if (columnDef1.Key == columnDefinition1.Key) { var newVal = columnDef1.Value; // Use newer type to override old one newVal.type = columnDefinition2.Value.type; newDefinition.columnDefinitions.Add(columnDef1.Key, newVal); } else { newDefinition.columnDefinitions.Add(columnDef1.Key, columnDef1.Value); } } } Console.ResetColor(); } if (columnDefinition2.Key != columnDefinition1.Key) { if (Utils.NormalizeColumn(columnDefinition2.Key, true) == columnDefinition1.Key) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Automagically fixed casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key); for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { secondFile.versionDefinitions[i].definitions[j].name = Utils.NormalizeColumn(columnDefinition2.Key, true); break; } } } } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Unable to automagically fix casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key + ", falling back to (1) naming"); for (var i = 0; i < secondFile.versionDefinitions.Length; i++) { for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++) { if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key) { secondFile.versionDefinitions[i].definitions[j].name = columnDefinition1.Key; break; } } } } Console.ResetColor(); } break; } } if (!foundCol) { // Column was not found, add it Console.WriteLine(dbName + "::" + columnDefinition2.Key + " was not found found in first file!"); newDefinition.columnDefinitions.Add(columnDefinition2.Key, columnDefinition2.Value); } } // Merge version definitions foreach (var versionDefinition2 in secondFile.versionDefinitions) { var foundVersion = false; foreach (var versionDefinition1 in firstFile.versionDefinitions) { foreach (var layoutHash2 in versionDefinition2.layoutHashes) { if (versionDefinition1.layoutHashes.Contains(layoutHash2)) { foundVersion = true; break; } } // If layouthash was found, don't check builds if (foundVersion) { break; } // Check builds foreach (var build2 in versionDefinition2.builds) { foreach (var build1 in versionDefinition1.builds) { if (build1.Equals(build2)) { foundVersion = true; break; } } foreach (var buildranges1 in versionDefinition1.buildRanges) { if (build2.expansion == buildranges1.minBuild.expansion && build2.major == buildranges1.minBuild.major && build2.minor == buildranges1.minBuild.minor) { if (build2.build >= buildranges1.minBuild.build && build2.build <= buildranges1.maxBuild.build) { //Console.WriteLine("Build match? Build " + Utils.BuildToString(build2) + " seem to match with " + Utils.BuildToString(buildranges1.minBuild) + "-" + Utils.BuildToString(buildranges1.maxBuild)); foundVersion = true; break; } } } } } if (!foundVersion) { // Version was not found, add it! // TODO: Only for secondFile, not firstFile! var mergedWithPreviousBuild = false; var newVersions = newDefinition.versionDefinitions.ToList(); for (var i = 0; i < newVersions.Count; i++) { if (newVersions[i].definitions.SequenceEqual(versionDefinition2.definitions)) { Console.WriteLine("Looks like these two definition arrays are the same!"); var curBuilds = newVersions[i].builds.ToList(); curBuilds.AddRange(versionDefinition2.builds.ToList()); var tempVersion = newVersions[i]; tempVersion.builds = curBuilds.ToArray(); newVersions[i] = tempVersion; mergedWithPreviousBuild = true; } } if (!mergedWithPreviousBuild) { newVersions.Add(versionDefinition2); } newDefinition.versionDefinitions = newVersions.ToArray(); } else { // Version exists, compare stuff // TODO } } newDefinitions.Add(dbName, newDefinition); } else { // Only 2nd dir has this file, use that newDefinitions.Add(dbName, reader.Read(Path.Combine(secondDir, file))); } } foreach (var file in firstDirFiles) { if (!secondDirFiles.Contains(file)) { // Only 1st dir has this file, use that newDefinitions.Add(Path.GetFileNameWithoutExtension(file), reader.Read(Path.Combine(firstDir, file))); } } var writer = new DBDWriter(); foreach (var entry in newDefinitions) { writer.Save(entry.Value, Path.Combine(targetDir, entry.Key + ".dbd")); } //Console.ReadLine(); }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: <definitionsdir> (rewrite when done: bool, default false) (verbose: bool, default true) (rawRepoDir: location of WoWDBDefsRaw repository, default none)"); Environment.Exit(1); } var definitionDir = args[0]; var rewrite = false; var verbose = true; var checkRaw = false; var rawRepoDir = ""; if (args.Length >= 2 && args[1] == "true") { rewrite = true; } if (args.Length >= 3 && args[2] == "false") { verbose = false; } if (args.Length >= 4) { checkRaw = true; rawRepoDir = args[3]; } var errorEncountered = new List <string>(); foreach (var file in Directory.GetFiles(definitionDir)) { var dbName = Path.GetFileNameWithoutExtension(file); var reader = new DBDReader(); try { definitionCache.Add(dbName, reader.Read(file, true)); if (verbose) { Console.WriteLine("Read " + definitionCache[dbName].versionDefinitions.Length + " versions and " + definitionCache[dbName].columnDefinitions.Count + " columns for " + dbName); } if (rewrite) { var writer = new DBDWriter(); writer.Save(definitionCache[dbName], Path.Combine(definitionDir, dbName + ".dbd"), true); } } catch (Exception ex) { errorEncountered.Add(dbName); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Failed to read " + dbName + ": " + ex); Console.ResetColor(); } } Console.WriteLine("Read " + definitionCache.Count + " database definitions!"); var foreignKeys = 0; foreach (var definition in definitionCache) { foreach (var columnDefinition in definition.Value.columnDefinitions) { if (!string.IsNullOrEmpty(columnDefinition.Value.foreignTable) || !string.IsNullOrEmpty(columnDefinition.Value.foreignColumn)) { if (definitionCache.ContainsKey(columnDefinition.Value.foreignTable) && definitionCache[columnDefinition.Value.foreignTable].columnDefinitions.ContainsKey(columnDefinition.Value.foreignColumn)) { Console.ForegroundColor = ConsoleColor.Green; //Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn); } else { errorEncountered.Add(definition.Key); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn + " WHICH DOES NOT EXIST!"); } foreignKeys++; Console.ResetColor(); } } } Console.WriteLine("Checked " + foreignKeys + " foreign keys!"); if (checkRaw) { Console.WriteLine("Checking for differences between raw definitions and target definitions (limited to 9.0+)"); if (!Directory.Exists(rawRepoDir)) { throw new DirectoryNotFoundException("Could not find WoWDBDefsRaw repository"); } foreach (var definition in definitionCache) { foreach (var versionDefinition in definition.Value.versionDefinitions) { foreach (var build in versionDefinition.builds) { // TODO: There are issues in older expansions, but limit to 9.0+ for now if (build.expansion < 9) { continue; } var rawDefLocation = Path.Combine(rawRepoDir, build.ToString(), definition.Key + ".dbd"); // Definitions for really old versions aren't in raw repo, we can't check those. if (!File.Exists(rawDefLocation)) { continue; } var rawDefReader = new DBDReader(); var rawDef = rawDefReader.Read(rawDefLocation); if (versionDefinition.definitions.Length != rawDef.versionDefinitions[0].definitions.Length) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[" + definition.Key + "] [" + build + "] Column count mismatch between raw (" + rawDef.versionDefinitions[0].definitions.Length + ") and target definition (" + versionDefinition.definitions.Length + ")"); errorEncountered.Add(definition.Key); continue; } for (var i = 0; i < versionDefinition.definitions.Length; i++) { var targetColDef = versionDefinition.definitions[i]; var rawColDef = rawDef.versionDefinitions[0].definitions[i]; if (rawColDef.isSigned != targetColDef.isSigned) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " signedness mismatch: " + rawColDef.isSigned + " <-> " + targetColDef.isSigned); errorEncountered.Add(definition.Key); } if (rawColDef.size != targetColDef.size) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " size mismatch: " + rawColDef.size + " <-> " + targetColDef.size); errorEncountered.Add(definition.Key); } if (rawColDef.arrLength != targetColDef.arrLength) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " array length mismatch: " + rawColDef.arrLength + " <-> " + targetColDef.arrLength); errorEncountered.Add(definition.Key); } if (rawColDef.isRelation != targetColDef.isRelation) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " relation mismatch: " + rawColDef.isRelation + " <-> " + targetColDef.isRelation); errorEncountered.Add(definition.Key); } Console.ResetColor(); } } } } } errorEncountered = errorEncountered.Distinct().ToList(); if (errorEncountered.Count != 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("There have been errors in the following DBDs:"); foreach (var dbName in errorEncountered) { Console.WriteLine(" - " + dbName); } Environment.Exit(1); } else { Console.WriteLine("Done"); } }