osu/osu.Game/Beatmaps/BeatmapStore.cs

118 lines
5.7 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2018-04-13 09:19:50 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using osu.Game.Database;
namespace osu.Game.Beatmaps
{
/// <summary>
/// Handles the storage and retrieval of Beatmaps/BeatmapSets to the database backing
/// </summary>
public class BeatmapStore : MutableDatabaseBackedStoreWithFileIncludes<BeatmapSetInfo, BeatmapSetFileInfo>
2018-04-13 09:19:50 +00:00
{
public event Action<BeatmapInfo> BeatmapHidden;
public event Action<BeatmapInfo> BeatmapRestored;
public BeatmapStore(IDatabaseContextFactory factory)
: base(factory)
{
}
/// <summary>
/// Hide a <see cref="BeatmapInfo"/> in the database.
/// </summary>
2021-10-02 15:55:29 +00:00
/// <param name="beatmapInfo">The beatmap to hide.</param>
2018-04-13 09:19:50 +00:00
/// <returns>Whether the beatmap's <see cref="BeatmapInfo.Hidden"/> was changed.</returns>
2021-10-02 15:55:29 +00:00
public bool Hide(BeatmapInfo beatmapInfo)
2018-04-13 09:19:50 +00:00
{
using (ContextFactory.GetForWrite())
{
2021-10-02 15:55:29 +00:00
Refresh(ref beatmapInfo, Beatmaps);
2018-04-13 09:19:50 +00:00
2021-10-02 15:55:29 +00:00
if (beatmapInfo.Hidden) return false;
2019-02-28 04:31:40 +00:00
2021-10-02 15:55:29 +00:00
beatmapInfo.Hidden = true;
2018-04-13 09:19:50 +00:00
}
2021-10-02 15:55:29 +00:00
BeatmapHidden?.Invoke(beatmapInfo);
2018-04-13 09:19:50 +00:00
return true;
}
/// <summary>
/// Restore a previously hidden <see cref="BeatmapInfo"/>.
/// </summary>
2021-10-02 15:55:29 +00:00
/// <param name="beatmapInfo">The beatmap to restore.</param>
2018-04-13 09:19:50 +00:00
/// <returns>Whether the beatmap's <see cref="BeatmapInfo.Hidden"/> was changed.</returns>
2021-10-02 15:55:29 +00:00
public bool Restore(BeatmapInfo beatmapInfo)
2018-04-13 09:19:50 +00:00
{
using (ContextFactory.GetForWrite())
{
2021-10-02 15:55:29 +00:00
Refresh(ref beatmapInfo, Beatmaps);
2018-04-13 09:19:50 +00:00
2021-10-02 15:55:29 +00:00
if (!beatmapInfo.Hidden) return false;
2019-02-28 04:31:40 +00:00
2021-10-02 15:55:29 +00:00
beatmapInfo.Hidden = false;
2018-04-13 09:19:50 +00:00
}
2021-10-02 15:55:29 +00:00
BeatmapRestored?.Invoke(beatmapInfo);
2018-04-13 09:19:50 +00:00
return true;
}
protected override IQueryable<BeatmapSetInfo> AddIncludesForDeletion(IQueryable<BeatmapSetInfo> query) =>
base.AddIncludesForDeletion(query)
.Include(s => s.Metadata)
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata);
2018-04-13 09:19:50 +00:00
protected override IQueryable<BeatmapSetInfo> AddIncludesForConsumption(IQueryable<BeatmapSetInfo> query) =>
base.AddIncludesForConsumption(query)
.Include(s => s.Metadata)
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata);
2018-04-13 09:19:50 +00:00
protected override void Purge(List<BeatmapSetInfo> items, OsuDbContext context)
{
// metadata is M-N so we can't rely on cascades
context.BeatmapMetadata.RemoveRange(items.Select(s => s.Metadata));
context.BeatmapMetadata.RemoveRange(items.SelectMany(s => s.Beatmaps.Select(b => b.Metadata).Where(m => m != null)));
// todo: we can probably make cascades work here with a FK in BeatmapDifficulty. just make to make it work correctly.
context.BeatmapDifficulty.RemoveRange(items.SelectMany(s => s.Beatmaps.Select(b => b.BaseDifficulty)));
base.Purge(items, context);
}
public IQueryable<BeatmapSetInfo> BeatmapSetsOverview => ContextFactory.Get().BeatmapSetInfo
.Include(s => s.Metadata)
.Include(s => s.Beatmaps)
.AsNoTracking();
public IQueryable<BeatmapSetInfo> BeatmapSetsWithoutRuleset => ContextFactory.Get().BeatmapSetInfo
.Include(s => s.Metadata)
.Include(s => s.Files).ThenInclude(f => f.FileInfo)
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
.AsNoTracking();
public IQueryable<BeatmapSetInfo> BeatmapSetsWithoutFiles => ContextFactory.Get().BeatmapSetInfo
.Include(s => s.Metadata)
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
.AsNoTracking();
2018-04-13 09:19:50 +00:00
public IQueryable<BeatmapInfo> Beatmaps =>
ContextFactory.Get().BeatmapInfo
.Include(b => b.BeatmapSet).ThenInclude(s => s.Metadata)
.Include(b => b.BeatmapSet).ThenInclude(s => s.Files).ThenInclude(f => f.FileInfo)
.Include(b => b.Metadata)
.Include(b => b.Ruleset)
.Include(b => b.BaseDifficulty);
}
}