This commit is contained in:
Michael Green
2024-11-20 11:16:10 +11:00
parent 74171b50af
commit ca2dbfb4cd
7 changed files with 367 additions and 114 deletions

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography; using System.Security.Cryptography;
using gaseous_server.Classes.Metadata;
using HasheousClient.Models.Metadata.IGDB; using HasheousClient.Models.Metadata.IGDB;
namespace gaseous_server.Classes namespace gaseous_server.Classes
@@ -12,6 +13,37 @@ namespace gaseous_server.Classes
} }
public static void ImportBiosFile(string FilePath, Common.hashObject Hash, ref Dictionary<string, object> BiosFileInfo)
{
BiosFileInfo.Add("type", "bios");
BiosFileInfo.Add("status", "notimported");
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
{
if (biosItem.Available == false)
{
if (biosItem.hash == Hash.md5hash)
{
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, biosItem.hash + ".bios");
Logging.Log(Logging.LogType.Information, "Import BIOS File", " " + FilePath + " is a BIOS file - moving to " + biosPath);
File.Move(FilePath, biosItem.biosPath, true);
BiosFileInfo.Add("name", biosItem.filename);
BiosFileInfo.Add("platform", Platforms.GetPlatform(biosItem.platformid));
BiosFileInfo["status"] = "imported";
}
}
else
{
if (biosItem.hash == Hash.md5hash)
{
BiosFileInfo["status"] = "duplicate";
}
}
}
}
public static void MigrateToNewFolderStructure() public static void MigrateToNewFolderStructure()
{ {
// migrate from old BIOS file structure which had each bios file inside a folder named for the platform to the new structure which has each file in a subdirectory named after the MD5 hash // migrate from old BIOS file structure which had each bios file inside a folder named for the platform to the new structure which has each file in a subdirectory named after the MD5 hash

View File

@@ -322,7 +322,7 @@ namespace gaseous_server.Classes
switch (metadataResult.Source) switch (metadataResult.Source)
{ {
case HasheousClient.Models.MetadataSources.IGDB: case HasheousClient.Models.MetadataSources.IGDB:
signature.Flags.IGDBPlatformId = (long)Platforms.GetPlatform(metadataResult.Id, false).Id; signature.Flags.IGDBPlatformId = (long)Platforms.GetPlatform(metadataResult.Id).Id;
break; break;
} }
} }

View File

