mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 00:40:09 +09:00
Move remaining realm classes out of Stores
namespace
This commit is contained in:
122
osu.Game/Database/RealmFileStore.cs
Normal file
122
osu.Game/Database/RealmFileStore.cs
Normal file
@ -0,0 +1,122 @@
|
||||
// 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.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
using Realms;
|
||||
|
||||
namespace osu.Game.Database
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles the storing of files to the file system (and database) backing.
|
||||
/// </summary>
|
||||
[ExcludeFromDynamicCompile]
|
||||
public class RealmFileStore
|
||||
{
|
||||
private readonly RealmAccess realm;
|
||||
|
||||
public readonly IResourceStore<byte[]> Store;
|
||||
|
||||
public readonly Storage Storage;
|
||||
|
||||
public RealmFileStore(RealmAccess realm, Storage storage)
|
||||
{
|
||||
this.realm = realm;
|
||||
|
||||
Storage = storage.GetStorageForDirectory(@"files");
|
||||
Store = new StorageBackedResourceStore(Storage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a new file to the game-wide database, copying it to permanent storage if not already present.
|
||||
/// </summary>
|
||||
/// <param name="data">The file data stream.</param>
|
||||
/// <param name="realm">The realm instance to add to. Should already be in a transaction.</param>
|
||||
/// <returns></returns>
|
||||
public RealmFile Add(Stream data, Realm realm)
|
||||
{
|
||||
string hash = data.ComputeSHA2Hash();
|
||||
|
||||
var existing = realm.Find<RealmFile>(hash);
|
||||
|
||||
var file = existing ?? new RealmFile { Hash = hash };
|
||||
|
||||
if (!checkFileExistsAndMatchesHash(file))
|
||||
copyToStore(file, data);
|
||||
|
||||
if (!file.IsManaged)
|
||||
realm.Add(file);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
private void copyToStore(RealmFile file, Stream data)
|
||||
{
|
||||
data.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (var output = Storage.CreateFileSafely(file.GetStoragePath()))
|
||||
data.CopyTo(output);
|
||||
|
||||
data.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
private bool checkFileExistsAndMatchesHash(RealmFile file)
|
||||
{
|
||||
string path = file.GetStoragePath();
|
||||
|
||||
// we may be re-adding a file to fix missing store entries.
|
||||
if (!Storage.Exists(path))
|
||||
return false;
|
||||
|
||||
// even if the file already exists, check the existing checksum for safety.
|
||||
using (var stream = Storage.GetStream(path))
|
||||
return stream.ComputeSHA2Hash() == file.Hash;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
Logger.Log(@"Beginning realm file store cleanup");
|
||||
|
||||
int totalFiles = 0;
|
||||
int removedFiles = 0;
|
||||
|
||||
// can potentially be run asynchronously, although we will need to consider operation order for disk deletion vs realm removal.
|
||||
realm.Write(r =>
|
||||
{
|
||||
// TODO: consider using a realm native query to avoid iterating all files (https://github.com/realm/realm-dotnet/issues/2659#issuecomment-927823707)
|
||||
var files = r.All<RealmFile>().ToList();
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
totalFiles++;
|
||||
|
||||
if (file.BacklinksCount > 0)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
removedFiles++;
|
||||
Storage.Delete(file.GetStoragePath());
|
||||
r.Remove(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, $@"Could not delete databased file {file.Hash}");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Logger.Log($@"Finished realm file store cleanup ({removedFiles} of {totalFiles} deleted)");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user