diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs index 99eb038b2d..d0ca2f0fd4 100644 --- a/osu.Game/Database/RealmContextFactory.cs +++ b/osu.Game/Database/RealmContextFactory.cs @@ -95,7 +95,12 @@ namespace osu.Game.Database if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal)) Filename += realm_extension; + // This method triggers the first `CreateContext` call, which will implicitly run realm migrations and bring the schema up-to-date. cleanupPendingDeletions(); + + // Data migration is handled separately from schema migrations. + // This is required as the user may be initialising realm for the first time ever, which would result in no schema migrations running. + migrateDataFromEF(); } private void cleanupPendingDeletions() @@ -163,6 +168,53 @@ namespace osu.Game.Database }; } + private void migrateDataFromEF() + { + if (efContextFactory == null) + return; + + using (var db = efContextFactory.GetForWrite()) + { + // migrate ruleset settings. can be removed 20220315. + var existingSettings = db.Context.DatabasedSetting; + + // previous entries in EF are removed post migration. + if (!existingSettings.Any()) + return; + + using (var realm = CreateContext()) + using (var transaction = realm.BeginWrite()) + { + // only migrate data if the realm database is empty. + if (!realm.All().Any()) + { + foreach (var dkb in existingSettings) + { + if (dkb.RulesetID == null) + continue; + + string? shortName = getRulesetShortNameFromLegacyID(dkb.RulesetID.Value); + + if (string.IsNullOrEmpty(shortName)) + continue; + + realm.Add(new RealmRulesetSetting + { + Key = dkb.Key, + Value = dkb.StringValue, + RulesetName = shortName, + Variant = dkb.Variant ?? 0, + }); + } + } + + db.Context.RemoveRange(existingSettings); + + transaction.Commit(); + } + } + } + private void onMigration(Migration migration, ulong lastSchemaVersion) { for (ulong i = lastSchemaVersion + 1; i <= schema_version; i++) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 1f2dbf1054..dd4ae590c7 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -262,8 +262,6 @@ namespace osu.Game dependencies.Cache(scorePerformanceManager); AddInternal(scorePerformanceManager); - migrateDataToRealm(); - dependencies.Cache(rulesetConfigCache = new RulesetConfigCache(realmFactory, RulesetStore)); var powerStatus = CreateBatteryInfo(); @@ -439,35 +437,6 @@ namespace osu.Game private void migrateDataToRealm() { - using (var db = contextFactory.GetForWrite()) - using (var realm = realmFactory.CreateContext()) - using (var transaction = realm.BeginWrite()) - { - // migrate ruleset settings. can be removed 20220315. - var existingSettings = db.Context.DatabasedSetting; - - // only migrate data if the realm database is empty. - if (!realm.All().Any()) - { - foreach (var dkb in existingSettings) - { - if (dkb.RulesetID == null) continue; - - realm.Add(new RealmRulesetSetting - { - Key = dkb.Key, - Value = dkb.StringValue, - // important: this RulesetStore must be the EF one. - RulesetName = RulesetStore.GetRuleset(dkb.RulesetID.Value).ShortName, - Variant = dkb.Variant ?? 0, - }); - } - } - - db.Context.RemoveRange(existingSettings); - - transaction.Commit(); - } } private void onRulesetChanged(ValueChangedEvent r) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 3fac94b243..a96f64cdc3 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -311,6 +311,7 @@ AABB API BPM + EF FPS GC GL