@@ -18,6 +18,15 @@ namespace gaseous_server.Classes
{ {
public class ImportGame : QueueItemStatus public class ImportGame : QueueItemStatus
{ {
/// <summary>
/// Scan the import directory for games and process them
/// </summary>
/// <param name="ImportPath">
/// The path to the directory to scan
/// </param>
/// <exception cref="DirectoryNotFoundException">
/// Thrown when the import directory does not exist
/// </exception>
public void ProcessDirectory(string ImportPath) public void ProcessDirectory(string ImportPath)
{ {
if (Directory.Exists(ImportPath)) if (Directory.Exists(ImportPath))
@@ -47,22 +56,29 @@ namespace gaseous_server.Classes
} }
} }
/// <summary>
/// Import a single game file
/// </summary>
/// <param name="GameFileImportPath">
/// The path to the game file to import
/// </param>
/// <param name="OverridePlatform">
/// The platform to use for the game file
/// </param>
/// <returns>
/// A dictionary containing the results of the import
/// </returns>
public Dictionary<string, object> ImportGameFile(string GameFileImportPath, Platform? OverridePlatform) public Dictionary<string, object> ImportGameFile(string GameFileImportPath, Platform? OverridePlatform)
{ {
Dictionary<string, object> RetVal = new Dictionary<string, object>(); Dictionary<string, object> RetVal = new Dictionary<string, object>();
RetVal.Add("path", Path.GetFileName(GameFileImportPath)); RetVal.Add("path", Path.GetFileName(GameFileImportPath));
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "";
Dictionary<string, object> dbDict = new Dictionary<string, object>();
if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase)) if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase))
{ {
Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath); Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath);
} }
else else
{ {
FileInfo fi = new FileInfo(GameFileImportPath);
Common.hashObject hash = new Common.hashObject(GameFileImportPath); Common.hashObject hash = new Common.hashObject(GameFileImportPath);
Models.PlatformMapping.PlatformMapItem? IsBios = Classes.Bios.BiosHashSignatureLookup(hash.md5hash); Models.PlatformMapping.PlatformMapItem? IsBios = Classes.Bios.BiosHashSignatureLookup(hash.md5hash);
@@ -70,114 +86,234 @@ namespace gaseous_server.Classes
if (IsBios == null) if (IsBios == null)
{ {
// file is a rom // file is a rom
RetVal.Add("type", "rom"); _ImportGameFile(GameFileImportPath, hash, ref RetVal, OverridePlatform);
// check to make sure we don't already have this file imported
sql = "SELECT COUNT(Id) AS count FROM view_Games_Roms WHERE MD5=@md5 AND SHA1=@sha1";
dbDict.Add("md5", hash.md5hash);
dbDict.Add("sha1", hash.sha1hash);
DataTable importDB = db.ExecuteCMD(sql, dbDict);
if ((Int64)importDB.Rows[0]["count"] > 0)
{
// import source was the import directory
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
{
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - moving to " + Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
string targetPathWithFileName = GameFileImportPath.Replace(Config.LibraryConfiguration.LibraryImportDirectory, Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
string targetPath = Path.GetDirectoryName(targetPathWithFileName);
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
File.Move(GameFileImportPath, targetPathWithFileName, true);
}
// import source was the upload directory
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
{
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - skipping import");
}
RetVal.Add("status", "duplicate");
}
else
{
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " not in database - processing");
FileSignature fileSignature = new FileSignature();
gaseous_server.Models.Signatures_Games discoveredSignature = fileSignature.GetFileSignature(GameLibrary.GetDefaultLibrary, hash, fi, GameFileImportPath);
// get discovered platform
Platform? determinedPlatform = null;
if (OverridePlatform == null)
{
determinedPlatform = Metadata.Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
if (determinedPlatform == null)
{
determinedPlatform = new Platform();
}
}
else
{
determinedPlatform = OverridePlatform;
discoveredSignature.Flags.IGDBPlatformId = (long)determinedPlatform.Id;
discoveredSignature.Flags.IGDBPlatformName = determinedPlatform.Name;
}
gaseous_server.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId, true);
// add to database
long RomId = StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath, 0, true);
// build return value
RetVal.Add("romid", RomId);
RetVal.Add("platform", determinedPlatform);
RetVal.Add("game", determinedGame);
RetVal.Add("signature", discoveredSignature);
RetVal.Add("status", "imported");
}
} }
else else
{ {
// file is a bios // file is a bios
RetVal.Add("type", "bios"); Bios.ImportBiosFile(GameFileImportPath, hash, ref RetVal);
RetVal.Add("status", "notimported");
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
{
if (biosItem.Available == false)
{
if (biosItem.hash == hash.md5hash)
{
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, biosItem.hash + ".bios");
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " is a BIOS file - moving to " + biosPath);
File.Move(GameFileImportPath, biosItem.biosPath, true);
RetVal.Add("name", biosItem.filename);
RetVal.Add("platform", Platforms.GetPlatform(biosItem.platformid));
RetVal["status"] = "imported";
return RetVal;
}
}
else
{
if (biosItem.hash == hash.md5hash)
{
RetVal["status"] = "duplicate";
return RetVal;
}
}
}
} }
} }
return RetVal; return RetVal;
} }
/// <summary>
/// Import a single game file
/// </summary>
/// <param name="FilePath">
/// The path to the game file to import
/// </param>
/// <param name="Hash">
/// The hash of the game file
/// </param>
/// <param name="GameFileInfo">
/// A dictionary to store the results of the import
/// </param>
/// <param name="OverridePlatform">
/// The platform to use for the game file
/// </param>
private static void _ImportGameFile(string FilePath, Common.hashObject Hash, ref Dictionary<string, object> GameFileInfo, Platform? OverridePlatform)
{
GameFileInfo.Add("type", "rom");
// check to make sure we don't already have this file imported
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "";
Dictionary<string, object> dbDict = new Dictionary<string, object>();
sql = "SELECT COUNT(Id) AS count FROM view_Games_Roms WHERE MD5=@md5 AND SHA1=@sha1";
dbDict.Add("md5", Hash.md5hash);
dbDict.Add("sha1", Hash.sha1hash);
DataTable importDB = db.ExecuteCMD(sql, dbDict);
if ((Int64)importDB.Rows[0]["count"] > 0)
{
// import source was the import directory
if (FilePath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
{
Logging.Log(Logging.LogType.Warning, "Import Game", " " + FilePath + " already in database - moving to " + Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
string targetPathWithFileName = FilePath.Replace(Config.LibraryConfiguration.LibraryImportDirectory, Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
string targetPath = Path.GetDirectoryName(targetPathWithFileName);
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
File.Move(FilePath, targetPathWithFileName, true);
}
// import source was the upload directory
if (FilePath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
{
Logging.Log(Logging.LogType.Warning, "Import Game", " " + FilePath + " already in database - skipping import");
}
GameFileInfo.Add("status", "duplicate");
}
else
{
Logging.Log(Logging.LogType.Information, "Import Game", " " + FilePath + " not in database - processing");
FileInfo fi = new FileInfo(FilePath);
FileSignature fileSignature = new FileSignature();
gaseous_server.Models.Signatures_Games discoveredSignature = fileSignature.GetFileSignature(GameLibrary.GetDefaultLibrary, Hash, fi, FilePath);
// get discovered platform
Platform? determinedPlatform = null;
if (OverridePlatform == null)
{
determinedPlatform = Metadata.Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
if (determinedPlatform == null)
{
determinedPlatform = new Platform();
}
}
else
{
determinedPlatform = OverridePlatform;
discoveredSignature.Flags.IGDBPlatformId = (long)determinedPlatform.Id;
discoveredSignature.Flags.IGDBPlatformName = determinedPlatform.Name;
}
// add to database
long RomId = StoreGame(GameLibrary.GetDefaultLibrary, Hash, discoveredSignature, determinedPlatform, FilePath, 0, false);
// build return value
GameFileInfo.Add("romid", RomId);
GameFileInfo.Add("platform", determinedPlatform);
GameFileInfo.Add("game", discoveredSignature.Game.Name);
GameFileInfo.Add("signature", discoveredSignature);
GameFileInfo.Add("status", "imported");
}
}
/// <summary>
/// Store a game in the database and move the file to the library (if required)
/// </summary>
/// <param name="library">
/// The library to store the game in
/// </param>
/// <param name="hash">
/// The hash of the game file
/// </param>
/// <param name="signature">
/// The signature of the game file
/// </param>
/// <param name="filePath">
/// The path to the game file
/// </param>
/// <param name="romId">
/// The ID of the ROM in the database (if it already exists, 0 if it doesn't)
/// </param>
/// <param name="SourceIsExternal">
/// Whether the source of the file is external to the library
/// </param>
public static long StoreGame(GameLibrary.LibraryItem library, Common.hashObject hash, Signatures_Games signature, Platform platform, string filePath, long romId = 0, bool SourceIsExternal = false)
{
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "";
Dictionary<string, object> dbDict = new Dictionary<string, object>();
// add the metadata map
// check if the map exists already
long mapId = 0;
sql = "SELECT ParentMapId FROM MetadataMapBridge WHERE SignatureGameName=@gamename AND SignaturePlatformId=@platformid;";
dbDict = new Dictionary<string, object>(){
{ "gamename", signature.Game.Name },
{ "platformid", platform.Id }
};
DataTable mapDT = db.ExecuteCMD(sql, dbDict);
if (mapDT.Rows.Count > 0)
{
mapId = (long)mapDT.Rows[0]["ParentMapId"];
}
else
{
sql = "INSERT INTO MetadataMapBridge (ParentMapId, SignatureGameName, SignaturePlatformId, MetadataSourceType, MetadataSourceId, Preferred, ProcessedAtImport) VALUES (@parentmapid, @gamename, @platformid, @metadatasourcetype, @metadatasourceid, @preferred, @processedatimport); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
dbDict = new Dictionary<string, object>(){
{ "parentmapid", 0 },
{ "gamename", signature.Game.Name },
{ "platformid", platform.Id },
{ "metadatasourcetype", MetadataModel.MetadataSources.None },
{ "metadatasourceid", 0 }, // set to zero as an initial value - another process will update this later
{ "preferred", 1 },
{ "processedatimport", 0 }
};
DataTable mapInsert = db.ExecuteCMD(sql, dbDict);
mapId = (long)mapInsert.Rows[0][0];
}
// add or update the rom
dbDict = new Dictionary<string, object>();
if (romId == 0)
{
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, RelativePath, MetadataSource, MetadataGameName, MetadataVersion, LibraryId, RomDataVersion, MetadataMapId) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid, @romdataversion, @metadatamapid); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
}
else
{
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion, RomDataVersion=@romdataversion, MetadataMapId=@metadatamapid WHERE Id=@id;";
dbDict.Add("id", romId);
}
dbDict.Add("platformid", Common.ReturnValueIfNull(platform.Id, 0));
dbDict.Add("gameid", 0); // set to 0 - no longer required as game is mapped using the MetadataMapBridge table
dbDict.Add("name", Common.ReturnValueIfNull(signature.Rom.Name, 0));
dbDict.Add("size", Common.ReturnValueIfNull(signature.Rom.Size, 0));
dbDict.Add("md5", hash.md5hash);
dbDict.Add("sha1", hash.sha1hash);
dbDict.Add("crc", Common.ReturnValueIfNull(signature.Rom.Crc, ""));
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(signature.Rom.DevelopmentStatus, ""));
dbDict.Add("metadatasource", signature.Rom.SignatureSource);
dbDict.Add("metadatagamename", signature.Game.Name);
dbDict.Add("metadataversion", 2);
dbDict.Add("libraryid", library.Id);
dbDict.Add("romdataversion", 2);
dbDict.Add("metadatamapid", mapId);
if (signature.Rom.Attributes != null)
{
if (signature.Rom.Attributes.Count > 0)
{
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(signature.Rom.Attributes));
}
else
{
dbDict.Add("attributes", "[ ]");
}
}
else
{
dbDict.Add("attributes", "[ ]");
}
dbDict.Add("romtype", (int)signature.Rom.RomType);
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(signature.Rom.RomTypeMedia, ""));
dbDict.Add("medialabel", Common.ReturnValueIfNull(signature.Rom.MediaLabel, ""));
string libraryRootPath = library.Path;
if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false)
{
libraryRootPath += Path.DirectorySeparatorChar;
}
dbDict.Add("path", filePath.Replace(libraryRootPath, ""));
DataTable romInsert = db.ExecuteCMD(sql, dbDict);
if (romId == 0)
{
romId = (long)romInsert.Rows[0][0];
}
// move to destination
if (library.IsDefaultLibrary == true)
{
//MoveGameFile(romId, SourceIsExternal);
}
return romId;
}
public static gaseous_server.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload) public static gaseous_server.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
{ {
if (Signature.Flags != null) if (Signature.Flags != null)

View File

@@ -37,7 +37,10 @@ namespace gaseous_server.Classes.Metadata
public static Game? GetGame(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string? Slug) public static Game? GetGame(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string? Slug)
{ {
throw new NotImplementedException(); Game? RetVal = Metadata.GetMetadata<Game>(SourceType, Slug, false);
RetVal.MetadataSource = SourceType;
RetVal = MassageResult(RetVal);
return RetVal;
} }
public static Game GetGame(DataRow dataRow) public static Game GetGame(DataRow dataRow)

View File

@@ -17,7 +17,7 @@ namespace gaseous_server.Classes.Metadata
{ {
} }
public InvalidMetadataId(string SourceType, string Id) : base("Invalid Metadata id: " + Id + " from source: " + SourceType) public InvalidMetadataId(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string Id) : base("Invalid Metadata id: " + Id + " from source: " + SourceType)
{ {
} }
} }
@@ -77,14 +77,30 @@ namespace gaseous_server.Classes.Metadata
return _GetMetadata<T>(SourceType, Id, ForceRefresh); return _GetMetadata<T>(SourceType, Id, ForceRefresh);
} }
private static T? _GetMetadata<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, long Id, Boolean ForceRefresh) where T : class public static T? GetMetadata<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string Slug, Boolean ForceRefresh = false) where T : class
{
return _GetMetadata<T>(SourceType, Slug, ForceRefresh);
}
private static T? _GetMetadata<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, object Id, Boolean ForceRefresh) where T : class
{ {
// get T type as string // get T type as string
string type = typeof(T).Name; string type = typeof(T).Name;
// get type of Id as string
IdType idType = Id.GetType() == typeof(long) ? IdType.Long : IdType.String;
// check cached metadata status // check cached metadata status
// if metadata is not cached or expired, get it from the source. Otherwise, return the cached metadata // if metadata is not cached or expired, get it from the source. Otherwise, return the cached metadata
Storage.CacheStatus? cacheStatus = Storage.GetCacheStatus(SourceType, type, Id); Storage.CacheStatus? cacheStatus;
if (idType == IdType.Long)
{
cacheStatus = Storage.GetCacheStatus(SourceType, type, (long)Id);
}
else
{
cacheStatus = Storage.GetCacheStatus(SourceType, type, (string)Id);
}
// if ForceRefresh is true, set cache status to expired if it is current // if ForceRefresh is true, set cache status to expired if it is current
if (ForceRefresh == true) if (ForceRefresh == true)
@@ -100,16 +116,37 @@ namespace gaseous_server.Classes.Metadata
switch (cacheStatus) switch (cacheStatus)
{ {
case Storage.CacheStatus.Current: case Storage.CacheStatus.Current:
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Id", Id); if (idType == IdType.Long)
{
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Id", (long)Id);
}
else
{
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Slug", (string)Id);
}
break; break;
case Storage.CacheStatus.Expired: case Storage.CacheStatus.Expired:
metadata = GetMetadataFromServer<T>(SourceType, Id).Result; if (idType == IdType.Long)
{
metadata = GetMetadataFromServer<T>(SourceType, (long)Id).Result;
}
else
{
metadata = GetMetadataFromServer<T>(SourceType, (string)Id).Result;
}
Storage.NewCacheValue<T>(SourceType, metadata, true); Storage.NewCacheValue<T>(SourceType, metadata, true);
break; break;
case Storage.CacheStatus.NotPresent: case Storage.CacheStatus.NotPresent:
metadata = GetMetadataFromServer<T>(SourceType, Id).Result; if (idType == IdType.Long)
{
metadata = GetMetadataFromServer<T>(SourceType, (long)Id).Result;
}
else
{
metadata = GetMetadataFromServer<T>(SourceType, (string)Id).Result;
}
Storage.NewCacheValue<T>(SourceType, metadata, false); Storage.NewCacheValue<T>(SourceType, metadata, false);
break; break;
} }
@@ -117,6 +154,12 @@ namespace gaseous_server.Classes.Metadata
return metadata; return metadata;
} }
private enum IdType
{
Long,
String
}
private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, long Id) where T : class private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, long Id) where T : class
{ {
// get T type as string // get T type as string
@@ -135,6 +178,24 @@ namespace gaseous_server.Classes.Metadata
return results.FirstOrDefault<T>(); return results.FirstOrDefault<T>();
} }
private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string Id) where T : class
{
// get T type as string
string type = typeof(T).Name;
// get metadata from the server
Communications comms = new Communications();
var results = await comms.APIComm<T>(SourceType, (Communications.MetadataEndpoint)Enum.Parse(typeof(Communications.MetadataEndpoint), type, true), Id);
// check for errors
if (results == null)
{
throw new InvalidMetadataId(SourceType, Id);
}
return results.FirstOrDefault<T>();
}
#endregion #endregion
} }
} }

