2017-07-26 07:28:32 +00:00
|
|
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
2017-02-07 04:59:30 +00:00
|
|
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
2016-12-06 09:56:20 +00:00
|
|
|
|
|
|
|
using System;
|
2016-10-04 20:29:08 +00:00
|
|
|
using System.Collections.Generic;
|
2017-02-24 08:08:13 +00:00
|
|
|
using osu.Framework.Logging;
|
2017-07-26 07:28:32 +00:00
|
|
|
using osu.Game.Database;
|
2016-10-18 17:35:01 +00:00
|
|
|
using SQLite.Net;
|
|
|
|
using SQLiteNetExtensions.Extensions;
|
2016-10-04 15:31:10 +00:00
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
namespace osu.Game.Beatmaps
|
2016-10-14 03:33:58 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Handles the storage and retrieval of Beatmaps/BeatmapSets to the database backing
|
|
|
|
/// </summary>
|
|
|
|
public class BeatmapDatabase : DatabaseStore
|
2016-10-14 03:33:58 +00:00
|
|
|
{
|
2016-10-11 17:52:16 +00:00
|
|
|
public event Action<BeatmapSetInfo> BeatmapSetAdded;
|
2017-02-24 05:37:54 +00:00
|
|
|
public event Action<BeatmapSetInfo> BeatmapSetRemoved;
|
2016-10-21 09:25:22 +00:00
|
|
|
|
2017-07-26 11:22:02 +00:00
|
|
|
public BeatmapDatabase(SQLiteConnection connection)
|
|
|
|
: base(connection)
|
2016-10-14 03:33:58 +00:00
|
|
|
{
|
2016-10-04 20:29:08 +00:00
|
|
|
}
|
2016-10-18 17:35:01 +00:00
|
|
|
|
2017-07-26 11:22:02 +00:00
|
|
|
protected override Type[] ValidTypes => new[]
|
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
typeof(BeatmapSetInfo),
|
|
|
|
typeof(BeatmapInfo),
|
|
|
|
typeof(BeatmapMetadata),
|
|
|
|
typeof(BeatmapDifficulty),
|
|
|
|
};
|
2017-02-24 08:08:13 +00:00
|
|
|
|
2017-04-17 10:44:03 +00:00
|
|
|
protected override void Prepare(bool reset = false)
|
2017-01-23 09:13:06 +00:00
|
|
|
{
|
2017-04-17 10:44:03 +00:00
|
|
|
if (reset)
|
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
Connection.DropTable<BeatmapMetadata>();
|
|
|
|
Connection.DropTable<BeatmapDifficulty>();
|
|
|
|
Connection.DropTable<BeatmapSetInfo>();
|
2017-07-26 11:22:02 +00:00
|
|
|
Connection.DropTable<BeatmapSetFileInfo>();
|
2017-07-26 07:28:32 +00:00
|
|
|
Connection.DropTable<BeatmapInfo>();
|
2016-10-27 08:08:53 +00:00
|
|
|
}
|
2016-10-21 08:01:46 +00:00
|
|
|
|
2017-07-26 08:14:38 +00:00
|
|
|
Connection.CreateTable<BeatmapMetadata>();
|
|
|
|
Connection.CreateTable<BeatmapDifficulty>();
|
|
|
|
Connection.CreateTable<BeatmapSetInfo>();
|
2017-07-26 11:22:02 +00:00
|
|
|
Connection.CreateTable<BeatmapSetFileInfo>();
|
2017-07-26 08:14:38 +00:00
|
|
|
Connection.CreateTable<BeatmapInfo>();
|
|
|
|
|
2017-04-17 10:44:03 +00:00
|
|
|
deletePending();
|
2016-10-21 08:01:46 +00:00
|
|
|
}
|
|
|
|
|
2017-07-26 11:22:02 +00:00
|
|
|
public void Update(BeatmapSetInfo setInfo) => Connection.Update(setInfo);
|
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
public void Import(IEnumerable<BeatmapSetInfo> beatmapSets)
|
2016-10-14 03:33:58 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
lock (Connection)
|
2017-03-17 09:57:24 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
Connection.BeginTransaction();
|
2017-05-23 07:26:51 +00:00
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
foreach (var s in beatmapSets)
|
2017-02-28 13:46:16 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
Connection.InsertOrReplaceWithChildren(s, true);
|
|
|
|
BeatmapSetAdded?.Invoke(s);
|
2017-02-28 13:46:16 +00:00
|
|
|
}
|
2017-05-23 07:26:51 +00:00
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
Connection.Commit();
|
|
|
|
}
|
2017-02-12 05:53:33 +00:00
|
|
|
}
|
|
|
|
|
2017-07-26 11:22:02 +00:00
|
|
|
public bool Delete(BeatmapSetInfo set)
|
2017-02-28 13:35:42 +00:00
|
|
|
{
|
2017-07-26 11:22:02 +00:00
|
|
|
if (set.DeletePending) return false;
|
|
|
|
|
|
|
|
set.DeletePending = true;
|
|
|
|
Connection.Update(set);
|
|
|
|
|
|
|
|
BeatmapSetRemoved?.Invoke(set);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool Undelete(BeatmapSetInfo set)
|
|
|
|
{
|
|
|
|
if (!set.DeletePending) return false;
|
|
|
|
|
|
|
|
set.DeletePending = false;
|
|
|
|
Connection.Update(set);
|
|
|
|
|
|
|
|
BeatmapSetAdded?.Invoke(set);
|
|
|
|
return true;
|
2017-02-28 13:35:42 +00:00
|
|
|
}
|
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
private void deletePending()
|
2017-05-23 07:26:51 +00:00
|
|
|
{
|
2017-07-26 11:22:02 +00:00
|
|
|
foreach (var b in GetAllWithChildren<BeatmapSetInfo>(b => b.DeletePending && !b.Protected))
|
2017-02-24 08:49:19 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
try
|
2017-02-24 08:49:19 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
foreach (var i in b.Beatmaps)
|
2016-10-19 15:00:11 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
if (i.Metadata != null) Connection.Delete(i.Metadata);
|
|
|
|
if (i.Difficulty != null) Connection.Delete(i.Difficulty);
|
2017-04-17 10:44:03 +00:00
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
Connection.Delete(i);
|
2016-10-19 15:00:11 +00:00
|
|
|
}
|
2017-02-25 01:39:13 +00:00
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
if (b.Metadata != null) Connection.Delete(b.Metadata);
|
|
|
|
Connection.Delete(b);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
2017-03-02 12:36:01 +00:00
|
|
|
{
|
2017-07-26 07:28:32 +00:00
|
|
|
Logger.Error(e, $@"Could not delete beatmap {b}");
|
2017-03-02 12:36:01 +00:00
|
|
|
}
|
2017-02-25 01:39:13 +00:00
|
|
|
}
|
2016-10-14 03:33:58 +00:00
|
|
|
|
2017-07-26 07:28:32 +00:00
|
|
|
//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");
|
2016-10-18 19:38:59 +00:00
|
|
|
}
|
2016-10-14 03:33:58 +00:00
|
|
|
}
|
2017-07-26 07:28:32 +00:00
|
|
|
}
|