diff --git a/gaseous-server/Classes/ImportGames.cs b/gaseous-server/Classes/ImportGames.cs index be35aa9..5e69368 100644 --- a/gaseous-server/Classes/ImportGames.cs +++ b/gaseous-server/Classes/ImportGames.cs @@ -3,6 +3,7 @@ using System.Data; using System.Threading.Tasks; using gaseous_tools; using Org.BouncyCastle.Utilities.IO.Pem; +using static gaseous_server.Classes.Metadata.Games; namespace gaseous_server.Classes { @@ -99,24 +100,48 @@ namespace gaseous_server.Classes } else { - // no signature match found - try alternate methods - Models.Signatures_Games.GameItem gi = new Models.Signatures_Games.GameItem(); - Models.Signatures_Games.RomItem ri = new Models.Signatures_Games.RomItem(); + // no signature match found - try name search + signatures = sc.GetByTosecName(fi.Name); - discoveredSignature.Game = gi; - discoveredSignature.Rom = ri; + if (signatures.Count == 1) + { + // only 1 signature found! + discoveredSignature = signatures.ElementAt(0); + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false); + } + else if (signatures.Count > 1) + { + // more than one signature found - find one with highest score + foreach (Models.Signatures_Games Sig in signatures) + { + if (Sig.Score > discoveredSignature.Score) + { + discoveredSignature = Sig; + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false); + } + } + } + else + { + // still no search - try alternate method + Models.Signatures_Games.GameItem gi = new Models.Signatures_Games.GameItem(); + Models.Signatures_Games.RomItem ri = new Models.Signatures_Games.RomItem(); - // game title is the file name without the extension or path - gi.Name = Path.GetFileNameWithoutExtension(GameFileImportPath); + discoveredSignature.Game = gi; + discoveredSignature.Rom = ri; - // guess platform - gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, true); + // game title is the file name without the extension or path + gi.Name = Path.GetFileNameWithoutExtension(GameFileImportPath); - // get rom data - ri.Name = Path.GetFileName(GameFileImportPath); - ri.Md5 = hash.md5hash; - ri.Sha1 = hash.sha1hash; - ri.Size = fi.Length; + // guess platform + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, true); + + // get rom data + ri.Name = Path.GetFileName(GameFileImportPath); + ri.Md5 = hash.md5hash; + ri.Sha1 = hash.sha1hash; + ri.Size = fi.Length; + } } Logging.Log(Logging.LogType.Information, "Import Game", " Determined import file as: " + discoveredSignature.Game.Name + " (" + discoveredSignature.Game.Year + ") " + discoveredSignature.Game.System); @@ -127,6 +152,13 @@ namespace gaseous_server.Classes determinedPlatform = new IGDB.Models.Platform(); } + // remove string ending ", The" if present + if (discoveredSignature.Game.Name.Contains(", The")) + { + Logging.Log(Logging.LogType.Information, "Import Game", " Removing ', The' from end of game title for search"); + discoveredSignature.Game.Name.Replace(", The", ""); + } + // search discovered game - case insensitive exact match first IGDB.Models.Game determinedGame = new IGDB.Models.Game(); @@ -137,7 +169,7 @@ namespace gaseous_server.Classes if (games.Length == 1) { // exact match! - determinedGame = Metadata.Games.GetGame((long)games[0].Id, false); + determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false); Logging.Log(Logging.LogType.Information, "Import Game", " IGDB game: " + determinedGame.Name); break; } @@ -198,7 +230,7 @@ namespace gaseous_server.Classes // get metadata IGDB.Models.Platform platform = gaseous_server.Classes.Metadata.Platforms.GetPlatform(rom.PlatformId); - IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false); + IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false, false); // build path string platformSlug = "Unknown Platform"; diff --git a/gaseous-server/Classes/Metadata/AgeRating.cs b/gaseous-server/Classes/Metadata/AgeRating.cs new file mode 100644 index 0000000..7057fa6 --- /dev/null +++ b/gaseous-server/Classes/Metadata/AgeRating.cs @@ -0,0 +1,120 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class AgeRatings + { + const string fieldList = "fields category,checksum,content_descriptions,rating,rating_cover_url,synopsis;"; + + public AgeRatings() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static AgeRating? GetAgeRatings(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetAgeRatings(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static AgeRating GetAgeRatings(string Slug) + { + Task RetVal = _GetAgeRatings(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetAgeRatings(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("AgeRating", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("AgeRating", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + AgeRating returnValue = new AgeRating(); + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue); + UpdateSubClasses(returnValue); + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue, true); + UpdateSubClasses(returnValue); + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private static void UpdateSubClasses(AgeRating ageRating) + { + if (ageRating.ContentDescriptions != null) + { + foreach (long AgeRatingContentDescriptionId in ageRating.ContentDescriptions.Ids) + { + AgeRatingContentDescription ageRatingContentDescription = AgeRatingContentDescriptions.GetAgeRatingContentDescriptions(AgeRatingContentDescriptionId); + } + } + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get AgeRatings metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.AgeRating, query: fieldList + " " + WhereClause + ";"); + var result = results.First(); + + return result; + } + } +} + diff --git a/gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs b/gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs new file mode 100644 index 0000000..eeec99c --- /dev/null +++ b/gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs @@ -0,0 +1,107 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class AgeRatingContentDescriptions + { + const string fieldList = "fields category,checksum,description;"; + + public AgeRatingContentDescriptions() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static AgeRatingContentDescription? GetAgeRatingContentDescriptions(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetAgeRatingContentDescriptions(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static AgeRatingContentDescription GetAgeRatingContentDescriptions(string Slug) + { + Task RetVal = _GetAgeRatingContentDescriptions(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetAgeRatingContentDescriptions(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("AgeRatingContentDescription", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("AgeRatingContentDescription", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + AgeRatingContentDescription returnValue = new AgeRatingContentDescription(); + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue); + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue, true); + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get AgeRatingContentDescriptionContentDescriptions metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.AgeRatingContentDescriptions, query: fieldList + " " + WhereClause + ";"); + var result = results.First(); + + return result; + } + } +} + diff --git a/gaseous-server/Classes/Metadata/AlternativeNames.cs b/gaseous-server/Classes/Metadata/AlternativeNames.cs new file mode 100644 index 0000000..3a5fe91 --- /dev/null +++ b/gaseous-server/Classes/Metadata/AlternativeNames.cs @@ -0,0 +1,107 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class AlternativeNames + { + const string fieldList = "fields checksum,comment,game,name;"; + + public AlternativeNames() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static AlternativeName? GetAlternativeNames(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetAlternativeNames(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static AlternativeName GetAlternativeNames(string Slug) + { + Task RetVal = _GetAlternativeNames(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetAlternativeNames(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("AlternativeName", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("AlternativeName", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + AlternativeName returnValue = new AlternativeName(); + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue); + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue, true); + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get AlternativeNames metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.AlternativeNames, query: fieldList + " " + WhereClause + ";"); + var result = results.First(); + + return result; + } + } +} + diff --git a/gaseous-server/Classes/Metadata/Collections.cs b/gaseous-server/Classes/Metadata/Collections.cs new file mode 100644 index 0000000..956ddf6 --- /dev/null +++ b/gaseous-server/Classes/Metadata/Collections.cs @@ -0,0 +1,107 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class Collections + { + const string fieldList = "fields checksum,created_at,games,name,slug,updated_at,url;"; + + public Collections() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static Collection? GetCollections(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetCollections(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static Collection GetCollections(string Slug) + { + Task RetVal = _GetCollections(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetCollections(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("Collection", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("Collection", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + Collection returnValue = new Collection(); + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue); + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue, true); + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get Collections metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.Collections, query: fieldList + " " + WhereClause + ";"); + var result = results.First(); + + return result; + } + } +} + diff --git a/gaseous-server/Classes/Metadata/ExternalGames.cs b/gaseous-server/Classes/Metadata/ExternalGames.cs new file mode 100644 index 0000000..348365d --- /dev/null +++ b/gaseous-server/Classes/Metadata/ExternalGames.cs @@ -0,0 +1,120 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class ExternalGames + { + const string fieldList = "fields category,checksum,countries,created_at,game,media,name,platform,uid,updated_at,url,year;"; + + public ExternalGames() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static ExternalGame? GetExternalGames(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetExternalGames(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static ExternalGame GetExternalGames(string Slug) + { + Task RetVal = _GetExternalGames(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetExternalGames(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("ExternalGame", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("ExternalGame", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + ExternalGame returnValue = new ExternalGame(); + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + if (returnValue != null) + { + Storage.NewCacheValue(returnValue); + } + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + if (returnValue != null) + { + Storage.NewCacheValue(returnValue, true); + } + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get ExternalGames metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.ExternalGames, query: fieldList + " " + WhereClause + ";"); + if (results.Length > 0) + { + var result = results.First(); + + return result; + } + else + { + return null; + } + } + } +} + diff --git a/gaseous-server/Classes/Metadata/Franchises.cs b/gaseous-server/Classes/Metadata/Franchises.cs new file mode 100644 index 0000000..f688ceb --- /dev/null +++ b/gaseous-server/Classes/Metadata/Franchises.cs @@ -0,0 +1,107 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class Franchises + { + const string fieldList = "fields checksum,created_at,games,name,slug,updated_at,url;"; + + public Franchises() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static Franchise? GetFranchises(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetFranchises(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static Franchise GetFranchises(string Slug) + { + Task RetVal = _GetFranchises(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetFranchises(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("Franchise", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("Franchise", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + Franchise returnValue = new Franchise(); + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue); + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue, true); + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get FranchiseContentDescriptions metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.Franchies, query: fieldList + " " + WhereClause + ";"); + var result = results.First(); + + return result; + } + } +} + diff --git a/gaseous-server/Classes/Metadata/GameVideos.cs b/gaseous-server/Classes/Metadata/GameVideos.cs new file mode 100644 index 0000000..63c8f21 --- /dev/null +++ b/gaseous-server/Classes/Metadata/GameVideos.cs @@ -0,0 +1,110 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class GamesVideos + { + const string fieldList = "fields checksum,game,name,video_id;"; + + public GamesVideos() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static GameVideo? GetGame_Videos(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetGame_Videos(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static GameVideo GetGame_Videos(string Slug) + { + Task RetVal = _GetGame_Videos(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetGame_Videos(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("GameVideo", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("GameVideo", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + GameVideo returnValue = new GameVideo(); + bool forceImageDownload = false; + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue); + forceImageDownload = true; + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue, true); + forceImageDownload = true; + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get Game_Videos metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.GameVideos, query: fieldList + " " + WhereClause + ";"); + var result = results.First(); + + return result; + } + } +} + diff --git a/gaseous-server/Classes/Metadata/Games.cs b/gaseous-server/Classes/Metadata/Games.cs index 9b60e23..ba235de 100644 --- a/gaseous-server/Classes/Metadata/Games.cs +++ b/gaseous-server/Classes/Metadata/Games.cs @@ -20,7 +20,7 @@ namespace gaseous_server.Classes.Metadata Config.IGDB.Secret ); - public static Game? GetGame(long Id, bool followSubGames) + public static Game? GetGame(long Id, bool followSubGames, bool forceRefresh) { if (Id == 0) { @@ -28,18 +28,18 @@ namespace gaseous_server.Classes.Metadata } else { - Task RetVal = _GetGame(SearchUsing.id, Id, followSubGames); + Task RetVal = _GetGame(SearchUsing.id, Id, followSubGames, forceRefresh); return RetVal.Result; } } - public static Game GetGame(string Slug, bool followSubGames) + public static Game GetGame(string Slug, bool followSubGames, bool forceRefresh) { - Task RetVal = _GetGame(SearchUsing.slug, Slug, followSubGames); + Task RetVal = _GetGame(SearchUsing.slug, Slug, followSubGames, forceRefresh); return RetVal.Result; } - private static async Task _GetGame(SearchUsing searchUsing, object searchValue, bool followSubGames = false) + private static async Task _GetGame(SearchUsing searchUsing, object searchValue, bool followSubGames = false, bool forceRefresh = false) { // check database first Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); @@ -52,6 +52,11 @@ namespace gaseous_server.Classes.Metadata cacheStatus = Storage.GetCacheStatus("Game", (string)searchValue); } + if (forceRefresh == true) + { + if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; } + } + // set up where clause string WhereClause = ""; switch (searchUsing) @@ -88,6 +93,20 @@ namespace gaseous_server.Classes.Metadata private static void UpdateSubClasses(Game Game, bool followSubGames) { + if (Game.AgeRatings != null) + { + foreach (long AgeRatingId in Game.AgeRatings.Ids) + { + AgeRating GameAgeRating = AgeRatings.GetAgeRatings(AgeRatingId); + } + } + if (Game.AlternativeNames != null) + { + foreach (long AlternativeNameId in Game.AlternativeNames.Ids) + { + AlternativeName GameAlternativeName = AlternativeNames.GetAlternativeNames(AlternativeNameId); + } + } if (Game.Artworks != null) { foreach (long ArtworkId in Game.Artworks.Ids) @@ -102,19 +121,48 @@ namespace gaseous_server.Classes.Metadata if (Game.Dlcs != null) { gamesToFetch.AddRange(Game.Dlcs.Ids); } if (Game.Expansions != null) { gamesToFetch.AddRange(Game.Expansions.Ids); } if (Game.ParentGame != null) { gamesToFetch.Add((long)Game.ParentGame.Id); } - if (Game.SimilarGames != null) { gamesToFetch.AddRange(Game.SimilarGames.Ids); } + //if (Game.SimilarGames != null) { gamesToFetch.AddRange(Game.SimilarGames.Ids); } if (Game.StandaloneExpansions != null) { gamesToFetch.AddRange(Game.StandaloneExpansions.Ids); } if (Game.VersionParent != null) { gamesToFetch.Add((long)Game.VersionParent.Id); } foreach (long gameId in gamesToFetch) { - Game relatedGame = GetGame(gameId, false); + Game relatedGame = GetGame(gameId, false, false); } } + if (Game.Collection != null) + { + Collection GameCollection = Collections.GetCollections(Game.Collection.Id); + } if (Game.Cover != null) { Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game)); } + if (Game.ExternalGames != null) + { + foreach (long ExternalGameId in Game.ExternalGames.Ids) + { + ExternalGame GameExternalGame = ExternalGames.GetExternalGames(ExternalGameId); + } + } + if (Game.Franchise != null) + { + Franchise GameFranchise = Franchises.GetFranchises(Game.Franchise.Id); + } + if (Game.Franchises != null) + { + foreach (long FranchiseId in Game.Franchises.Ids) + { + Franchise GameFranchise = Franchises.GetFranchises(FranchiseId); + } + } + if (Game.Genres != null) + { + foreach (long GenreId in Game.Genres.Ids) + { + Genre GameGenre = Genres.GetGenres(GenreId); + } + } if (Game.Platforms != null) { foreach (long PlatformId in Game.Platforms.Ids) @@ -129,6 +177,13 @@ namespace gaseous_server.Classes.Metadata Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game)); } } + if (Game.Videos != null) + { + foreach (long GameVideoId in Game.Videos.Ids) + { + GameVideo gameVideo = GamesVideos.GetGame_Videos(GameVideoId); + } + } } private enum SearchUsing diff --git a/gaseous-server/Classes/Metadata/Genres.cs b/gaseous-server/Classes/Metadata/Genres.cs new file mode 100644 index 0000000..5995e48 --- /dev/null +++ b/gaseous-server/Classes/Metadata/Genres.cs @@ -0,0 +1,110 @@ +using System; +using gaseous_tools; +using IGDB; +using IGDB.Models; +using MySqlX.XDevAPI.Common; +using static gaseous_tools.Config.ConfigFile; + +namespace gaseous_server.Classes.Metadata +{ + public class Genres + { + const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;"; + + public Genres() + { + } + + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + public static Genre? GetGenres(long? Id) + { + if ((Id == 0) || (Id == null)) + { + return null; + } + else + { + Task RetVal = _GetGenres(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static Genre GetGenres(string Slug) + { + Task RetVal = _GetGenres(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _GetGenres(SearchUsing searchUsing, object searchValue) + { + // check database first + Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); + if (searchUsing == SearchUsing.id) + { + cacheStatus = Storage.GetCacheStatus("Genre", (long)searchValue); + } + else + { + cacheStatus = Storage.GetCacheStatus("Genre", (string)searchValue); + } + + // set up where clause + string WhereClause = ""; + switch (searchUsing) + { + case SearchUsing.id: + WhereClause = "where id = " + searchValue; + break; + case SearchUsing.slug: + WhereClause = "where slug = " + searchValue; + break; + default: + throw new Exception("Invalid search type"); + } + + Genre returnValue = new Genre(); + bool forceImageDownload = false; + switch (cacheStatus) + { + case Storage.CacheStatus.NotPresent: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue); + forceImageDownload = true; + break; + case Storage.CacheStatus.Expired: + returnValue = await GetObjectFromServer(WhereClause); + Storage.NewCacheValue(returnValue, true); + forceImageDownload = true; + break; + case Storage.CacheStatus.Current: + returnValue = Storage.GetCacheValue(returnValue, "id", (long)searchValue); + break; + default: + throw new Exception("How did you get here?"); + } + + return returnValue; + } + + private enum SearchUsing + { + id, + slug + } + + private static async Task GetObjectFromServer(string WhereClause) + { + // get Genres metadata + var results = await igdb.QueryAsync(IGDBClient.Endpoints.Genres, query: fieldList + " " + WhereClause + ";"); + var result = results.First(); + + return result; + } + } +} + diff --git a/gaseous-server/Classes/Metadata/Storage.cs b/gaseous-server/Classes/Metadata/Storage.cs index f712385..decba18 100644 --- a/gaseous-server/Classes/Metadata/Storage.cs +++ b/gaseous-server/Classes/Metadata/Storage.cs @@ -243,6 +243,15 @@ namespace gaseous_server.Classes.Metadata break; case "[igdb.models.gamestatus": property.SetValue(EndpointType, (GameStatus)dataRow[property.Name]); + break; + case "[igdb.models.ageratingcategory": + property.SetValue(EndpointType, (AgeRatingCategory)dataRow[property.Name]); + break; + case "[igdb.models.ageratingtitle": + property.SetValue(EndpointType, (AgeRatingTitle)dataRow[property.Name]); + break; + case "[igdb.models.externalcategory": + property.SetValue(EndpointType, (ExternalCategory)dataRow[property.Name]); break; default: property.SetValue(EndpointType, dataRow[property.Name]); diff --git a/gaseous-server/Classes/MetadataManagement.cs b/gaseous-server/Classes/MetadataManagement.cs index 90e9f96..4c51df2 100644 --- a/gaseous-server/Classes/MetadataManagement.cs +++ b/gaseous-server/Classes/MetadataManagement.cs @@ -6,7 +6,7 @@ namespace gaseous_server.Classes { public class MetadataManagement { - public static void RefreshMetadata() + public static void RefreshMetadata(bool forceRefresh = false) { Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); string sql = "SELECT id, `name` FROM game;"; @@ -15,7 +15,7 @@ namespace gaseous_server.Classes foreach (DataRow dr in dt.Rows) { Logging.Log(Logging.LogType.Information, "Metadata Refresh", "Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ")"); - Metadata.Games.GetGame((long)dr["id"], true); + Metadata.Games.GetGame((long)dr["id"], true, forceRefresh); } } } diff --git a/gaseous-server/Controllers/SignaturesController.cs b/gaseous-server/Controllers/SignaturesController.cs index fd14de2..1e272d2 100644 --- a/gaseous-server/Controllers/SignaturesController.cs +++ b/gaseous-server/Controllers/SignaturesController.cs @@ -39,6 +39,19 @@ namespace gaseous_server.Controllers } } + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + public List GetByTosecName(string TosecName = "") + { + if (TosecName.Length > 0) + { + return _GetSignature("signatures_roms.name = @searchstring", TosecName); + } else + { + return null; + } + } + private List _GetSignature(string sqlWhere, string searchString) { Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); diff --git a/gaseous-server/ProcessQueue.cs b/gaseous-server/ProcessQueue.cs index 4a9a781..4057ced 100644 --- a/gaseous-server/ProcessQueue.cs +++ b/gaseous-server/ProcessQueue.cs @@ -72,7 +72,7 @@ namespace gaseous_server case QueueItemType.MetadataRefresh: Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Metadata Refresher"); - Classes.MetadataManagement.RefreshMetadata(); + Classes.MetadataManagement.RefreshMetadata(true); break; } } diff --git a/gaseous-tools/Database/MySQL/gaseous-1000.sql b/gaseous-tools/Database/MySQL/gaseous-1000.sql index 13b74ae..5e2b19f 100644 --- a/gaseous-tools/Database/MySQL/gaseous-1000.sql +++ b/gaseous-tools/Database/MySQL/gaseous-1000.sql @@ -1,13 +1,13 @@ --- MySQL dump 10.13 Distrib 8.0.32, for macos13.0 (arm64) +-- MySQL dump 10.13 Distrib 8.0.29, for macos12 (x86_64) -- -- Host: localhost Database: gaseous -- ------------------------------------------------------ --- Server version 8.0.32 +-- Server version 8.0.33 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!50503 SET NAMES utf8mb4 */; +/*!50503 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -15,11 +15,70 @@ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +-- +-- Table structure for table `agerating` +-- + +DROP TABLE IF EXISTS `agerating`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `agerating` ( + `id` bigint NOT NULL, + `category` int DEFAULT NULL, + `checksum` varchar(45) DEFAULT NULL, + `contentdescriptions` json DEFAULT NULL, + `rating` int DEFAULT NULL, + `ratingcoverurl` varchar(255) DEFAULT NULL, + `synopsis` longtext, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ageratingcontentdescription` +-- + +DROP TABLE IF EXISTS `ageratingcontentdescription`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ageratingcontentdescription` ( + `id` bigint NOT NULL, + `category` int DEFAULT NULL, + `checksum` varchar(45) DEFAULT NULL, + `description` varchar(255) DEFAULT NULL, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `alternativename` +-- + +DROP TABLE IF EXISTS `alternativename`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `alternativename` ( + `id` bigint NOT NULL, + `checksum` varchar(45) DEFAULT NULL, + `comment` longtext, + `game` int DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `artwork` -- DROP TABLE IF EXISTS `artwork`; +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `artwork` ( `id` bigint NOT NULL, @@ -35,14 +94,36 @@ CREATE TABLE `artwork` ( `lastUpdated` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `collection` +-- + +DROP TABLE IF EXISTS `collection`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `collection` ( + `id` bigint NOT NULL, + `checksum` varchar(45) DEFAULT NULL, + `games` json DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `slug` varchar(100) DEFAULT NULL, + `createdAt` datetime DEFAULT NULL, + `updatedAt` datetime DEFAULT NULL, + `url` varchar(255) DEFAULT NULL, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `cover` -- DROP TABLE IF EXISTS `cover`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `cover` ( `id` bigint NOT NULL, @@ -58,14 +139,63 @@ CREATE TABLE `cover` ( `lastUpdated` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `externalgame` +-- + +DROP TABLE IF EXISTS `externalgame`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `externalgame` ( + `id` bigint NOT NULL, + `category` int DEFAULT NULL, + `checksum` varchar(45) DEFAULT NULL, + `createdat` datetime DEFAULT NULL, + `countries` json DEFAULT NULL, + `game` bigint DEFAULT NULL, + `media` int DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `platform` bigint DEFAULT NULL, + `uid` varchar(255) DEFAULT NULL, + `updatedat` datetime DEFAULT NULL, + `url` varchar(255) DEFAULT NULL, + `year` int DEFAULT NULL, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `franchise` +-- + +DROP TABLE IF EXISTS `franchise`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `franchise` ( + `id` bigint NOT NULL, + `checksum` varchar(45) DEFAULT NULL, + `createdat` datetime DEFAULT NULL, + `updatedat` datetime DEFAULT NULL, + `games` json DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `slug` varchar(255) DEFAULT NULL, + `url` varchar(255) DEFAULT NULL, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `game` -- DROP TABLE IF EXISTS `game`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `game` ( `id` bigint NOT NULL, @@ -113,7 +243,7 @@ CREATE TABLE `game` ( `totalrating` double DEFAULT NULL, `totalratingcount` int DEFAULT NULL, `updatedat` datetime DEFAULT NULL, - `url` varchar(100) DEFAULT NULL, + `url` varchar(255) DEFAULT NULL, `versionparent` bigint DEFAULT NULL, `versiontitle` varchar(100) DEFAULT NULL, `videos` json DEFAULT NULL, @@ -121,16 +251,39 @@ CREATE TABLE `game` ( `dateAdded` datetime DEFAULT NULL, `lastUpdated` datetime DEFAULT NULL, PRIMARY KEY (`id`), - UNIQUE KEY `id_UNIQUE` (`id`) + UNIQUE KEY `id_UNIQUE` (`id`), + KEY `idx_genres` ((cast(`genres` as unsigned array))), + KEY `idx_alternativenames` ((cast(`alternativenames` as unsigned array))), + KEY `idx_artworks` ((cast(`artworks` as unsigned array))), + KEY `idx_bundles` ((cast(`bundles` as unsigned array))), + KEY `idx_dlcs` ((cast(`dlcs` as unsigned array))), + KEY `idx_expansions` ((cast(`expansions` as unsigned array))), + KEY `idx_externalgames` ((cast(`externalgames` as unsigned array))), + KEY `idx_franchises` ((cast(`franchises` as unsigned array))), + KEY `idx_gameengines` ((cast(`gameengines` as unsigned array))), + KEY `idx_gamemodes` ((cast(`gamemodes` as unsigned array))), + KEY `idx_involvedcompanies` ((cast(`involvedcompanies` as unsigned array))), + KEY `idx_keywords` ((cast(`keywords` as unsigned array))), + KEY `idx_multiplayermodes` ((cast(`multiplayermodes` as unsigned array))), + KEY `idx_platforms` ((cast(`platforms` as unsigned array))), + KEY `idx_playerperspectives` ((cast(`playerperspectives` as unsigned array))), + KEY `idx_releasedates` ((cast(`releasedates` as unsigned array))), + KEY `idx_screenshots` ((cast(`screenshots` as unsigned array))), + KEY `idx_similargames` ((cast(`similargames` as unsigned array))), + KEY `idx_standaloneexpansions` ((cast(`standaloneexpansions` as unsigned array))), + KEY `idx_tags` ((cast(`tags` as unsigned array))), + KEY `idx_themes` ((cast(`themes` as unsigned array))), + KEY `idx_videos` ((cast(`videos` as unsigned array))), + KEY `idx_websites` ((cast(`websites` as unsigned array))) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `games_roms` -- DROP TABLE IF EXISTS `games_roms`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `games_roms` ( `id` bigint NOT NULL AUTO_INCREMENT, @@ -149,20 +302,60 @@ CREATE TABLE `games_roms` ( `path` longtext, PRIMARY KEY (`id`), UNIQUE KEY `id_UNIQUE` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=398 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `gamevideo` +-- + +DROP TABLE IF EXISTS `gamevideo`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `gamevideo` ( + `id` bigint NOT NULL, + `checksum` varchar(45) DEFAULT NULL, + `game` bigint DEFAULT NULL, + `name` varchar(100) DEFAULT NULL, + `videoid` varchar(45) DEFAULT NULL, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `genre` +-- + +DROP TABLE IF EXISTS `genre`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `genre` ( + `id` bigint NOT NULL, + `checksum` varchar(45) DEFAULT NULL, + `createdat` datetime DEFAULT NULL, + `updatedat` datetime DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `slug` varchar(100) DEFAULT NULL, + `url` varchar(255) DEFAULT NULL, + `dateAdded` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `platform` -- DROP TABLE IF EXISTS `platform`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `platform` ( `id` bigint NOT NULL, `abbreviation` varchar(45) DEFAULT NULL, - `alternativename` varchar(45) DEFAULT NULL, + `alternativename` varchar(255) DEFAULT NULL, `category` int DEFAULT NULL, `checksum` varchar(45) DEFAULT NULL, `createdat` datetime DEFAULT NULL, @@ -181,14 +374,14 @@ CREATE TABLE `platform` ( PRIMARY KEY (`id`), UNIQUE KEY `id_UNIQUE` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `platformlogo` -- DROP TABLE IF EXISTS `platformlogo`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `platformlogo` ( `id` bigint NOT NULL, @@ -203,14 +396,14 @@ CREATE TABLE `platformlogo` ( `lastUpdated` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `platformversion` -- DROP TABLE IF EXISTS `platformversion`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `platformversion` ( `id` bigint NOT NULL, @@ -237,14 +430,14 @@ CREATE TABLE `platformversion` ( `lastUpdated` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `screenshot` -- DROP TABLE IF EXISTS `screenshot`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `screenshot` ( `id` bigint NOT NULL, @@ -260,14 +453,14 @@ CREATE TABLE `screenshot` ( `lastUpdated` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `settings` -- DROP TABLE IF EXISTS `settings`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `settings` ( `setting` varchar(45) NOT NULL, @@ -275,14 +468,14 @@ CREATE TABLE `settings` ( PRIMARY KEY (`setting`), UNIQUE KEY `setting_UNIQUE` (`setting`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `signatures_games` -- DROP TABLE IF EXISTS `signatures_games`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `signatures_games` ( `id` int NOT NULL AUTO_INCREMENT, @@ -304,15 +497,15 @@ CREATE TABLE `signatures_games` ( KEY `ingest_idx` (`name`,`year`,`publisherid`,`systemid`,`country`,`language`) USING BTREE, CONSTRAINT `publisher` FOREIGN KEY (`publisherid`) REFERENCES `signatures_publishers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `system` FOREIGN KEY (`systemid`) REFERENCES `signatures_platforms` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +) ENGINE=InnoDB AUTO_INCREMENT=785672 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `signatures_platforms` -- DROP TABLE IF EXISTS `signatures_platforms`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `signatures_platforms` ( `id` int NOT NULL AUTO_INCREMENT, @@ -320,15 +513,15 @@ CREATE TABLE `signatures_platforms` ( PRIMARY KEY (`id`), UNIQUE KEY `idsignatures_platforms_UNIQUE` (`id`), KEY `platforms_idx` (`platform`,`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +) ENGINE=InnoDB AUTO_INCREMENT=417 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `signatures_publishers` -- DROP TABLE IF EXISTS `signatures_publishers`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `signatures_publishers` ( `id` int NOT NULL AUTO_INCREMENT, @@ -336,15 +529,15 @@ CREATE TABLE `signatures_publishers` ( PRIMARY KEY (`id`), UNIQUE KEY `id_UNIQUE` (`id`), KEY `publisher_idx` (`publisher`,`id`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +) ENGINE=InnoDB AUTO_INCREMENT=52259 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `signatures_roms` -- DROP TABLE IF EXISTS `signatures_roms`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `signatures_roms` ( `id` int NOT NULL AUTO_INCREMENT, @@ -366,15 +559,15 @@ CREATE TABLE `signatures_roms` ( KEY `sha1_idx` (`sha1`) USING BTREE, KEY `flags_idx` ((cast(`flags` as char(255) array))), CONSTRAINT `gameid` FOREIGN KEY (`gameid`) REFERENCES `signatures_games` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +) ENGINE=InnoDB AUTO_INCREMENT=1734101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `signatures_sources` -- DROP TABLE IF EXISTS `signatures_sources`; - +/*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `signatures_sources` ( `id` int NOT NULL AUTO_INCREMENT, @@ -393,7 +586,16 @@ CREATE TABLE `signatures_sources` ( UNIQUE KEY `id_UNIQUE` (`id`), KEY `sourcemd5_idx` (`sourcemd5`,`id`) USING BTREE, KEY `sourcesha1_idx` (`sourcesha1`,`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=3109 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping events for database 'gaseous' +-- + +-- +-- Dumping routines for database 'gaseous' +-- -- -- Final view structure for view `view_signatures_games`