View File

@@ -27,9 +27,19 @@ namespace gaseous_server.Classes.Metadata
} }
} }
public static Platform GetPlatform(string Slug, bool forceRefresh = false, bool GetImages = false) public static Platform GetPlatform(string Slug)
{ {
throw new NotImplementedException(); // get platform id from slug - query Platform table
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string query = "SELECT Id FROM Platform WHERE slug = @slug AND SourceId = @sourceid;";
DataTable result = db.ExecuteCMD(query, new Dictionary<string, object> { { "@slug", Slug }, { "@sourceid", Communications.MetadataSource } });
if (result.Rows.Count == 0)
{
throw new Metadata.InvalidMetadataId(Slug);
}
long Id = (long)result.Rows[0]["Id"];
return GetPlatform(Id);
} }
private static void AddPlatformMapping(Platform platform) private static void AddPlatformMapping(Platform platform)

View File

@@ -120,15 +120,26 @@ CREATE TABLE `MetadataMap` (
CREATE TABLE `MetadataMapBridge` ( CREATE TABLE `MetadataMapBridge` (
`ParentMapId` bigint(20) NOT NULL, `ParentMapId` bigint(20) NOT NULL,
`SignatureGameName` varchar(255) NOT NULL,
`SignaturePlatformId` bigint(20) NOT NULL,
`MetadataSourceType` int(11) NOT NULL DEFAULT 0, `MetadataSourceType` int(11) NOT NULL DEFAULT 0,
`MetadataSourceId` bigint(20) NOT NULL `Preferred` BOOLEAN NOT NULL DEFAULT 0, `MetadataSourceId` bigint(20) NOT NULL,
`Preferred` BOOLEAN NOT NULL DEFAULT 0,
`ProcessedAtImport` BOOLEAN NOT NULL DEFAULT 0,
PRIMARY KEY ( PRIMARY KEY (
`ParentMapId`, `ParentMapId`,
`MetadataSourceType`, `MetadataSourceType`,
`MetadataSourceId` `MetadataSourceId`
),
INDEX `idx_gamename` (
`SignatureGameName`,
`SignaturePlatformId`
) )
); );
ALTER TABLE `Games_Roms`
ADD CONSTRAINT metadataMapId FOREIGN KEY (`MetadataMapId`) REFERENCES `MetadataMapBridge` (`ParentMapId`) ON DELETE CASCADE;
ALTER TABLE `Games_Roms` ALTER TABLE `Games_Roms`
ADD COLUMN `MetadataMapId` BIGINT NOT NULL DEFAULT 0; ADD COLUMN `MetadataMapId` BIGINT NOT NULL DEFAULT 0;