mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Field possible database changes
The current format of the database is good for small amounts of data. The truth is that the hashes and sizes of the files are what really determine if a file is different or not. After chatting with Obiwantje about this, I'm beginning some code tests with a hash-centric database model, instead of the game/rom centric. This means that each hash can have mutliple roms attached to it, similarly a given game can have multiple sources or systems attached. It's a much cleaner system, but demands a total rewrite and new databae structure.
This commit is contained in:
@@ -429,6 +429,7 @@ namespace SabreTools
|
||||
/// <param name="sysid">System ID for the game to be added with</param>
|
||||
/// <param name="machinename">Name of the game to be added</param>
|
||||
/// <param name="srcid">Source ID for the game to be added with</param>
|
||||
/// <param name="dbc">SQLite database connection to use</param>
|
||||
/// <returns>Game ID of the inserted (or found) game, -1 on error</returns>
|
||||
private long AddGame(int sysid, string machinename, int srcid, SqliteConnection dbc)
|
||||
{
|
||||
@@ -488,6 +489,7 @@ namespace SabreTools
|
||||
/// <param name="rom">RomData object representing the rom</param>
|
||||
/// <param name="gameid">ID of the parent game to be mapped to</param>
|
||||
/// <param name="date">Last updated date</param>
|
||||
/// <param name="dbc">SQLite database connection to use</param>
|
||||
/// <returns>True if the file exists or could be added, false on error</returns>
|
||||
private bool AddRom(RomData rom, long gameid, string date, SqliteConnection dbc)
|
||||
{
|
||||
@@ -547,5 +549,97 @@ COMMIT;";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a hash to the database if it doesn't exist already
|
||||
/// </summary>
|
||||
/// <param name="rom">RomData object representing the rom</param>
|
||||
/// <param name="sysid">System ID for the game to be added with</param>
|
||||
/// <param name="srcid">Source ID for the game to be added with</param>
|
||||
/// <param name="date">Last updated date</param>
|
||||
/// <param name="dbc">SQLite database connection to use</param>
|
||||
/// <returns>True if the hash exists or could be added, false on error</returns>
|
||||
/// <remarks>This is currently unused. It is a test method for the new SabreTools DB schema</remarks>
|
||||
private bool AddHash(RomData rom, int sysid, int srcid, string date, SqliteConnection dbc)
|
||||
{
|
||||
// Process the game name
|
||||
|
||||
// WoD gets rid of anything past the first "(" or "[" as the name, we will do the same
|
||||
string stripPattern = @"(([[(].*[\)\]] )?([^([]+))";
|
||||
Regex stripRegex = new Regex(stripPattern);
|
||||
Match stripMatch = stripRegex.Match(rom.Game);
|
||||
rom.Game = stripMatch.Groups[1].Value;
|
||||
|
||||
// Run the name through the filters to make sure that it's correct
|
||||
rom.Game = Style.NormalizeChars(rom.Game);
|
||||
rom.Game = Style.RussianToLatin(rom.Game);
|
||||
rom.Game = Style.SearchPattern(rom.Game);
|
||||
rom.Game = rom.Game.Trim();
|
||||
|
||||
// Process the rom name
|
||||
|
||||
// WOD origninally stripped out any subdirs from the imported files, we do the same
|
||||
rom.Name = Path.GetFileName(rom.Name);
|
||||
|
||||
// Run the name through the filters to make sure that it's correct
|
||||
rom.Name = Style.NormalizeChars(rom.Name);
|
||||
rom.Name = Style.RussianToLatin(rom.Name);
|
||||
rom.Name = Regex.Replace(rom.Name, @"(.*) \.(.*)", "$1.$2");
|
||||
|
||||
// Retrieve or insert the hash
|
||||
long hashid = -1;
|
||||
string query = "SELECT id FROM hash WHERE size=" + rom.Size + " AND crc='" + rom.CRC + "' AND md5='" + rom.MD5 + "' AND sha1='" + rom.SHA1 + "'";
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If nothing is found, add the hash and get the insert ID
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
query = "INSERT INTO hash (size, crc, md5, sha1)" +
|
||||
" VALUES (" + rom.Size + ", '" + rom.CRC + "', '" + rom.MD5 + "', '" + rom.SHA1 + "')";
|
||||
|
||||
using (SqliteCommand slc2 = new SqliteCommand(query, dbc))
|
||||
{
|
||||
slc2.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
query = "SELECT last_insert_rowid()";
|
||||
using (SqliteCommand slc2 = new SqliteCommand(query, dbc))
|
||||
{
|
||||
hashid = (long)slc2.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
// Otherwise, retrieve the ID
|
||||
else
|
||||
{
|
||||
sldr.Read();
|
||||
hashid = sldr.GetInt64(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore or insert the file and game
|
||||
query = @"BEGIN;
|
||||
INSERT OR IGNORE INTO hashdata (hashid, key, value) VALUES " +
|
||||
"(" + hashid + ", 'name', '" + rom.Name + "'), " +
|
||||
"(" + hashid + ", 'game', '" + rom.Game + "'), " +
|
||||
"(" + hashid + ", 'lastupdated', '" + date + @"');
|
||||
INSERT OR IGNORE INTO gamesystem (game, systemid) VALUES ('" + rom.Game + "', " + sysid + @");
|
||||
INSERT OR IGNORE INTO gamesource (game, sourceid) VALUES ('" + rom.Game + "', " + srcid + @");
|
||||
COMMIT;";
|
||||
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
int ret = slc.ExecuteNonQuery();
|
||||
if ((SQLiteErrorCode)ret != SQLiteErrorCode.Done && (SQLiteErrorCode)ret != SQLiteErrorCode.Ok)
|
||||
{
|
||||
_logger.Error("A SQLite error has occurred: " + ((SQLiteErrorCode)ret).ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,65 @@ CREATE TABLE IF NOT EXISTS data (
|
||||
SqliteCommand slc = new SqliteCommand(query, dbc);
|
||||
slc.ExecuteNonQuery();
|
||||
}
|
||||
else if (type == "SabreTools")
|
||||
{
|
||||
string query = @"
|
||||
CREATE TABLE IF NOT EXISTS hash (
|
||||
'id' INTEGER PRIMARY KEY NOT NULL,
|
||||
'size' INTEGER NOT NULL DEFAULT -1,
|
||||
'crc' TEXT NOT NULL,
|
||||
'md5' TEXT NOT NULL,
|
||||
'sha1' TEXT NOT NULL
|
||||
)";
|
||||
SqliteCommand slc = new SqliteCommand(query, dbc);
|
||||
slc.ExecuteNonQuery();
|
||||
|
||||
query = @"
|
||||
CREATE TABLE IF NOT EXISTS hashdata (
|
||||
'hashid' INTEGER NOT NULL,
|
||||
'key' TEXT NOT NULL,
|
||||
'value' TEXT,
|
||||
PRIMARY KEY (hashid, key, value)
|
||||
)";
|
||||
slc = new SqliteCommand(query, dbc);
|
||||
slc.ExecuteNonQuery();
|
||||
|
||||
query = @"
|
||||
CREATE TABLE IF NOT EXISTS source (
|
||||
'id' INTEGER PRIMARY KEY NOT NULL,
|
||||
'name' TEXT NOT NULL UNIQUE,
|
||||
'url' TEXT NOT NULL
|
||||
)";
|
||||
slc = new SqliteCommand(query, dbc);
|
||||
slc.ExecuteNonQuery();
|
||||
|
||||
query = @"
|
||||
CREATE TABLE IF NOT EXISTS system (
|
||||
'id' INTEGER PRIMARY KEY NOT NULL,
|
||||
'manufacturer' TEXT NOT NULL,
|
||||
'name' TEXT NOT NULL
|
||||
)";
|
||||
slc = new SqliteCommand(query, dbc);
|
||||
slc.ExecuteNonQuery();
|
||||
|
||||
query = @"
|
||||
CREATE TABLE IF NOT EXISTS gamesystem (
|
||||
'game' TEXT NOT NULL,
|
||||
'systemid' INTEGER NOT NULL,
|
||||
PRIMARY KEY (game, systemid)
|
||||
)";
|
||||
slc = new SqliteCommand(query, dbc);
|
||||
slc.ExecuteNonQuery();
|
||||
|
||||
query = @"
|
||||
CREATE TABLE IF NOT EXISTS gamesource (
|
||||
'game' TEXT NOT NULL,
|
||||
'sourceid' INTEGER NOT NULL,
|
||||
PRIMARY KEY (game, sourceid)
|
||||
)";
|
||||
slc = new SqliteCommand(query, dbc);
|
||||
slc.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user