diff --git a/build/embeddeddb/entrypoint.sh b/build/embeddeddb/entrypoint.sh index 89cb777..508f93c 100644 --- a/build/embeddeddb/entrypoint.sh +++ b/build/embeddeddb/entrypoint.sh @@ -5,6 +5,9 @@ echo "Creating user gaseous with UID ${PUID} and GID ${PGID}" groupadd -g ${PGID} gaseous useradd -u ${PUID} -g ${PGID} -m gaseous -d /home/gaseous -G sudo usermod -p "*" gaseous +mkdir -p /home/gaseous/.aspnet +chown -R ${PUID} /App /home/gaseous/.aspnet +chgrp -R ${PGID} /App /home/gaseous/.aspnet mkdir -p /home/gaseous/.gaseous-server chown -R ${PUID} /App /home/gaseous/.gaseous-server chgrp -R ${PGID} /App /home/gaseous/.gaseous-server diff --git a/build/standard/entrypoint.sh b/build/standard/entrypoint.sh index 8256268..d4e9e49 100644 --- a/build/standard/entrypoint.sh +++ b/build/standard/entrypoint.sh @@ -5,6 +5,9 @@ echo "Creating user gaseous with UID ${PUID} and GID ${PGID}" groupadd -g ${PGID} gaseous useradd -u ${PUID} -g ${PGID} -m gaseous -d /home/gaseous -G sudo usermod -p "*" gaseous +mkdir -p /home/gaseous/.aspnet +chown -R ${PUID} /App /home/gaseous/.aspnet +chgrp -R ${PGID} /App /home/gaseous/.aspnet mkdir -p /home/gaseous/.gaseous-server chown -R ${PUID} /App /home/gaseous/.gaseous-server chgrp -R ${PGID} /App /home/gaseous/.gaseous-server diff --git a/gaseous-server/Classes/Config.cs b/gaseous-server/Classes/Config.cs index f7b88e9..c82dadb 100644 --- a/gaseous-server/Classes/Config.cs +++ b/gaseous-server/Classes/Config.cs @@ -531,11 +531,7 @@ namespace gaseous_server.Classes { get { - return ReadSetting("LibraryRootDirectory", Path.Combine(Config.ConfigurationPath, "Data")); - } - set - { - SetSetting("LibraryRootDirectory", value); + return Path.Combine(Config.ConfigurationPath, "Data"); } } diff --git a/gaseous-server/Classes/DatabaseMigration.cs b/gaseous-server/Classes/DatabaseMigration.cs index ba6a67d..0bb712c 100644 --- a/gaseous-server/Classes/DatabaseMigration.cs +++ b/gaseous-server/Classes/DatabaseMigration.cs @@ -149,9 +149,6 @@ namespace gaseous_server.Classes db.ExecuteNonQuery(sql, dbDict); } while (reader.EndOfStream == false); } - - // this is a safe background task - BackgroundUpgradeTargetSchemaVersions.Add(1023); break; case 1024: @@ -181,6 +178,73 @@ namespace gaseous_server.Classes }; db.ExecuteNonQuery(sql, dbDict); } + + // update all rom paths to use the new format + sql = "SELECT * FROM GameLibraries;"; + data = db.ExecuteCMD(sql); + foreach (DataRow row in data.Rows) + { + sql = "SELECT * FROM Games_Roms WHERE LibraryId = @libraryid;"; + dbDict = new Dictionary + { + { "libraryid", row["Id"] } + }; + DataTable romData = db.ExecuteCMD(sql, dbDict); + + string libraryRootPath = (string)row["Path"]; + if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false) + { + libraryRootPath += Path.DirectorySeparatorChar; + } + + bool GetLastThreeElements = (bool)row["DefaultLibrary"]; + + foreach (DataRow romRow in romData.Rows) + { + string existingPath = (string)romRow["RelativePath"]; + string newPath = ""; + + if (GetLastThreeElements == true) + { + // strip all but the last 3 elements from existingPath separated by directory separator + // this mode only works for the default library + string[] pathParts = existingPath.Split(Path.DirectorySeparatorChar); + if (pathParts.Length > 3) + { + newPath = Path.Combine(pathParts[pathParts.Length - 3], pathParts[pathParts.Length - 2], pathParts[pathParts.Length - 1]); + } + else + { + newPath = existingPath; + } + } + else + { + // strip the library root path from the existing path + if (existingPath.StartsWith(libraryRootPath)) + { + newPath = existingPath.Substring(libraryRootPath.Length); + } + else + { + newPath = existingPath; + } + } + + Logging.Log(Logging.LogType.Information, "Database Upgrade", "Updating ROM path from " + existingPath + " to " + newPath); + + sql = "UPDATE Games_Roms SET RelativePath = @newpath WHERE Id = @id;"; + dbDict = new Dictionary + { + { "newpath", newPath }, + { "id", romRow["Id"] } + }; + db.ExecuteNonQuery(sql, dbDict); + } + } + + // migrating metadata is a safe background task + BackgroundUpgradeTargetSchemaVersions.Add(1024); break; } break; @@ -197,8 +261,8 @@ namespace gaseous_server.Classes MySql_1002_MigrateMetadataVersion(); break; - case 1023: - MySql_1023_MigrateMetadataVersion(); + case 1024: + MySql_1024_MigrateMetadataVersion(); break; } } @@ -301,12 +365,12 @@ namespace gaseous_server.Classes } } - public static void MySql_1023_MigrateMetadataVersion() + public static void MySql_1024_MigrateMetadataVersion() { FileSignature fileSignature = new FileSignature(); Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "SELECT * FROM Games_Roms WHERE RomDataVersion = 1;"; + string sql = "SELECT * FROM view_Games_Roms WHERE RomDataVersion = 1;"; DataTable data = db.ExecuteCMD(sql); long count = 1; foreach (DataRow row in data.Rows) diff --git a/gaseous-server/Classes/Filters.cs b/gaseous-server/Classes/Filters.cs index f58291a..570a69b 100644 --- a/gaseous-server/Classes/Filters.cs +++ b/gaseous-server/Classes/Filters.cs @@ -24,7 +24,7 @@ namespace gaseous_server.Classes ageRestriction_Generic += " OR view_Games.AgeGroupId IS NULL"; } - string sql = "SELECT Platform.Id, Platform.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, Games_Roms.PlatformId, COUNT(Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN Games_Roms ON Game.Id = Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id , Games_Roms.PlatformId HAVING RomCount > 0) Game JOIN Platform ON Game.PlatformId = Platform.Id GROUP BY Platform.`Name`;"; + string sql = "SELECT Platform.Id, Platform.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, view_Games_Roms.PlatformId, COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id , view_Games_Roms.PlatformId HAVING RomCount > 0) Game JOIN Platform ON Game.PlatformId = Platform.Id GROUP BY Platform.`Name`;"; DataTable dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300)); @@ -82,7 +82,7 @@ namespace gaseous_server.Classes // age groups List agegroupings = new List(); - sql = "SELECT Game.AgeGroupId, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, AgeGroup.AgeGroupId, COUNT(Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN Games_Roms ON Game.Id = Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id HAVING RomCount > 0) Game GROUP BY Game.AgeGroupId ORDER BY Game.AgeGroupId DESC"; + sql = "SELECT Game.AgeGroupId, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, AgeGroup.AgeGroupId, COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id HAVING RomCount > 0) Game GROUP BY Game.AgeGroupId ORDER BY Game.AgeGroupId DESC"; dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300)); foreach (DataRow dr in dbResponse.Rows) @@ -112,7 +112,7 @@ namespace gaseous_server.Classes { //string sql = "SELECT DISTINCT .Id, .`Name`, COUNT(view_Games.Id) AS GameCount FROM LEFT JOIN Relation_Game_s ON Relation_Game_s.sId = .Id LEFT JOIN view_Games ON view_Games.Id = Relation_Game_s.GameId WHERE (" + AgeRestriction_Generic + ") GROUP BY .Id HAVING GameCount > 0 ORDER BY .`Name`;"; - string sql = "SELECT .Id, .`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, AgeGroup.AgeGroupId, COUNT(Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN Games_Roms ON Game.Id = Games_Roms.GameId WHERE (" + AgeRestriction + ") GROUP BY Game.Id HAVING RomCount > 0) Game JOIN Relation_Game_s ON Game.Id = Relation_Game_s.GameId JOIN ON Relation_Game_s.sId = .Id GROUP BY .`Name` ORDER BY .`Name`;"; + string sql = "SELECT .Id, .`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, AgeGroup.AgeGroupId, COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId WHERE (" + AgeRestriction + ") GROUP BY Game.Id HAVING RomCount > 0) Game JOIN Relation_Game_s ON Game.Id = Relation_Game_s.GameId JOIN ON Relation_Game_s.sId = .Id GROUP BY .`Name` ORDER BY .`Name`;"; sql = sql.Replace("", Name); DataTable dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300)); diff --git a/gaseous-server/Classes/GameLibrary.cs b/gaseous-server/Classes/GameLibrary.cs index b30ea46..bc8f890 100644 --- a/gaseous-server/Classes/GameLibrary.cs +++ b/gaseous-server/Classes/GameLibrary.cs @@ -60,6 +60,18 @@ namespace gaseous_server } } + // update default library path + public static void UpdateDefaultLibraryPath() + { + Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); + string sql = "UPDATE GameLibraries SET Path=@path WHERE DefaultLibrary=1;"; + Dictionary dbDict = new Dictionary + { + { "path", Path.Combine(Config.LibraryConfiguration.LibraryRootDirectory, "Library") } + }; + db.ExecuteCMD(sql, dbDict); + } + public static List GetLibraries { get diff --git a/gaseous-server/Classes/ImportGames.cs b/gaseous-server/Classes/ImportGames.cs index d0fa5a3..155c392 100644 --- a/gaseous-server/Classes/ImportGames.cs +++ b/gaseous-server/Classes/ImportGames.cs @@ -73,7 +73,7 @@ namespace gaseous_server.Classes RetVal.Add("type", "rom"); // check to make sure we don't already have this file imported - sql = "SELECT COUNT(Id) AS count FROM Games_Roms WHERE MD5=@md5 AND SHA1=@sha1"; + 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); @@ -129,7 +129,7 @@ namespace gaseous_server.Classes IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId, true); // add to database - long RomId = StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath); + long RomId = StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath, 0, true); // build return value RetVal.Add("romid", RomId); @@ -329,7 +329,7 @@ namespace gaseous_server.Classes return SearchCandidates; } - public static long StoreROM(GameLibrary.LibraryItem library, Common.hashObject hash, IGDB.Models.Game determinedGame, IGDB.Models.Platform determinedPlatform, gaseous_server.Models.Signatures_Games discoveredSignature, string GameFileImportPath, long UpdateId = 0) + public static long StoreROM(GameLibrary.LibraryItem library, Common.hashObject hash, IGDB.Models.Game determinedGame, IGDB.Models.Platform determinedPlatform, gaseous_server.Models.Signatures_Games discoveredSignature, string GameFileImportPath, long UpdateId = 0, bool SourceIsExternal = false) { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); @@ -339,7 +339,7 @@ namespace gaseous_server.Classes if (UpdateId == 0) { - sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, Path, MetadataSource, MetadataGameName, MetadataVersion, LibraryId, RomDataVersion) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid, @romdataversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; + sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, RelativePath, MetadataSource, MetadataGameName, MetadataVersion, LibraryId, RomDataVersion) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid, @romdataversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; } else { @@ -378,7 +378,13 @@ namespace gaseous_server.Classes dbDict.Add("romtype", (int)discoveredSignature.Rom.RomType); dbDict.Add("romtypemedia", Common.ReturnValueIfNull(discoveredSignature.Rom.RomTypeMedia, "")); dbDict.Add("medialabel", Common.ReturnValueIfNull(discoveredSignature.Rom.MediaLabel, "")); - dbDict.Add("path", GameFileImportPath); + + string libraryRootPath = library.Path; + if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false) + { + libraryRootPath += Path.DirectorySeparatorChar; + } + dbDict.Add("path", GameFileImportPath.Replace(libraryRootPath, "")); DataTable romInsert = db.ExecuteCMD(sql, dbDict); long romId = 0; @@ -394,7 +400,7 @@ namespace gaseous_server.Classes // move to destination if (library.IsDefaultLibrary == true) { - MoveGameFile(romId); + MoveGameFile(romId, SourceIsExternal); } return romId; @@ -430,10 +436,14 @@ namespace gaseous_server.Classes return DestinationPathName; } - public static bool MoveGameFile(long RomId) + public static bool MoveGameFile(long RomId, bool SourceIsExternal) { Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId); string romPath = rom.Path; + if (SourceIsExternal == true) + { + romPath = rom.RelativePath; + } if (File.Exists(romPath)) { @@ -458,10 +468,16 @@ namespace gaseous_server.Classes // update the db Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "UPDATE Games_Roms SET Path=@path WHERE Id=@id"; + string sql = "UPDATE Games_Roms SET RelativePath=@path WHERE Id=@id"; Dictionary dbDict = new Dictionary(); dbDict.Add("id", RomId); - dbDict.Add("path", DestinationPath); + + string libraryRootPath = rom.Library.Path; + if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false) + { + libraryRootPath += Path.DirectorySeparatorChar; + } + dbDict.Add("path", DestinationPath.Replace(libraryRootPath, "")); db.ExecuteCMD(sql, dbDict); return true; @@ -483,7 +499,7 @@ namespace gaseous_server.Classes // move rom files to their new location Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "SELECT * FROM Games_Roms WHERE LibraryId = @libraryid"; + string sql = "SELECT * FROM view_Games_Roms WHERE LibraryId = @libraryid"; Dictionary dbDict = new Dictionary(); dbDict.Add("libraryid", library.Id); DataTable romDT = db.ExecuteCMD(sql, dbDict); @@ -495,7 +511,7 @@ namespace gaseous_server.Classes SetStatus(i, romDT.Rows.Count, "Processing file " + romDT.Rows[i]["name"]); Logging.Log(Logging.LogType.Information, "Organise Library", "(" + i + "/" + romDT.Rows.Count + ") Processing ROM " + romDT.Rows[i]["name"]); long RomId = (long)romDT.Rows[i]["id"]; - MoveGameFile(RomId); + MoveGameFile(RomId, false); } } ClearStatus(); @@ -639,7 +655,7 @@ namespace gaseous_server.Classes dupDict.Add("libraryid", library.Id); db.ExecuteCMD(duplicateSql, dupDict); - string sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`"; + string sql = "SELECT * FROM view_Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`"; Dictionary dbDict = new Dictionary(); dbDict.Add("libraryid", library.Id); DataTable dtRoms = db.ExecuteCMD(sql, dbDict); @@ -664,7 +680,7 @@ namespace gaseous_server.Classes } } - sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`"; + sql = "SELECT * FROM view_Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`"; dtRoms = db.ExecuteCMD(sql, dbDict); // search for files in the library that aren't in the database @@ -736,7 +752,7 @@ namespace gaseous_server.Classes } ClearStatus(); - sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`"; + sql = "SELECT * FROM view_Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`"; dtRoms = db.ExecuteCMD(sql, dbDict); // check all roms to see if their local file still exists @@ -760,7 +776,7 @@ namespace gaseous_server.Classes if (romPath != ComputeROMPath(romId)) { Logging.Log(Logging.LogType.Information, "Library Scan", "ROM at path " + romPath + " found, but needs to be moved"); - MoveGameFile(romId); + MoveGameFile(romId, false); } else { @@ -801,11 +817,11 @@ namespace gaseous_server.Classes string sql = ""; if (ForceExecute == false) { - sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) AND LibraryId = @libraryid LIMIT 100;"; + sql = "SELECT * FROM view_Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) AND LibraryId = @libraryid LIMIT 100;"; } else { - sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND LibraryId = @libraryid;"; + sql = "SELECT * FROM view_Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND LibraryId = @libraryid;"; } Dictionary dbDict = new Dictionary(); dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7)); diff --git a/gaseous-server/Classes/Metadata/Games.cs b/gaseous-server/Classes/Metadata/Games.cs index e659755..79904dd 100644 --- a/gaseous-server/Classes/Metadata/Games.cs +++ b/gaseous-server/Classes/Metadata/Games.cs @@ -510,8 +510,8 @@ namespace gaseous_server.Classes.Metadata Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); string sql = @" SELECT DISTINCT - Games_Roms.GameId, - Games_Roms.PlatformId, + view_Games_Roms.GameId, + view_Games_Roms.PlatformId, Platform.`Name`, User_RecentPlayedRoms.UserId AS MostRecentUserId, User_RecentPlayedRoms.RomId AS MostRecentRomId, @@ -530,23 +530,23 @@ SELECT DISTINCT END AS `FavouriteRomName`, User_GameFavouriteRoms.IsMediaGroup AS FavouriteRomIsMediaGroup FROM - Games_Roms + view_Games_Roms LEFT JOIN - Platform ON Games_Roms.PlatformId = Platform.Id + Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid - AND User_RecentPlayedRoms.GameId = Games_Roms.GameId - AND User_RecentPlayedRoms.PlatformId = Games_Roms.PlatformId + AND User_RecentPlayedRoms.GameId = view_Games_Roms.GameId + AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId LEFT JOIN User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid - AND User_GameFavouriteRoms.GameId = Games_Roms.GameId - AND User_GameFavouriteRoms.PlatformId = Games_Roms.PlatformId + AND User_GameFavouriteRoms.GameId = view_Games_Roms.GameId + AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId LEFT JOIN - Games_Roms AS GMR ON GMR.Id = User_RecentPlayedRoms.RomId + view_Games_Roms AS GMR ON GMR.Id = User_RecentPlayedRoms.RomId LEFT JOIN - Games_Roms AS GFV ON GFV.Id = User_GameFavouriteRoms.RomId + view_Games_Roms AS GFV ON GFV.Id = User_GameFavouriteRoms.RomId WHERE - Games_Roms.GameId = @gameid + view_Games_Roms.GameId = @gameid ORDER BY Platform.`Name`;"; Dictionary dbDict = new Dictionary { @@ -583,7 +583,10 @@ ORDER BY Platform.`Name`;"; { LastPlayedRomId = (long?)row["MostRecentRomId"]; LastPlayedIsMediagroup = (bool)row["MostRecentRomIsMediaGroup"]; - LastPlayedRomName = (string)row["MostRecentRomName"]; + if (row["MostRecentRomName"] != System.DBNull.Value) + { + LastPlayedRomName = string.IsNullOrEmpty((string?)row["MostRecentRomName"]) ? "" : (string)row["MostRecentRomName"]; + } } long? FavouriteRomId = null; @@ -593,7 +596,10 @@ ORDER BY Platform.`Name`;"; { FavouriteRomId = (long?)row["FavouriteRomId"]; FavouriteRomIsMediagroup = (bool)row["FavouriteRomIsMediaGroup"]; - FavouriteRomName = (string)row["FavouriteRomName"]; + if (row["MostRecentRomName"] != System.DBNull.Value) + { + FavouriteRomName = string.IsNullOrEmpty((string?)row["MostRecentRomName"]) ? "" : (string)row["MostRecentRomName"]; + } } AvailablePlatformItem valuePair = new AvailablePlatformItem diff --git a/gaseous-server/Classes/Roms.cs b/gaseous-server/Classes/Roms.cs index 4721977..a8b27bf 100644 --- a/gaseous-server/Classes/Roms.cs +++ b/gaseous-server/Classes/Roms.cs @@ -39,7 +39,7 @@ namespace gaseous_server.Classes string NameSearchWhere = ""; if (NameSearch.Length > 0) { - NameSearchWhere = " AND Games_Roms.`Name` LIKE @namesearch"; + NameSearchWhere = " AND view_Games_Roms.`Name` LIKE @namesearch"; dbDict.Add("namesearch", '%' + NameSearch + '%'); } @@ -51,37 +51,37 @@ namespace gaseous_server.Classes UserJoin = @" LEFT JOIN User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid - AND User_RecentPlayedRoms.GameId = Games_Roms.GameId - AND User_RecentPlayedRoms.PlatformId = Games_Roms.PlatformId - AND User_RecentPlayedRoms.RomId = Games_Roms.Id + AND User_RecentPlayedRoms.GameId = view_Games_Roms.GameId + AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId + AND User_RecentPlayedRoms.RomId = view_Games_Roms.Id AND User_RecentPlayedRoms.IsMediaGroup = 0 LEFT JOIN User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid - AND User_GameFavouriteRoms.GameId = Games_Roms.GameId - AND User_GameFavouriteRoms.PlatformId = Games_Roms.PlatformId - AND User_GameFavouriteRoms.RomId = Games_Roms.Id + AND User_GameFavouriteRoms.GameId = view_Games_Roms.GameId + AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId + AND User_GameFavouriteRoms.RomId = view_Games_Roms.Id AND User_GameFavouriteRoms.IsMediaGroup = 0 "; } // platform query - sqlPlatform = "SELECT DISTINCT Games_Roms.PlatformId, Platform.`Name` FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;"; + sqlPlatform = "SELECT DISTINCT view_Games_Roms.PlatformId, Platform.`Name` FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;"; if (PlatformId == -1) { // data query - sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE Games_Roms.GameId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;"; + sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (view_Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE view_Games_Roms.GameId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, view_Games_Roms.`Name` LIMIT 1000;"; // count query - sqlCount = "SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.GameId = @id" + NameSearchWhere + ";"; + sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id" + NameSearchWhere + ";"; } else { // data query - sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE Games_Roms.GameId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;"; + sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (view_Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE view_Games_Roms.GameId = @id AND view_Games_Roms.PlatformId = @platformid" + NameSearchWhere + " ORDER BY Platform.`Name`, view_Games_Roms.`Name` LIMIT 1000;"; // count query - sqlCount = "SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.GameId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + ";"; + sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id AND view_Games_Roms.PlatformId = @platformid" + NameSearchWhere + ";"; dbDict.Add("platformid", PlatformId); } @@ -114,7 +114,7 @@ namespace gaseous_server.Classes public static GameRomItem GetRom(long RomId) { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "SELECT Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON Games_Roms.GameId = Game.Id WHERE Games_Roms.Id = @id"; + string sql = "SELECT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id WHERE view_Games_Roms.Id = @id"; Dictionary dbDict = new Dictionary(); dbDict.Add("id", RomId); DataTable romDT = db.ExecuteCMD(sql, dbDict); @@ -134,7 +134,7 @@ namespace gaseous_server.Classes public static GameRomItem GetRom(string MD5) { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "SELECT Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON Games_Roms.GameId = Game.Id WHERE Games_Roms.MD5 = @id"; + string sql = "SELECT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id WHERE view_Games_Roms.MD5 = @id"; Dictionary dbDict = new Dictionary(); dbDict.Add("id", MD5); DataTable romDT = db.ExecuteCMD(sql, dbDict); @@ -282,6 +282,7 @@ namespace gaseous_server.Classes RomTypeMedia = (string)romDR["romtypemedia"], MediaLabel = (string)romDR["medialabel"], Path = (string)romDR["path"], + RelativePath = (string)romDR["relativepath"], SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)romDR["metadatasource"], SignatureSourceGameTitle = (string)Common.ReturnValueIfNull(romDR["MetadataGameName"], ""), HasSaveStates = hasSaveStates, @@ -322,6 +323,7 @@ namespace gaseous_server.Classes public long GameId { get; set; } public string Game { get; set; } public string? Path { get; set; } + public string? RelativePath { get; set; } public string? SignatureSourceGameTitle { get; set; } public bool HasSaveStates { get; set; } = false; public GameLibrary.LibraryItem Library { get; set; } diff --git a/gaseous-server/Controllers/V1.0/GamesController.cs b/gaseous-server/Controllers/V1.0/GamesController.cs index 2b4c08f..b7b0a60 100644 --- a/gaseous-server/Controllers/V1.0/GamesController.cs +++ b/gaseous-server/Controllers/V1.0/GamesController.cs @@ -105,7 +105,7 @@ namespace gaseous_server.Controllers if (platform.Length > 0) { - tempVal = "Games_Roms.PlatformId IN ("; + tempVal = "view_Games_Roms.PlatformId IN ("; string[] platformClauseItems = platform.Split(","); for (int i = 0; i < platformClauseItems.Length; i++) { @@ -281,9 +281,7 @@ namespace gaseous_server.Controllers } Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - //string sql = "SELECT DISTINCT Games_Roms.GameId AS ROMGameId, Game.* FROM Games_Roms LEFT JOIN Game ON Game.Id = Games_Roms.GameId LEFT JOIN Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId " + whereClause + " " + havingClause + " " + orderByClause; - - string sql = "SELECT DISTINCT Games_Roms.GameId AS ROMGameId, Game.*, case when Game.`Name` like 'The %' then CONCAT(trim(substr(Game.`Name` from 4)), ', The') else Game.`Name` end as NameThe FROM Games_Roms LEFT JOIN Game ON Game.Id = Games_Roms.GameId LEFT JOIN Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId LEFT JOIN (SELECT Relation_Game_AgeRatings.GameId, AgeRating.* FROM Relation_Game_AgeRatings JOIN AgeRating ON Relation_Game_AgeRatings.AgeRatingsId = AgeRating.Id) view_AgeRatings ON Game.Id = view_AgeRatings.GameId " + whereClause + " " + havingClause + " " + orderByClause; + string sql = "SELECT DISTINCT view_Games_Roms.GameId AS ROMGameId, Game.*, case when Game.`Name` like 'The %' then CONCAT(trim(substr(Game.`Name` from 4)), ', The') else Game.`Name` end as NameThe FROM view_Games_Roms LEFT JOIN Game ON Game.Id = view_Games_Roms.GameId LEFT JOIN Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId LEFT JOIN (SELECT Relation_Game_AgeRatings.GameId, AgeRating.* FROM Relation_Game_AgeRatings JOIN AgeRating ON Relation_Game_AgeRatings.AgeRatingsId = AgeRating.Id) view_AgeRatings ON Game.Id = view_AgeRatings.GameId " + whereClause + " " + havingClause + " " + orderByClause; List RetVal = new List(); diff --git a/gaseous-server/Controllers/V1.0/PlatformsController.cs b/gaseous-server/Controllers/V1.0/PlatformsController.cs index bebb965..6ddda49 100644 --- a/gaseous-server/Controllers/V1.0/PlatformsController.cs +++ b/gaseous-server/Controllers/V1.0/PlatformsController.cs @@ -37,7 +37,7 @@ namespace gaseous_server.Controllers { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "SELECT * FROM Platform WHERE Id IN (SELECT DISTINCT PlatformId FROM Games_Roms) ORDER BY `Name` ASC;"; + string sql = "SELECT * FROM Platform WHERE Id IN (SELECT DISTINCT PlatformId FROM view_Games_Roms) ORDER BY `Name` ASC;"; List RetVal = new List(); diff --git a/gaseous-server/Controllers/V1.0/SystemController.cs b/gaseous-server/Controllers/V1.0/SystemController.cs index ea7995d..b3bd011 100644 --- a/gaseous-server/Controllers/V1.0/SystemController.cs +++ b/gaseous-server/Controllers/V1.0/SystemController.cs @@ -51,7 +51,7 @@ namespace gaseous_server.Controllers ReturnValue.DatabaseSize = (long)(System.Decimal)dbResponse.Rows[0][1]; // platform statistics - sql = "SELECT Platform.`name`, grc.Count, grs.Size FROM Platform INNER JOIN (SELECT Platform.`name` AS `Name`, SUM(grs.Size) AS Size FROM Platform JOIN Games_Roms AS grs ON (grs.PlatformId = Platform.Id) GROUP BY Platform.`name`) grs ON (grs.`Name` = Platform.`name`) INNER JOIN (SELECT Platform.`name` AS `Name`, COUNT(grc.Size) AS Count FROM Platform JOIN Games_Roms AS grc ON (grc.PlatformId = Platform.Id) GROUP BY Platform.`name`) grc ON (grc.`Name` = Platform.`name`) ORDER BY Platform.`name`;"; + sql = "SELECT Platform.`name`, grc.Count, grs.Size FROM Platform INNER JOIN (SELECT Platform.`name` AS `Name`, SUM(grs.Size) AS Size FROM Platform JOIN view_Games_Roms AS grs ON (grs.PlatformId = Platform.Id) GROUP BY Platform.`name`) grs ON (grs.`Name` = Platform.`name`) INNER JOIN (SELECT Platform.`name` AS `Name`, COUNT(grc.Size) AS Count FROM Platform JOIN view_Games_Roms AS grc ON (grc.PlatformId = Platform.Id) GROUP BY Platform.`name`) grc ON (grc.`Name` = Platform.`name`) ORDER BY Platform.`name`;"; dbResponse = db.ExecuteCMD(sql); ReturnValue.PlatformStatistics = new List(); foreach (DataRow dr in dbResponse.Rows) diff --git a/gaseous-server/Controllers/V1.1/GamesController.cs b/gaseous-server/Controllers/V1.1/GamesController.cs index 5e675ad..f1e9f8b 100644 --- a/gaseous-server/Controllers/V1.1/GamesController.cs +++ b/gaseous-server/Controllers/V1.1/GamesController.cs @@ -303,7 +303,7 @@ namespace gaseous_server.Controllers.v1_1 string platformWhereClause = ""; if (model.Platform.Count > 0) { - tempVal = " AND Games_Roms.PlatformId IN ("; + tempVal = " AND view_Games_Roms.PlatformId IN ("; for (int i = 0; i < model.Platform.Count; i++) { if (i > 0) @@ -511,26 +511,26 @@ FROM WHEN Game.`Name` LIKE 'The %' THEN CONCAT(TRIM(SUBSTR(Game.`Name` FROM 4)), ', The') ELSE Game.`Name` END AS NameThe, - Games_Roms.PlatformId, + view_Games_Roms.PlatformId, AgeGroup.AgeGroupId, - COUNT(Games_Roms.Id) AS RomCount + COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId - LEFT JOIN Games_Roms ON Game.Id = Games_Roms.GameId" + platformWhereClause + @" + LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId" + platformWhereClause + @" LEFT JOIN AlternativeName ON Game.Id = AlternativeName.Game " + nameWhereClause + @" GROUP BY Game.Id HAVING RomCount > 0) Game LEFT JOIN (SELECT - Games_Roms.GameId, COUNT(GameState.Id) AS RomSaveCount + view_Games_Roms.GameId, COUNT(GameState.Id) AS RomSaveCount FROM GameState - JOIN Games_Roms ON GameState.RomId = Games_Roms.Id + JOIN view_Games_Roms ON GameState.RomId = view_Games_Roms.Id WHERE GameState.IsMediaGroup = 0 AND GameState.UserId = @userid - GROUP BY Games_Roms.GameId) RomSavedStates ON Game.Id = RomSavedStates.GameId + GROUP BY view_Games_Roms.GameId) RomSavedStates ON Game.Id = RomSavedStates.GameId LEFT JOIN (SELECT RomMediaGroup.GameId, diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs index ff86a81..23b63b1 100644 --- a/gaseous-server/Program.cs +++ b/gaseous-server/Program.cs @@ -48,6 +48,9 @@ Config.InitSettings(); // write updated settings back to the config file Config.UpdateConfig(); +// update default library path +GameLibrary.UpdateDefaultLibraryPath(); + // set api metadata source from config Communications.MetadataSource = Config.MetadataConfiguration.MetadataSource; diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1024.sql b/gaseous-server/Support/Database/MySQL/gaseous-1024.sql index e0e421d..a2ea403 100644 --- a/gaseous-server/Support/Database/MySQL/gaseous-1024.sql +++ b/gaseous-server/Support/Database/MySQL/gaseous-1024.sql @@ -76,4 +76,18 @@ CREATE TABLE `User_GameFavouriteRoms` ( `PlatformId` ), CONSTRAINT `GameFavouriteRoms_Users` FOREIGN KEY (`UserId`) REFERENCES `Users` (`Id`) ON DELETE CASCADE -); \ No newline at end of file +); + +ALTER TABLE `Games_Roms` +CHANGE `Path` `RelativePath` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL; + +ALTER TABLE `Games_Roms` +ADD CONSTRAINT Games_Roms_LibraryId FOREIGN KEY (`LibraryId`) REFERENCES `GameLibraries` (`Id`) ON DELETE CASCADE; + +CREATE VIEW view_Games_Roms AS +SELECT `Games_Roms`.*, CONCAT( + `GameLibraries`.`Path`, '/', `Games_Roms`.`RelativePath` + ) AS `Path`, `GameLibraries`.`Name` AS `LibraryName` +FROM + `Games_Roms` + JOIN `GameLibraries` ON `Games_Roms`.`LibraryId` = `GameLibraries`.`Id`; \ No newline at end of file