mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 08:13:31 +08:00
Merge branch 'master' into scroll_to_selected
This commit is contained in:
commit
024a34a9b3
@ -1 +1 @@
|
||||
Subproject commit 5a9ca94fc31bc796b45572eb3d0b27b46556c586
|
||||
Subproject commit 2204764944ff693e857649253547054cc91764a0
|
@ -20,7 +20,6 @@ using osu.Game.IPC;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets;
|
||||
using SQLite.Net;
|
||||
using FileInfo = osu.Game.IO.FileInfo;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
@ -170,7 +169,7 @@ namespace osu.Game.Beatmaps
|
||||
if (!beatmaps.Delete(beatmapSet)) return;
|
||||
|
||||
if (!beatmapSet.Protected)
|
||||
files.Dereference(beatmapSet.Files);
|
||||
files.Dereference(beatmapSet.Files.Select(f => f.FileInfo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -183,7 +182,8 @@ namespace osu.Game.Beatmaps
|
||||
lock (beatmaps)
|
||||
if (!beatmaps.Undelete(beatmapSet)) return;
|
||||
|
||||
files.Reference(beatmapSet.Files);
|
||||
if (!beatmapSet.Protected)
|
||||
files.Reference(beatmapSet.Files.Select(f => f.FileInfo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -318,12 +318,16 @@ namespace osu.Game.Beatmaps
|
||||
return beatmapSet;
|
||||
}
|
||||
|
||||
List<FileInfo> fileInfos = new List<FileInfo>();
|
||||
List<BeatmapSetFileInfo> fileInfos = new List<BeatmapSetFileInfo>();
|
||||
|
||||
// import files to manager
|
||||
foreach (string file in reader.Filenames)
|
||||
using (Stream s = reader.GetStream(file))
|
||||
fileInfos.Add(files.Add(s, file));
|
||||
fileInfos.Add(new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = file,
|
||||
FileInfo = files.Add(s)
|
||||
});
|
||||
|
||||
BeatmapMetadata metadata;
|
||||
|
||||
@ -422,7 +426,7 @@ namespace osu.Game.Beatmaps
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => f.Filename == filename).StoragePath;
|
||||
private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => f.Filename == filename).FileInfo.StoragePath;
|
||||
|
||||
protected override Texture GetBackground()
|
||||
{
|
||||
|
@ -2,16 +2,26 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.IO;
|
||||
using SQLite.Net.Attributes;
|
||||
using SQLiteNetExtensions.Attributes;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
public class BeatmapSetFileInfo
|
||||
{
|
||||
[ForeignKey(typeof(BeatmapSetInfo))]
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int ID { get; set; }
|
||||
|
||||
[ForeignKey(typeof(BeatmapSetInfo)), NotNull]
|
||||
public int BeatmapSetInfoID { get; set; }
|
||||
|
||||
[ForeignKey(typeof(FileInfo))]
|
||||
[ForeignKey(typeof(FileInfo)), NotNull]
|
||||
public int FileInfoID { get; set; }
|
||||
|
||||
[OneToOne(CascadeOperations = CascadeOperation.CascadeRead)]
|
||||
public FileInfo FileInfo { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public string Filename { get; set; }
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.IO;
|
||||
using SQLite.Net.Attributes;
|
||||
using SQLiteNetExtensions.Attributes;
|
||||
|
||||
@ -37,8 +36,8 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public string StoryboardFile => Files.FirstOrDefault(f => f.Filename.EndsWith(".osb"))?.Filename;
|
||||
|
||||
[ManyToMany(typeof(BeatmapSetFileInfo), CascadeOperations = CascadeOperation.CascadeRead)]
|
||||
public List<FileInfo> Files { get; set; }
|
||||
[OneToMany(CascadeOperations = CascadeOperation.All)]
|
||||
public List<BeatmapSetFileInfo> Files { get; set; }
|
||||
|
||||
public bool Protected { get; set; }
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Beatmaps
|
||||
/// The current version of this store. Used for migrations (see <see cref="PerformMigration(int, int)"/>).
|
||||
/// The initial version is 1.
|
||||
/// </summary>
|
||||
protected override int StoreVersion => 1;
|
||||
protected override int StoreVersion => 2;
|
||||
|
||||
public BeatmapStore(SQLiteConnection connection)
|
||||
: base(connection)
|
||||
@ -52,7 +52,11 @@ namespace osu.Game.Beatmaps
|
||||
Connection.CreateTable<BeatmapSetInfo>();
|
||||
Connection.CreateTable<BeatmapSetFileInfo>();
|
||||
Connection.CreateTable<BeatmapInfo>();
|
||||
}
|
||||
|
||||
protected override void StartupTasks()
|
||||
{
|
||||
base.StartupTasks();
|
||||
cleanupPendingDeletions();
|
||||
}
|
||||
|
||||
@ -60,24 +64,19 @@ namespace osu.Game.Beatmaps
|
||||
/// Perform migrations between two store versions.
|
||||
/// </summary>
|
||||
/// <param name="currentVersion">The current store version. This will be zero on a fresh database initialisation.</param>
|
||||
/// <param name="newVersion">The target version which we are migrating to (equal to the current <see cref="StoreVersion"/>).</param>
|
||||
protected override void PerformMigration(int currentVersion, int newVersion)
|
||||
/// <param name="targetVersion">The target version which we are migrating to (equal to the current <see cref="StoreVersion"/>).</param>
|
||||
protected override void PerformMigration(int currentVersion, int targetVersion)
|
||||
{
|
||||
base.PerformMigration(currentVersion, newVersion);
|
||||
base.PerformMigration(currentVersion, targetVersion);
|
||||
|
||||
while (currentVersion++ < newVersion)
|
||||
while (currentVersion++ < targetVersion)
|
||||
{
|
||||
switch (currentVersion)
|
||||
{
|
||||
case 1:
|
||||
// initialising from a version before we had versioning (or a fresh install).
|
||||
|
||||
// force adding of Protected column (not automatically migrated).
|
||||
Connection.MigrateTable<BeatmapSetInfo>();
|
||||
|
||||
// remove all existing beatmaps.
|
||||
foreach (var b in Connection.GetAllWithChildren<BeatmapSetInfo>(null, true))
|
||||
Connection.Delete(b, true);
|
||||
case 2:
|
||||
// cannot migrate; breaking underlying changes.
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -51,14 +51,30 @@ namespace osu.Game.Database
|
||||
PerformMigration(reportedVersion.Version, reportedVersion.Version = StoreVersion);
|
||||
|
||||
Connection.InsertOrReplace(reportedVersion);
|
||||
|
||||
StartupTasks();
|
||||
}
|
||||
|
||||
protected virtual void PerformMigration(int currentVersion, int newVersion)
|
||||
/// <summary>
|
||||
/// Called when the database version of this store doesn't match the local version.
|
||||
/// Any manual migration operations should be performed in this.
|
||||
/// </summary>
|
||||
/// <param name="currentVersion">The current store version. This will be zero on a fresh database initialisation.</param>
|
||||
/// <param name="targetVersion">The target version which we are migrating to (equal to the current <see cref="StoreVersion"/>).</param>
|
||||
protected virtual void PerformMigration(int currentVersion, int targetVersion)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare this database for use.
|
||||
/// Perform any common startup tasks. Runs after <see cref="Prepare(bool)"/> and <see cref="PerformMigration(int, int)"/>.
|
||||
/// </summary>
|
||||
protected virtual void StartupTasks()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare this database for use. Tables should be created here.
|
||||
/// </summary>
|
||||
protected abstract void Prepare(bool reset = false);
|
||||
|
||||
@ -101,7 +117,6 @@ namespace osu.Game.Database
|
||||
public void Populate<T>(T item, bool recursive = true)
|
||||
{
|
||||
checkType(item.GetType());
|
||||
|
||||
Connection.GetChildren(item, recursive);
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,6 @@ namespace osu.Game.IO
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int ID { get; set; }
|
||||
|
||||
public string Filename { get; set; }
|
||||
|
||||
[Indexed(Unique = true)]
|
||||
public string Hash { get; set; }
|
||||
|
||||
|
@ -23,6 +23,8 @@ namespace osu.Game.IO
|
||||
|
||||
public readonly ResourceStore<byte[]> Store;
|
||||
|
||||
protected override int StoreVersion => 2;
|
||||
|
||||
public FileStore(SQLiteConnection connection, Storage storage) : base(connection, storage)
|
||||
{
|
||||
Store = new NamespacedResourceStore<byte[]>(new StorageBackedResourceStore(storage), prefix);
|
||||
@ -35,22 +37,53 @@ namespace osu.Game.IO
|
||||
protected override void Prepare(bool reset = false)
|
||||
{
|
||||
if (reset)
|
||||
{
|
||||
// in earlier versions we stored beatmaps as solid archives, but not any more.
|
||||
if (Storage.ExistsDirectory("beatmaps"))
|
||||
Storage.DeleteDirectory("beatmaps");
|
||||
|
||||
if (Storage.ExistsDirectory(prefix))
|
||||
Storage.DeleteDirectory(prefix);
|
||||
|
||||
Connection.DropTable<FileInfo>();
|
||||
}
|
||||
|
||||
Connection.CreateTable<FileInfo>();
|
||||
}
|
||||
|
||||
protected override void StartupTasks()
|
||||
{
|
||||
base.StartupTasks();
|
||||
deletePending();
|
||||
}
|
||||
|
||||
public FileInfo Add(Stream data, string filename = null)
|
||||
/// <summary>
|
||||
/// Perform migrations between two store versions.
|
||||
/// </summary>
|
||||
/// <param name="currentVersion">The current store version. This will be zero on a fresh database initialisation.</param>
|
||||
/// <param name="targetVersion">The target version which we are migrating to (equal to the current <see cref="StoreVersion"/>).</param>
|
||||
protected override void PerformMigration(int currentVersion, int targetVersion)
|
||||
{
|
||||
base.PerformMigration(currentVersion, targetVersion);
|
||||
|
||||
while (currentVersion++ < targetVersion)
|
||||
{
|
||||
switch (currentVersion)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
// cannot migrate; breaking underlying changes.
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FileInfo Add(Stream data)
|
||||
{
|
||||
string hash = data.ComputeSHA2Hash();
|
||||
|
||||
var info = new FileInfo
|
||||
{
|
||||
Filename = filename,
|
||||
Hash = hash,
|
||||
};
|
||||
var info = new FileInfo { Hash = hash };
|
||||
|
||||
var existing = Connection.Table<FileInfo>().FirstOrDefault(f => f.Hash == info.Hash);
|
||||
|
||||
@ -79,20 +112,32 @@ namespace osu.Game.IO
|
||||
|
||||
public void Reference(IEnumerable<FileInfo> files)
|
||||
{
|
||||
foreach (var f in files)
|
||||
Connection.RunInTransaction(() =>
|
||||
{
|
||||
f.ReferenceCount++;
|
||||
Connection.Update(f);
|
||||
}
|
||||
var incrementedFiles = files.GroupBy(f => f.ID).Select(f =>
|
||||
{
|
||||
var accurateRefCount = Connection.Get<FileInfo>(f.First().ID);
|
||||
accurateRefCount.ReferenceCount += f.Count();
|
||||
return accurateRefCount;
|
||||
});
|
||||
|
||||
Connection.UpdateAll(incrementedFiles);
|
||||
});
|
||||
}
|
||||
|
||||
public void Dereference(IEnumerable<FileInfo> files)
|
||||
{
|
||||
foreach (var f in files)
|
||||
Connection.RunInTransaction(() =>
|
||||
{
|
||||
f.ReferenceCount--;
|
||||
Connection.Update(f);
|
||||
}
|
||||
var incrementedFiles = files.GroupBy(f => f.ID).Select(f =>
|
||||
{
|
||||
var accurateRefCount = Connection.Get<FileInfo>(f.First().ID);
|
||||
accurateRefCount.ReferenceCount -= f.Count();
|
||||
return accurateRefCount;
|
||||
});
|
||||
|
||||
Connection.UpdateAll(incrementedFiles);
|
||||
});
|
||||
}
|
||||
|
||||
private void deletePending()
|
||||
@ -102,7 +147,7 @@ namespace osu.Game.IO
|
||||
try
|
||||
{
|
||||
Connection.Delete(f);
|
||||
Storage.Delete(Path.Combine(prefix, f.Hash));
|
||||
Storage.Delete(Path.Combine(prefix, f.StoragePath));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user