From 84a3fbd25cb29bc41a976810200d4a30ec8a11e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Aug 2022 17:36:48 +0900 Subject: [PATCH 1/4] Version realm files for debug executions To make it easier for developers to test out pull requests which bump the realm schema version, realm files are now stored with the schema version in the filename. Note that this means any changes made to a newer version will not be applied to previous ones. --- osu.Game/Database/RealmAccess.cs | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 5f0ec67c71..9e964750a8 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -172,6 +172,10 @@ namespace osu.Game.Database if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal)) Filename += realm_extension; +#if DEBUG + Filename = applyFilenameSchemaSuffix(Filename); +#endif + string newerVersionFilename = $"{Filename.Replace(realm_extension, string.Empty)}_newer_version{realm_extension}"; // Attempt to recover a newer database version if available. @@ -211,6 +215,50 @@ namespace osu.Game.Database } } + /// + /// Some developers may be annoyed if a newer version migration (ie. caused by testing a pull request) + /// cause their test database to be unusable with previous versions. + /// To get around this, store development databases against their realm version. + /// Note that this means changes made on newer realm versions will disappear. + /// + private string applyFilenameSchemaSuffix(string filename) + { + string proposedFilename = getVersionedFilename(schema_version); + + // First check if the current realm version already exists... + if (storage.Exists(proposedFilename)) + return proposedFilename; + + // If a non-versioned file exists (aka before this method was added), move it to the new versioned + // format. + if (storage.Exists(filename)) + { + Logger.Log(@$"Moving non-versioned realm file {filename} to {proposedFilename}"); + storage.Move(filename, proposedFilename); + return proposedFilename; + } + + // If it doesn't, check for a previous version we can use as a base database to migrate from... + for (int i = schema_version - 1; i >= 0; i--) + { + string iFilename = getVersionedFilename(i); + + if (storage.Exists(iFilename)) + { + using (var previous = storage.GetStream(iFilename)) + using (var current = storage.CreateFileSafely(proposedFilename)) + { + Logger.Log(@$"Using previous realm database {iFilename} to migrate new schema version {schema_version}"); + previous.CopyTo(current); + } + } + } + + return proposedFilename; + + string getVersionedFilename(int version) => filename.Replace(realm_extension, $"_{version}{realm_extension}"); + } + private void attemptRecoverFromFile(string recoveryFilename) { Logger.Log($@"Performing recovery from {recoveryFilename}", LoggingTarget.Database); From 3c84b1a389905ec61295afee2e284f27975b69ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Aug 2022 17:48:51 +0900 Subject: [PATCH 2/4] Change order of application to use original `client.realm` last --- osu.Game/Database/RealmAccess.cs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 9e964750a8..65cad5bdf0 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -173,7 +173,7 @@ namespace osu.Game.Database Filename += realm_extension; #if DEBUG - Filename = applyFilenameSchemaSuffix(Filename); + applyFilenameSchemaSuffix(ref Filename); #endif string newerVersionFilename = $"{Filename.Replace(realm_extension, string.Empty)}_newer_version{realm_extension}"; @@ -221,24 +221,17 @@ namespace osu.Game.Database /// To get around this, store development databases against their realm version. /// Note that this means changes made on newer realm versions will disappear. /// - private string applyFilenameSchemaSuffix(string filename) + private void applyFilenameSchemaSuffix(ref string filename) { - string proposedFilename = getVersionedFilename(schema_version); + string originalFilename = filename; + + filename = getVersionedFilename(schema_version); // First check if the current realm version already exists... - if (storage.Exists(proposedFilename)) - return proposedFilename; - - // If a non-versioned file exists (aka before this method was added), move it to the new versioned - // format. if (storage.Exists(filename)) - { - Logger.Log(@$"Moving non-versioned realm file {filename} to {proposedFilename}"); - storage.Move(filename, proposedFilename); - return proposedFilename; - } + return; - // If it doesn't, check for a previous version we can use as a base database to migrate from... + // Check for a previous version we can use as a base database to migrate from... for (int i = schema_version - 1; i >= 0; i--) { string iFilename = getVersionedFilename(i); @@ -246,7 +239,7 @@ namespace osu.Game.Database if (storage.Exists(iFilename)) { using (var previous = storage.GetStream(iFilename)) - using (var current = storage.CreateFileSafely(proposedFilename)) + using (var current = storage.CreateFileSafely(filename)) { Logger.Log(@$"Using previous realm database {iFilename} to migrate new schema version {schema_version}"); previous.CopyTo(current); @@ -254,9 +247,14 @@ namespace osu.Game.Database } } - return proposedFilename; + // Finally, check for a non-versioned file exists (aka before this method was added)... + if (storage.Exists(originalFilename)) + { + Logger.Log(@$"Moving non-versioned realm file {filename} to {filename}"); + storage.Move(filename, filename); + } - string getVersionedFilename(int version) => filename.Replace(realm_extension, $"_{version}{realm_extension}"); + string getVersionedFilename(int version) => originalFilename.Replace(realm_extension, $"_{version}{realm_extension}"); } private void attemptRecoverFromFile(string recoveryFilename) From ad3d00b1dc5f28c095931cd40c506ddcc580a6df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Aug 2022 18:23:41 +0900 Subject: [PATCH 3/4] Don't add version suffixes when running unit tests --- osu.Game/Database/RealmAccess.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 65cad5bdf0..e31c121a9d 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -173,7 +173,8 @@ namespace osu.Game.Database Filename += realm_extension; #if DEBUG - applyFilenameSchemaSuffix(ref Filename); + if (!DebugUtils.IsNUnitRunning) + applyFilenameSchemaSuffix(ref Filename); #endif string newerVersionFilename = $"{Filename.Replace(realm_extension, string.Empty)}_newer_version{realm_extension}"; From 4544df59785e793286ee2a8e195ba7974c428704 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Aug 2022 18:27:29 +0900 Subject: [PATCH 4/4] Leave `client.realm` around to handle pull requests without this change merged --- osu.Game/Database/RealmAccess.cs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index e31c121a9d..83a007e4ff 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -235,24 +235,27 @@ namespace osu.Game.Database // Check for a previous version we can use as a base database to migrate from... for (int i = schema_version - 1; i >= 0; i--) { - string iFilename = getVersionedFilename(i); + string previousFilename = getVersionedFilename(i); - if (storage.Exists(iFilename)) + if (storage.Exists(previousFilename)) { - using (var previous = storage.GetStream(iFilename)) - using (var current = storage.CreateFileSafely(filename)) - { - Logger.Log(@$"Using previous realm database {iFilename} to migrate new schema version {schema_version}"); - previous.CopyTo(current); - } + copyPreviousVersion(previousFilename, filename); + return; } } // Finally, check for a non-versioned file exists (aka before this method was added)... if (storage.Exists(originalFilename)) + copyPreviousVersion(originalFilename, filename); + + void copyPreviousVersion(string previousFilename, string newFilename) { - Logger.Log(@$"Moving non-versioned realm file {filename} to {filename}"); - storage.Move(filename, filename); + using (var previous = storage.GetStream(previousFilename)) + using (var current = storage.CreateFileSafely(newFilename)) + { + Logger.Log(@$"Copying previous realm database {previousFilename} to {newFilename} for migration to schema version {schema_version}"); + previous.CopyTo(current); + } } string getVersionedFilename(int version) => originalFilename.Replace(realm_extension, $"_{version}{realm_extension}");