1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-18 10:31:41 +08:00

Merge pull request #19027 from peppy/realm-nested-writes

Add nested transaction handling to realm helper methods
This commit is contained in:
Dan Balasescu
2022-07-07 19:40:08 +09:00
committed by GitHub
Unverified
2 changed files with 106 additions and 7 deletions
+58
View File
@@ -59,6 +59,64 @@ namespace osu.Game.Tests.Database
});
}
[Test]
public void TestFailedWritePerformsRollback()
{
RunTestWithRealm((realm, _) =>
{
Assert.Throws<InvalidOperationException>(() =>
{
realm.Write(r =>
{
r.Add(new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata()));
throw new InvalidOperationException();
});
});
Assert.That(realm.Run(r => r.All<BeatmapInfo>()), Is.Empty);
});
}
[Test]
public void TestFailedNestedWritePerformsRollback()
{
RunTestWithRealm((realm, _) =>
{
Assert.Throws<InvalidOperationException>(() =>
{
realm.Write(r =>
{
realm.Write(_ =>
{
r.Add(new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata()));
throw new InvalidOperationException();
});
});
});
Assert.That(realm.Run(r => r.All<BeatmapInfo>()), Is.Empty);
});
}
[Test]
public void TestNestedWriteCalls()
{
RunTestWithRealm((realm, _) =>
{
var beatmap = new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata());
var liveBeatmap = beatmap.ToLive(realm);
realm.Run(r =>
r.Write(_ =>
r.Write(_ =>
r.Add(beatmap)))
);
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
});
}
[Test]
public void TestAccessAfterAttach()
{
+48 -7
View File
@@ -8,19 +8,60 @@ namespace osu.Game.Database
{
public static class RealmExtensions
{
/// <summary>
/// Perform a write operation against the provided realm instance.
/// </summary>
/// <remarks>
/// This will automatically start a transaction if not already in one.
/// </remarks>
/// <param name="realm">The realm to operate on.</param>
/// <param name="function">The write operation to run.</param>
public static void Write(this Realm realm, Action<Realm> function)
{
using var transaction = realm.BeginWrite();
function(realm);
transaction.Commit();
Transaction? transaction = null;
try
{
if (!realm.IsInTransaction)
transaction = realm.BeginWrite();
function(realm);
transaction?.Commit();
}
finally
{
transaction?.Dispose();
}
}
/// <summary>
/// Perform a write operation against the provided realm instance.
/// </summary>
/// <remarks>
/// This will automatically start a transaction if not already in one.
/// </remarks>
/// <param name="realm">The realm to operate on.</param>
/// <param name="function">The write operation to run.</param>
public static T Write<T>(this Realm realm, Func<Realm, T> function)
{
using var transaction = realm.BeginWrite();
var result = function(realm);
transaction.Commit();
return result;
Transaction? transaction = null;
try
{
if (!realm.IsInTransaction)
transaction = realm.BeginWrite();
var result = function(realm);
transaction?.Commit();
return result;
}
finally
{
transaction?.Dispose();
}
}
/// <summary>