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

Add safe deletion support.

This commit is contained in:
Dean Herbert 2017-02-24 17:08:13 +09:00
parent 6c3bda18b6
commit 958bf54c31
No known key found for this signature in database
GPG Key ID: 46D71BF4958ABB49
3 changed files with 31 additions and 5 deletions

View File

@ -8,6 +8,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Security.Cryptography; using System.Security.Cryptography;
using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
@ -39,16 +40,37 @@ namespace osu.Game.Database
try try
{ {
connection = prepareConnection(); connection = prepareConnection();
deletePending();
} }
catch catch (Exception e)
{ {
Console.WriteLine(@"Failed to initialise the beatmap database! Trying again with a clean database..."); Logger.Error(e, @"Failed to initialise the beatmap database! Trying again with a clean database...");
storage.DeleteDatabase(@"beatmaps"); storage.DeleteDatabase(@"beatmaps");
connection = prepareConnection(); connection = prepareConnection();
} }
} }
} }
private void deletePending()
{
foreach (var b in Query<BeatmapSetInfo>().Where(b => b.DeletePending))
{
try
{
storage.Delete(b.Path);
connection.Delete(b);
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete beatmap {b.ToString()}");
}
}
//this is required because sqlite migrations don't work, initially inserting nulls into this field.
//see https://github.com/praeclarum/sqlite-net/issues/326
connection.Query<BeatmapSetInfo>("UPDATE BeatmapSetInfo SET DeletePending = 0 WHERE DeletePending IS NULL");
}
private SQLiteConnection prepareConnection() private SQLiteConnection prepareConnection()
{ {
var conn = storage.GetDatabase(@"beatmaps"); var conn = storage.GetDatabase(@"beatmaps");
@ -161,8 +183,9 @@ namespace osu.Game.Database
public void Delete(BeatmapSetInfo beatmapSet) public void Delete(BeatmapSetInfo beatmapSet)
{ {
storage.Delete(beatmapSet.Path); beatmapSet.DeletePending = true;
connection.Delete(beatmapSet); Update(beatmapSet, false);
BeatmapSetRemoved?.Invoke(beatmapSet); BeatmapSetRemoved?.Invoke(beatmapSet);
} }

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using SQLite.Net.Attributes; using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes; using SQLiteNetExtensions.Attributes;
@ -23,6 +24,8 @@ namespace osu.Game.Database
[OneToMany(CascadeOperations = CascadeOperation.All)] [OneToMany(CascadeOperations = CascadeOperation.All)]
public List<BeatmapInfo> Beatmaps { get; set; } public List<BeatmapInfo> Beatmaps { get; set; }
public bool DeletePending { get; set; }
public string Hash { get; set; } public string Hash { get; set; }
public string Path { get; set; } public string Path { get; set; }

View File

@ -377,7 +377,7 @@ namespace osu.Game.Screens.Select
private void addBeatmapSets(Framework.Game game, CancellationToken token) private void addBeatmapSets(Framework.Game game, CancellationToken token)
{ {
foreach (var beatmapSet in database.Query<BeatmapSetInfo>()) foreach (var beatmapSet in database.Query<BeatmapSetInfo>().Where(b => !b.DeletePending))
{ {
if (token.IsCancellationRequested) return; if (token.IsCancellationRequested) return;
addBeatmapSet(beatmapSet, game); addBeatmapSet(beatmapSet, game);