1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 13:37:25 +08:00

Simplify and document DatabaseStore API

This commit is contained in:
Dean Herbert 2017-07-27 15:06:10 +09:00
parent a90eff69db
commit 96b08b8777
8 changed files with 54 additions and 27 deletions

View File

@ -115,9 +115,11 @@ namespace osu.Game.Tests.Beatmaps.IO
{
IEnumerable<BeatmapSetInfo> resultSets = null;
var store = osu.Dependencies.Get<BeatmapStore>();
Action waitAction = () =>
{
while (!(resultSets = osu.Dependencies.Get<BeatmapStore>().Database.
while (!(resultSets = store.Database.
Query<BeatmapSetInfo>().Where(s => s.OnlineBeatmapSetID == 241526)).Any())
Thread.Sleep(50);
};
@ -134,15 +136,16 @@ namespace osu.Game.Tests.Beatmaps.IO
//if we don't re-check here, the set will be inserted but the beatmaps won't be present yet.
waitAction = () =>
{
while ((resultBeatmaps = osu.Dependencies.Get<BeatmapStore>().Database.
GetAllWithChildren<BeatmapInfo>(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12)
while ((resultBeatmaps = store.Database.
QueryAndPopulate<BeatmapInfo>(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12)
Thread.Sleep(50);
};
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout),
@"Beatmaps did not import to the database in allocated time");
var set = osu.Dependencies.Get<BeatmapStore>().Database.GetChildren(resultSets.First());
var set = resultSets.First();
store.Database.Populate(set);
Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(),
$@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).");
@ -152,16 +155,16 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(set.Beatmaps.Count > 0);
var beatmap = osu.Dependencies.Get<BeatmapStore>().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap;
var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
beatmap = osu.Dependencies.Get<BeatmapStore>().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap;
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
beatmap = osu.Dependencies.Get<BeatmapStore>().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap;
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
beatmap = osu.Dependencies.Get<BeatmapStore>().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
}
}

View File

@ -94,7 +94,7 @@ namespace osu.Game.Beatmaps
private void cleanupPendingDeletions()
{
foreach (var b in GetAllWithChildren<BeatmapSetInfo>(b => b.DeletePending && !b.Protected))
foreach (var b in QueryAndPopulate<BeatmapSetInfo>(b => b.DeletePending && !b.Protected))
{
try
{

View File

@ -150,9 +150,7 @@ namespace osu.Game.Beatmaps
if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
return DefaultBeatmap;
beatmapInfo = Database.GetChildren(beatmapInfo, true);
Database.GetChildren(beatmapInfo.BeatmapSet, true);
Database.Populate(beatmapInfo);
if (beatmapInfo.BeatmapSet == null)
throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database.");
@ -185,7 +183,7 @@ namespace osu.Game.Beatmaps
BeatmapSetInfo set = Database.Query<BeatmapSetInfo>().FirstOrDefault(query);
if (set != null)
Database.GetChildren(set, true);
Database.Populate(set);
return set;
}
@ -235,7 +233,7 @@ namespace osu.Game.Beatmaps
if (existing != null)
{
Database.GetChildren(existing);
Database.Populate(existing);
Undelete(existing);
return existing;
}

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using osu.Framework.Logging;
using osu.Framework.Platform;
@ -42,28 +43,50 @@ namespace osu.Game.Database
/// </summary>
public void Reset() => Prepare(true);
public TableQuery<T> Query<T>() where T : class
public TableQuery<T> Query<T>(Expression<Func<T, bool>> filter = null) where T : class
{
return Connection.Table<T>();
checkType(typeof(T));
var query = Connection.Table<T>();
if (filter != null)
query = query.Where(filter);
return query;
}
/// <summary>
/// This is expensive. Use with caution.
/// Query and populate results.
/// </summary>
public List<T> GetAllWithChildren<T>(Expression<Func<T, bool>> filter = null, bool recursive = true)
/// <param name="filter">An optional filter to refine results.</param>
/// <returns></returns>
public List<T> QueryAndPopulate<T>(Expression<Func<T, bool>> filter = null)
where T : class
{
return Connection.GetAllWithChildren(filter, recursive);
checkType(typeof(T));
return Connection.GetAllWithChildren(filter, true);
}
public T GetChildren<T>(T item, bool recursive = false)
/// <summary>
/// Populate a database-backed item.
/// </summary>
/// <param name="item"></param>
/// <param name="recursive">Whether population should recurse beyond a single level.</param>
public void Populate<T>(T item, bool recursive = true)
{
if (item == null) return default(T);
checkType(item.GetType());
Connection.GetChildren(item, recursive);
return item;
}
private void checkType(Type type)
{
if (!ValidTypes.Contains(type))
throw new InvalidOperationException($"The requested operation specified a type of {type}, which is invalid for this {nameof(DatabaseStore)}.");
}
protected abstract Type[] ValidTypes { get; }
}
}
}

View File

@ -97,7 +97,7 @@ namespace osu.Game.IO
private void deletePending()
{
foreach (var f in GetAllWithChildren<FileInfo>(f => f.ReferenceCount < 1))
foreach (var f in QueryAndPopulate<FileInfo>(f => f.ReferenceCount < 1))
{
try
{

View File

@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Music
},
};
list.BeatmapSets = BeatmapSets = beatmaps.Database.GetAllWithChildren<BeatmapSetInfo>(b => !b.DeletePending).ToList();
list.BeatmapSets = BeatmapSets = beatmaps.Database.QueryAndPopulate<BeatmapSetInfo>(b => !b.DeletePending).ToList();
beatmaps.BeatmapSetAdded += s => list.AddBeatmapSet(s);
beatmaps.BeatmapSetRemoved += s => list.RemoveBeatmapSet(s);

View File

@ -76,10 +76,13 @@ namespace osu.Game.Screens.Menu
if (!menuMusic)
{
var query = beatmaps.Database.Query<BeatmapSetInfo>().Where(b => !b.DeletePending);
var query = beatmaps.Database.Query<BeatmapSetInfo>(b => !b.DeletePending);
int count = query.Count();
if (count > 0)
{
setInfo = query.ElementAt(RNG.Next(0, count - 1));
beatmaps.Database.Populate(setInfo);
}
}
if (setInfo == null)

View File

@ -180,7 +180,7 @@ namespace osu.Game.Screens.Select
initialAddSetsTask = new CancellationTokenSource();
carousel.Beatmaps = store.Database.GetAllWithChildren<BeatmapSetInfo>(b => !b.DeletePending);
carousel.Beatmaps = store.Database.QueryAndPopulate<BeatmapSetInfo>(b => !b.DeletePending);
Beatmap.ValueChanged += beatmap_ValueChanged;