BizHawk/BizHawk.Client.DBMan/DB.cs

456 lines
15 KiB
C#

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<Rom> Roms = new List<Rom>();
public static List<Game> Games = new List<Game>();
public static Dictionary<string, Game> GameMap = new Dictionary<string, Game>();
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<Tuple<string, string>>();
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<string, string>(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<string> GetDeveloperPublisherNames()
{
var names = new List<string>();
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();
}
}
}