From 8a0b184dd6c5321789d8428f00f2fd7b0a1cddea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Oct 2017 12:56:58 +0900 Subject: [PATCH] Revert "Return back DatabaseBackedStore's query and populate functions" This reverts commit 7cf5d63cd32bde05ee0bcbc262e5dac7595036f4. --- osu.Game/Beatmaps/BeatmapInfo.cs | 9 +--- osu.Game/Beatmaps/BeatmapManager.cs | 46 +++++++------------ osu.Game/Beatmaps/BeatmapSetInfo.cs | 24 +--------- osu.Game/Beatmaps/BeatmapStore.cs | 42 +++++++++++++++++ osu.Game/Database/DatabaseBackedStore.cs | 41 ----------------- osu.Game/Database/IPopulate.cs | 10 ---- osu.Game/Rulesets/RulesetStore.cs | 19 ++++++-- .../Tests/Visual/TestCasePlaySongSelect.cs | 6 +-- osu.Game/Tests/Visual/TestCasePlayer.cs | 2 +- osu.Game/osu.Game.csproj | 1 - 10 files changed, 80 insertions(+), 120 deletions(-) delete mode 100644 osu.Game/Database/IPopulate.cs diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 621bc59786..c1516f17c9 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -6,13 +6,12 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using Newtonsoft.Json; -using osu.Game.Database; using osu.Game.IO.Serialization; using osu.Game.Rulesets; namespace osu.Game.Beatmaps { - public class BeatmapInfo : IEquatable, IJsonSerializable, IPopulate + public class BeatmapInfo : IEquatable, IJsonSerializable { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } @@ -125,11 +124,5 @@ namespace osu.Game.Beatmaps public bool BackgroundEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && BeatmapSet.Hash == other.BeatmapSet.Hash && (Metadata ?? BeatmapSet.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSet.Metadata).BackgroundFile; - - public void Populate(OsuDbContext connection) - { - var entry = connection.Entry(this); - entry.Reference(nameof(Difficulty)); - } } } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index d364a8fbe4..955c6f4b17 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Linq.Expressions; using System.Threading.Tasks; using Ionic.Zip; using osu.Framework.Audio.Track; @@ -259,13 +260,10 @@ namespace osu.Game.Beatmaps /// The beatmap set to delete. public void Delete(BeatmapSetInfo beatmapSet) { - lock (beatmaps) - { - if (!beatmaps.Delete(beatmapSet)) return; + if (!beatmaps.Delete(beatmapSet)) return; - if (!beatmapSet.Protected) - files.Dereference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); - } + if (!beatmapSet.Protected) + files.Dereference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); } /// @@ -304,9 +302,6 @@ namespace osu.Game.Beatmaps if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) return DefaultBeatmap; - lock (beatmaps) - beatmaps.Populate(beatmapInfo); - if (beatmapInfo.BeatmapSet == null) throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database."); @@ -338,10 +333,7 @@ namespace osu.Game.Beatmaps { lock (beatmaps) { - BeatmapSetInfo set = beatmaps.Query(query).FirstOrDefault(); - - if (set != null) - beatmaps.Populate(set); + BeatmapSetInfo set = beatmaps.QueryBeatmapSet(query); return set; } @@ -359,9 +351,9 @@ namespace osu.Game.Beatmaps /// /// The query. /// Results from the provided query. - public List QueryBeatmapSets(Func query) + public List QueryBeatmapSets(Expression> query) { - return beatmaps.QueryAndPopulate(query); + return beatmaps.QueryBeatmapSets(query); } /// @@ -371,15 +363,9 @@ namespace osu.Game.Beatmaps /// The first result for the provided query, or null if no results were found. public BeatmapInfo QueryBeatmap(Func query) { - lock (beatmaps) - { - BeatmapInfo set = beatmaps.Query(query).FirstOrDefault(); + BeatmapInfo set = beatmaps.QueryBeatmap(query); - if (set != null) - beatmaps.Populate(set); - - return set; - } + return set; } /// @@ -387,9 +373,9 @@ namespace osu.Game.Beatmaps /// /// The query. /// Results from the provided query. - public List QueryBeatmaps(Func query) + public List QueryBeatmaps(Expression> query) { - lock (beatmaps) return beatmaps.Query(query); + lock (beatmaps) return beatmaps.QueryBeatmaps(query); } /// @@ -428,7 +414,7 @@ namespace osu.Game.Beatmaps // check if this beatmap has already been imported and exit early if so. BeatmapSetInfo beatmapSet; lock (beatmaps) - beatmapSet = beatmaps.QueryAndPopulate(b => b.Hash == hash).FirstOrDefault(); + beatmapSet = beatmaps.QueryBeatmapSet(b => b.Hash == hash); if (beatmapSet != null) { @@ -492,8 +478,8 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.Metadata = null; // TODO: this should be done in a better place once we actually need to dynamically update it. - beatmap.BeatmapInfo.Ruleset = rulesets.Query(r => r.ID == beatmap.BeatmapInfo.RulesetID).FirstOrDefault(); - beatmap.BeatmapInfo.StarDifficulty = rulesets.Query(r => r.ID == beatmap.BeatmapInfo.RulesetID).FirstOrDefault()?.CreateInstance()?.CreateDifficultyCalculator(beatmap) + beatmap.BeatmapInfo.Ruleset = rulesets.QueryRulesetInfo(r => r.ID == beatmap.BeatmapInfo.RulesetID); + beatmap.BeatmapInfo.StarDifficulty = rulesets.QueryRulesetInfo(r => r.ID == beatmap.BeatmapInfo.RulesetID)?.CreateInstance()?.CreateDifficultyCalculator(beatmap) .Calculate() ?? 0; beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo); @@ -507,11 +493,11 @@ namespace osu.Game.Beatmaps /// Returns a list of all usable s. /// /// A list of available . - public List GetAllUsableBeatmapSets(bool populate = true) + public List GetAllUsableBeatmapSets() { lock (beatmaps) { - return populate ? beatmaps.QueryAndPopulate(b => !b.DeletePending) : beatmaps.Query(b => !b.DeletePending); + return beatmaps.QueryBeatmapSets(b => !b.DeletePending); } } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index ddbc5d0dfb..404add2fa5 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -4,12 +4,10 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; -using osu.Game.Database; -using osu.Game.IO; namespace osu.Game.Beatmaps { - public class BeatmapSetInfo : IPopulate + public class BeatmapSetInfo { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } @@ -36,25 +34,5 @@ namespace osu.Game.Beatmaps public List Files { get; set; } public bool Protected { get; set; } - - public void Populate(OsuDbContext connection) - { - var entry = connection.Entry(this); - entry.Collection(nameof(Beatmaps)).Load(); - entry.Reference(nameof(Metadata)).Load(); - entry.Collection(nameof(Files)).Load(); - - foreach (var beatmap in Beatmaps) - { - var beatmapEntry = connection.Entry(beatmap); - beatmapEntry.Reference(nameof(beatmap.Difficulty)).Load(); - } - - foreach (var file in Files) - { - var fileEntry = connection.Entry(file); - fileEntry.Reference(nameof(file.FileInfo)).Load(); - } - } } } diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 0be502132f..9c5a1a9dfc 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -2,7 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using Microsoft.EntityFrameworkCore; using osu.Game.Database; @@ -132,5 +134,45 @@ namespace osu.Game.Beatmaps { Connection.BeatmapSetInfo.RemoveRange(Connection.BeatmapSetInfo.Where(b => b.DeletePending && !b.Protected)); } + + public BeatmapSetInfo QueryBeatmapSet(Func query) + { + return Connection.BeatmapSetInfo + .Include(b => b.Metadata) + .Include(b => b.Beatmaps).ThenInclude(b => b.Ruleset) + .Include(b => b.Beatmaps).ThenInclude(b => b.Difficulty) + .Include(b => b.Files).ThenInclude(f => f.FileInfo) + .FirstOrDefault(query); + } + + public List QueryBeatmapSets(Expression> query) + { + return Connection.BeatmapSetInfo + .Include(b => b.Metadata) + .Include(b => b.Beatmaps).ThenInclude(b => b.Ruleset) + .Include(b => b.Beatmaps).ThenInclude(b => b.Difficulty) + .Include(b => b.Files).ThenInclude(f => f.FileInfo) + .Where(query).ToList(); + } + + public BeatmapInfo QueryBeatmap(Func query) + { + return Connection.BeatmapInfo + .Include(b => b.BeatmapSet) + .Include(b => b.Metadata) + .Include(b => b.Ruleset) + .Include(b => b.Difficulty) + .FirstOrDefault(query); + } + + public List QueryBeatmaps(Expression> query) + { + return Connection.BeatmapInfo + .Include(b => b.BeatmapSet) + .Include(b => b.Metadata) + .Include(b => b.Ruleset) + .Include(b => b.Difficulty) + .Where(query).ToList(); + } } } diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index fd891ca825..f4b6a866dc 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; using osu.Framework.Logging; @@ -50,46 +49,6 @@ namespace osu.Game.Database /// public void Reset() => Prepare(true); - public List Query(Func filter = null) where T : class - { - checkType(typeof(T)); - - var dbSet = Connection.GetType().GetProperties().Single(property => property.PropertyType == typeof(DbSet)).GetValue(Connection) as DbSet; - var query = dbSet.ToList(); - - if (filter != null) - query = query.Where(filter).ToList(); - - return query; - } - - /// - /// Query and populate results. - /// - /// An filter to refine results. - /// - public List QueryAndPopulate(Func filter) - where T : class, IPopulate - { - checkType(typeof(T)); - - var query = Query(filter); - foreach (var item in query) - Populate(item); - return query; - } - - /// - /// Populate a database-backed item. - /// - /// - public void Populate(IPopulate item) - { - checkType(item.GetType()); - - item.Populate(Connection); - } - private void checkType(Type type) { if (!ValidTypes.Contains(type)) diff --git a/osu.Game/Database/IPopulate.cs b/osu.Game/Database/IPopulate.cs deleted file mode 100644 index b07312f81c..0000000000 --- a/osu.Game/Database/IPopulate.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Database -{ - public interface IPopulate - { - void Populate(OsuDbContext connection); - } -} diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 8a8bbd9244..5a4b33df0b 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -42,14 +42,14 @@ namespace osu.Game.Rulesets { Connection.Database.ExecuteSqlCommand("DELETE FROM RulesetInfo"); } - + var instances = loaded_assemblies.Values.Select(r => (Ruleset)Activator.CreateInstance(r, new RulesetInfo())); //add all legacy modes in correct order foreach (var r in instances.Where(r => r.LegacyID >= 0).OrderBy(r => r.LegacyID)) { var rulesetInfo = createRulesetInfo(r); - if (Connection.RulesetInfo.SingleOrDefault(rsi => rsi.ID == rulesetInfo.ID) == null) + if (Connection.RulesetInfo.SingleOrDefault(rsi=>rsi.ID==rulesetInfo.ID)==null) { Connection.RulesetInfo.Add(rulesetInfo); } @@ -108,6 +108,19 @@ namespace osu.Game.Rulesets protected override Type[] ValidTypes => new[] { typeof(RulesetInfo) }; - public RulesetInfo GetRuleset(int id) => Query().First(r => r.ID == id); + public RulesetInfo GetRuleset(int id) => Connection.RulesetInfo.First(r => r.ID == id); + + public RulesetInfo QueryRulesetInfo(Func query) + { + return Connection.RulesetInfo.FirstOrDefault(query); + } + + public List QueryRulesets(Func query = null) + { + var rulesets = Connection.RulesetInfo; + if (query != null) + return rulesets.Where(query).ToList(); + return rulesets.ToList(); + } } } diff --git a/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs index f4c0d0b1b6..1b7f2def4d 100644 --- a/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs @@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1234 + i, - Ruleset = rulesets.Query().First(), + Ruleset = rulesets.QueryRulesets().First(), Path = "normal.osu", Version = "Normal", Difficulty = new BeatmapDifficulty @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1235 + i, - Ruleset = rulesets.Query().First(), + Ruleset = rulesets.QueryRulesets().First(), Path = "hard.osu", Version = "Hard", Difficulty = new BeatmapDifficulty @@ -97,7 +97,7 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1236 + i, - Ruleset = rulesets.Query().First(), + Ruleset = rulesets.QueryRulesets().First(), Path = "insane.osu", Version = "Insane", Difficulty = new BeatmapDifficulty diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index b0953ceb7e..811e240cee 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -50,7 +50,7 @@ namespace osu.Game.Tests.Visual string instantiation = ruleset?.AssemblyQualifiedName; - foreach (var r in rulesets.Query(rs => rs.Available && (instantiation == null || rs.InstantiationInfo == instantiation))) + foreach (var r in rulesets.QueryRulesets(rs => rs.Available && (instantiation == null || rs.InstantiationInfo == instantiation))) AddStep(r.Name, () => loadPlayerFor(r)); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 03ca32539c..6fbd169e2a 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -277,7 +277,6 @@ - 20171014052545_Init.cs