using System; using System.Collections.Generic; using System.Linq; using System.Text; using Community.CsharpSqlite.SQLiteClient; namespace BizHawk.Client.DBMan { public class Rom { public long RomId; public string CRC32; public string MD5; public string SHA1; public string System; public string Name; public string Region; public string VersionTags; public string RomMetadata; public string RomStatus; public string Catalog; public long Size; public DateTime Created; public DateTime Modified; public override string ToString() { return Name + " " + VersionTags; } public Game Game; public string CombinedMetaData { get { if (Game == null) return RomMetadata; if (Game.GameMetadata == null) return RomMetadata; if (RomMetadata == null) return Game.GameMetadata; return Game.GameMetadata + ";" + RomMetadata; } } public string SizeFriendly { get { return string.Format("{0} bytes ({1}k)", Size, Size / 1024); } } public bool New { get { return (Created > Modified); } } public string NameWithTheFlipped { get { if (!Name.EndsWith(", The")) return Name; return "The "+Name.Substring(0, Name.Length-5); } } public string SortString() { var ret = ""; if (Game.Classification == "Firmware") ret += "[BIOS] "; if (Game.Classification == "Homebrew") ret += "[Homebrew] "; if (Game.Classification == "Test Rom") ret += "[Test ROM] "; ret += Name; ret += "|" + RegionRank + "|" + VersionTags; return ret; } public string DisplayName { get { var ret = ""; if (Game.Classification == "Firmware") ret += "[BIOS] "; if (Game.Classification == "Homebrew") ret += "[Homebrew] "; if (Game.Classification == "Test Rom") ret += "[Test ROM] "; ret += Name; return ret; } } public int RegionRank { get { if (String.IsNullOrEmpty(Region)) return 99; if (Region.Contains("World")) return 1; if (Region.Contains("USA")) return 2; if (Region.Contains("Europe")) return 3; if (Region.Contains("Japan")) return 4; return Region.GetHashCode(); } } } public class Game { public long GameId; public string System; public string Name; public string Developer; public string Publisher; public string Classification; public string ReleaseDate; public string Players; public string GameMetadata; public string Tags; public string AltNames; public string Notes; public DateTime Created; public DateTime Modified; public override string ToString() { return Name; } } public static class DB { public static List Roms = new List(); public static List Games = new List(); public static Dictionary GameMap = new Dictionary(); public static SqliteConnection Con; public static void LoadDbForSystem(string system) { Games.Clear(); Roms.Clear(); LoadGames(system); LoadRoms(system); } static void LoadGames(string system) { var cmd = Con.CreateCommand(); cmd.CommandText = "SELECT game_id, system, name, developer, publisher, classification, release_date, players, game_metadata, tags, alternate_names, notes "+ "FROM game "+ "WHERE system = @System"; cmd.Parameters.Add(new SqliteParameter("@System", system)); var reader = cmd.ExecuteReader(); while (reader.NextResult()) { var game = new Game(); game.GameId = reader.GetInt64(0); game.System = reader.GetString(1); game.Name = reader.GetString(2); game.Developer = reader.GetString(3); game.Publisher = reader.GetString(4); game.Classification = reader.GetString(5); game.ReleaseDate = reader.GetString(6); game.Players = reader.GetString(7); game.GameMetadata = reader.GetString(8); game.Tags = reader.GetString(9); game.AltNames = reader.GetString(10); game.Notes = reader.GetString(11); Games.Add(game); GameMap[game.Name] = game; } reader.Dispose(); cmd.Dispose(); } static void LoadRoms(string system) { var cmd = Con.CreateCommand(); cmd.CommandText = "SELECT rom_id, crc32, md5, sha1, system, name, region, version_tags, rom_metadata, rom_status, catalog, size, created_date, modified_date " + "FROM rom " + "WHERE system = @System"; cmd.Parameters.Add(new SqliteParameter("@System", system)); var reader = cmd.ExecuteReader(); while (reader.NextResult()) { var rom = new Rom(); rom.RomId = reader.GetInt64(0); rom.CRC32 = reader.GetString(1); rom.MD5 = reader.GetString(2); rom.SHA1 = reader.GetString(3); rom.System = reader.GetString(4); rom.Name = reader.GetString(5); rom.Region = reader.GetString(6); rom.VersionTags = reader.GetString(7); rom.RomMetadata = reader.GetString(8); rom.RomStatus = reader.GetString(9); rom.Catalog = reader.GetString(10); rom.Size = reader.GetInt64(11); rom.Created = reader.GetDateTime(12); rom.Modified = reader.GetDateTime(13); rom.Game = GameMap[rom.Name]; Roms.Add(rom); } reader.Dispose(); cmd.Dispose(); Roms = Roms.OrderBy(x=>x.SortString()).ToList(); } public static void SaveRom(Rom rom) { var cmd = Con.CreateCommand(); cmd.CommandText = "UPDATE rom SET "+ "region=@Region, "+ "version_tags=@VersionTags, "+ "rom_metadata=@RomMetadata, "+ "rom_status=@RomStatus, "+ "catalog=@Catalog, " + "modified_date=datetime('now','localtime') " + "WHERE rom_id=@RomId"; cmd.Parameters.Add(new SqliteParameter("@Region", rom.Region)); cmd.Parameters.Add(new SqliteParameter("@VersionTags", rom.VersionTags)); cmd.Parameters.Add(new SqliteParameter("@RomMetadata", rom.RomMetadata)); cmd.Parameters.Add(new SqliteParameter("@RomStatus", rom.RomStatus)); cmd.Parameters.Add(new SqliteParameter("@Catalog", rom.Catalog)); cmd.Parameters.Add(new SqliteParameter("@RomId", rom.RomId)); cmd.ExecuteNonQuery(); cmd.Dispose(); cmd = Con.CreateCommand(); cmd.CommandText = "UPDATE game SET "+ "developer=@Developer, "+ "publisher=@Publisher, "+ "classification=@Classification, "+ "release_date=@ReleaseDate, "+ "players=@Players, "+ "game_metadata=@GameMetadata, "+ "tags=@Tags, "+ "alternate_names=@AltNames, "+ "notes=@Notes, "+ "modified_date=datetime('now','localtime') " + "WHERE game_id=@GameId"; cmd.Parameters.Add(new SqliteParameter("@Developer", rom.Game.Developer)); cmd.Parameters.Add(new SqliteParameter("@Publisher", rom.Game.Publisher)); cmd.Parameters.Add(new SqliteParameter("@Classification", rom.Game.Classification)); cmd.Parameters.Add(new SqliteParameter("@ReleaseDate", rom.Game.ReleaseDate)); cmd.Parameters.Add(new SqliteParameter("@Players", rom.Game.Players)); cmd.Parameters.Add(new SqliteParameter("@GameMetadata", rom.Game.GameMetadata)); cmd.Parameters.Add(new SqliteParameter("@Tags", rom.Game.Tags)); cmd.Parameters.Add(new SqliteParameter("@AltNames", rom.Game.AltNames)); cmd.Parameters.Add(new SqliteParameter("@Notes", rom.Game.Notes)); cmd.Parameters.Add(new SqliteParameter("@GameId", rom.Game.GameId)); cmd.ExecuteNonQuery(); cmd.Dispose(); } public static void SaveRom1(Rom rom, string origSystem, string origName) { // Does this game already exist? var game = GameExists(rom.System, rom.Name); if (game != null) // existing game with this system/name already exists. we'll merge to it. (existing game wins) { DeleteGame(origSystem, origName); rom.Game = game; } var cmd = Con.CreateCommand(); cmd.CommandText = "UPDATE rom SET " + "system=@System, " + "name=@Name " + "WHERE system=@OrigSystem and name=@OrigName"; cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); cmd.Parameters.Add(new SqliteParameter("@OrigSystem", origSystem)); cmd.Parameters.Add(new SqliteParameter("@OrigName", origName)); cmd.ExecuteNonQuery(); cmd.Dispose(); cmd = Con.CreateCommand(); cmd.CommandText = "UPDATE game SET " + "system=@System, " + "name=@Name " + "WHERE system=@OrigSystem and name=@OrigName"; cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); cmd.Parameters.Add(new SqliteParameter("@OrigSystem", origSystem)); cmd.Parameters.Add(new SqliteParameter("@OrigName", origName)); cmd.ExecuteNonQuery(); cmd.Dispose(); SaveRom(rom); } public static void SaveRom2(Rom rom) { var cmd = Con.CreateCommand(); cmd.CommandText = "UPDATE rom SET " + "system=@System, "+ "name=@Name, "+ "region=@Region, " + "version_tags=@VersionTags, " + "rom_metadata=@RomMetadata, " + "rom_status=@RomStatus, " + "catalog=@Catalog, " + "modified_date=datetime('now','localtime') " + "WHERE rom_id=@RomId"; cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); cmd.Parameters.Add(new SqliteParameter("@Region", rom.Region)); cmd.Parameters.Add(new SqliteParameter("@VersionTags", rom.VersionTags)); cmd.Parameters.Add(new SqliteParameter("@RomMetadata", rom.RomMetadata)); cmd.Parameters.Add(new SqliteParameter("@RomStatus", rom.RomStatus)); cmd.Parameters.Add(new SqliteParameter("@Catalog", rom.Catalog)); cmd.Parameters.Add(new SqliteParameter("@RomId", rom.RomId)); cmd.ExecuteNonQuery(); cmd.Dispose(); bool gameAlreadyExists = false; cmd = Con.CreateCommand(); cmd.CommandText = "SELECT game_id FROM game WHERE system=@System and name=@Name"; cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); gameAlreadyExists = cmd.ExecuteScalar() != null; cmd.Dispose(); if (!gameAlreadyExists) { cmd = Con.CreateCommand(); cmd.CommandText = "INSERT INTO game (system, name, created_date) values (@System, @Name, datetime('now','localtime'))"; cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); cmd.ExecuteNonQuery(); cmd.Dispose(); } cmd = Con.CreateCommand(); cmd.CommandText = "UPDATE game SET " + "developer=@Developer, " + "publisher=@Publisher, " + "classification=@Classification, " + "release_date=@ReleaseDate, " + "players=@Players, " + "game_metadata=@GameMetadata, " + "tags=@Tags, " + "alternate_names=@AltNames, " + "notes=@Notes, " + "modified_date=datetime('now','localtime') " + "WHERE system=@System and name=@Name"; cmd.Parameters.Add(new SqliteParameter("@Developer", rom.Game.Developer)); cmd.Parameters.Add(new SqliteParameter("@Publisher", rom.Game.Publisher)); cmd.Parameters.Add(new SqliteParameter("@Classification", rom.Game.Classification)); cmd.Parameters.Add(new SqliteParameter("@ReleaseDate", rom.Game.ReleaseDate)); cmd.Parameters.Add(new SqliteParameter("@Players", rom.Game.Players)); cmd.Parameters.Add(new SqliteParameter("@GameMetadata", rom.Game.GameMetadata)); cmd.Parameters.Add(new SqliteParameter("@Tags", rom.Game.Tags)); cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); cmd.Parameters.Add(new SqliteParameter("@AltNames", rom.Game.AltNames)); cmd.Parameters.Add(new SqliteParameter("@Notes", rom.Game.Notes)); cmd.ExecuteNonQuery(); cmd.Dispose(); } public static void Cleanup() { var orphanedGameList = new List>(); var cmd = Con.CreateCommand(); cmd.CommandText = "SELECT system, name FROM game "+ "EXCEPT "+ "SELECT system, name FROM rom"; var reader = cmd.ExecuteReader(); while (reader.NextResult()) { string system = reader.GetString(0); string name = reader.GetString(1); orphanedGameList.Add(new Tuple(system, name)); } reader.Dispose(); cmd.Dispose(); cmd = Con.CreateCommand(); cmd.CommandText = "DELETE FROM game WHERE system=@System and name=@Name"; foreach (var orphanedGame in orphanedGameList) { cmd.Parameters.Clear(); cmd.Parameters.Add(new SqliteParameter("@System", orphanedGame.Item1)); cmd.Parameters.Add(new SqliteParameter("@Name", orphanedGame.Item2)); cmd.ExecuteNonQuery(); } cmd.Dispose(); cmd = Con.CreateCommand(); cmd.CommandText = "VACUUM"; cmd.ExecuteNonQuery(); cmd.Dispose(); } public static List GetDeveloperPublisherNames() { var names = new List(); var cmd = Con.CreateCommand(); cmd.CommandText = "SELECT DISTINCT developer FROM game WHERE developer is not null and classification not in ('Homebrew','Test Rom')" + "UNION " + "SELECT DISTINCT publisher FROM game WHERE publisher is not null and classification not in ('Homebrew','Test Rom')"; var reader = cmd.ExecuteReader(); while (reader.NextResult()) { names.Add(reader.GetString(0)); } reader.Dispose(); cmd.Dispose(); return names; } static Game GameExists(string system, string name) { var game = new Game(); var cmd = Con.CreateCommand(); cmd.CommandText = "SELECT game_id, system, name, developer, publisher, classification, release_date, players, game_metadata, tags, alternate_names, notes FROM game WHERE system = @System and name = @Name"; cmd.Parameters.Add(new SqliteParameter("@System", system)); cmd.Parameters.Add(new SqliteParameter("@Name", name)); var reader = cmd.ExecuteReader(); if (reader.NextResult()) { game.GameId = reader.GetInt64(0); game.System = reader.GetString(1); game.Name = reader.GetString(2); game.Developer = reader.GetString(3); game.Publisher = reader.GetString(4); game.Classification = reader.GetString(5); game.ReleaseDate = reader.GetString(6); game.Players = reader.GetString(7); game.GameMetadata = reader.GetString(8); game.Tags = reader.GetString(9); game.AltNames = reader.GetString(10); game.Notes = reader.GetString(11); } reader.Dispose(); cmd.Dispose(); if (game.GameId == 0) return null; return game; } static void DeleteGame(string system, string name) { var cmd = Con.CreateCommand(); cmd.CommandText = "DELETE FROM game WHERE system=@System and name=@Name"; cmd.Parameters.Add(new SqliteParameter("@System", system)); cmd.Parameters.Add(new SqliteParameter("@Name", name)); cmd.ExecuteNonQuery(); cmd.Dispose(); } public static void DeleteRom(Rom rom) { var cmd = Con.CreateCommand(); cmd.CommandText = "DELETE FROM rom WHERE md5 = @Md5"; cmd.Parameters.Add(new SqliteParameter("@Md5", rom.MD5)); cmd.ExecuteNonQuery(); cmd.Dispose(); } } }