1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 09:07:25 +08:00

Add EF to realm beatmap migration

This commit is contained in:
Dean Herbert 2022-01-13 18:02:08 +09:00
parent 45a23e5a43
commit b610d2db12
2 changed files with 115 additions and 13 deletions

View File

@ -41,7 +41,7 @@ namespace osu.Game.Beatmaps
public BeatmapOnlineStatus Status { get; set; } = BeatmapOnlineStatus.None; public BeatmapOnlineStatus Status { get; set; } = BeatmapOnlineStatus.None;
[Required] [Required]
public EFBeatmapSetInfo BeatmapSet { get; set; } public EFBeatmapSetInfo BeatmapSetInfo { get; set; }
public EFBeatmapMetadata Metadata { get; set; } public EFBeatmapMetadata Metadata { get; set; }
@ -85,9 +85,10 @@ namespace osu.Game.Beatmaps
public float StackLeniency { get; set; } = 0.7f; public float StackLeniency { get; set; } = 0.7f;
public bool SpecialStyle { get; set; } public bool SpecialStyle { get; set; }
public int RulesetID { get; set; } [Column("RulesetID")]
public int RulesetInfoID { get; set; }
public EFRulesetInfo Ruleset { get; set; } public EFRulesetInfo RulesetInfo { get; set; }
public bool LetterboxInBreaks { get; set; } public bool LetterboxInBreaks { get; set; }
public bool WidescreenStoryboard { get; set; } public bool WidescreenStoryboard { get; set; }
@ -145,13 +146,13 @@ namespace osu.Game.Beatmaps
public bool Equals(IBeatmapInfo other) => other is EFBeatmapInfo b && Equals(b); public bool Equals(IBeatmapInfo other) => other is EFBeatmapInfo b && Equals(b);
public bool AudioEquals(EFBeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && public bool AudioEquals(EFBeatmapInfo other) => other != null && BeatmapSetInfo != null && other.BeatmapSetInfo != null &&
BeatmapSet.Hash == other.BeatmapSet.Hash && BeatmapSetInfo.Hash == other.BeatmapSetInfo.Hash &&
(Metadata ?? BeatmapSet.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSet.Metadata).AudioFile; (Metadata ?? BeatmapSetInfo.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSetInfo.Metadata).AudioFile;
public bool BackgroundEquals(EFBeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && public bool BackgroundEquals(EFBeatmapInfo other) => other != null && BeatmapSetInfo != null && other.BeatmapSetInfo != null &&
BeatmapSet.Hash == other.BeatmapSet.Hash && BeatmapSetInfo.Hash == other.BeatmapSetInfo.Hash &&
(Metadata ?? BeatmapSet.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSet.Metadata).BackgroundFile; (Metadata ?? BeatmapSetInfo.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSetInfo.Metadata).BackgroundFile;
/// <summary> /// <summary>
/// Returns a shallow-clone of this <see cref="EFBeatmapInfo"/>. /// Returns a shallow-clone of this <see cref="EFBeatmapInfo"/>.
@ -167,16 +168,16 @@ namespace osu.Game.Beatmaps
#region Implementation of IBeatmapInfo #region Implementation of IBeatmapInfo
[JsonIgnore] [JsonIgnore]
IBeatmapMetadataInfo IBeatmapInfo.Metadata => Metadata ?? BeatmapSet?.Metadata ?? new EFBeatmapMetadata(); IBeatmapMetadataInfo IBeatmapInfo.Metadata => Metadata ?? BeatmapSetInfo?.Metadata ?? new EFBeatmapMetadata();
[JsonIgnore] [JsonIgnore]
IBeatmapDifficultyInfo IBeatmapInfo.Difficulty => BaseDifficulty; IBeatmapDifficultyInfo IBeatmapInfo.Difficulty => BaseDifficulty;
[JsonIgnore] [JsonIgnore]
IBeatmapSetInfo IBeatmapInfo.BeatmapSet => BeatmapSet; IBeatmapSetInfo IBeatmapInfo.BeatmapSet => BeatmapSetInfo;
[JsonIgnore] [JsonIgnore]
IRulesetInfo IBeatmapInfo.Ruleset => Ruleset; IRulesetInfo IBeatmapInfo.Ruleset => RulesetInfo;
#endregion #endregion
} }

View File

@ -35,10 +35,111 @@ namespace osu.Game.Database
migrateSettings(db); migrateSettings(db);
migrateSkins(db); migrateSkins(db);
migrateBeatmaps(db);
migrateScores(db); migrateScores(db);
} }
} }
private void migrateBeatmaps(DatabaseWriteUsage db)
{
// can be removed 20220730.
var existingBeatmapSets = db.Context.EFBeatmapSetInfo
.Include(s => s.Beatmaps).ThenInclude(b => b.RulesetInfo)
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
.Include(s => s.Files).ThenInclude(f => f.FileInfo)
.ToList();
// previous entries in EF are removed post migration.
if (!existingBeatmapSets.Any())
return;
using (var realm = realmContextFactory.CreateContext())
using (var transaction = realm.BeginWrite())
{
// only migrate data if the realm database is empty.
// note that this cannot be written as: `realm.All<BeatmapInfo>().All(s => s.Protected)`, because realm does not support `.All()`.
if (!realm.All<BeatmapSetInfo>().Any(s => !s.Protected))
{
foreach (var beatmapSet in existingBeatmapSets)
{
var realmBeatmapSet = new BeatmapSetInfo
{
OnlineID = beatmapSet.OnlineID ?? -1,
DateAdded = beatmapSet.DateAdded,
Status = beatmapSet.Status,
DeletePending = beatmapSet.DeletePending,
Hash = beatmapSet.Hash,
Protected = beatmapSet.Protected,
};
migrateFiles(beatmapSet, realm, realmBeatmapSet);
foreach (var beatmap in beatmapSet.Beatmaps)
{
var realmBeatmap = new BeatmapInfo
{
DifficultyName = beatmap.DifficultyName,
Status = beatmap.Status,
OnlineID = beatmap.OnlineID ?? -1,
Length = beatmap.Length,
BPM = beatmap.BPM,
Hash = beatmap.Hash,
StarRating = beatmap.StarRating,
MD5Hash = beatmap.MD5Hash,
Hidden = beatmap.Hidden,
AudioLeadIn = beatmap.AudioLeadIn,
StackLeniency = beatmap.StackLeniency,
SpecialStyle = beatmap.SpecialStyle,
LetterboxInBreaks = beatmap.LetterboxInBreaks,
WidescreenStoryboard = beatmap.WidescreenStoryboard,
EpilepsyWarning = beatmap.EpilepsyWarning,
SamplesMatchPlaybackRate = beatmap.SamplesMatchPlaybackRate,
DistanceSpacing = beatmap.DistanceSpacing,
BeatDivisor = beatmap.BeatDivisor,
GridSize = beatmap.GridSize,
TimelineZoom = beatmap.TimelineZoom,
Countdown = beatmap.Countdown,
CountdownOffset = beatmap.CountdownOffset,
MaxCombo = beatmap.MaxCombo,
Bookmarks = beatmap.Bookmarks,
Ruleset = realm.Find<RulesetInfo>(beatmap.RulesetInfo.ShortName),
Difficulty = new BeatmapDifficulty(beatmap.BaseDifficulty),
Metadata = new BeatmapMetadata
{
Title = beatmap.Metadata.Title,
TitleUnicode = beatmap.Metadata.TitleUnicode,
Artist = beatmap.Metadata.Artist,
ArtistUnicode = beatmap.Metadata.ArtistUnicode,
Author = new RealmUser
{
OnlineID = beatmap.Metadata.Author.Id,
Username = beatmap.Metadata.Author.Username,
},
Source = beatmap.Metadata.Source,
Tags = beatmap.Metadata.Tags,
PreviewTime = beatmap.Metadata.PreviewTime,
AudioFile = beatmap.Metadata.AudioFile,
BackgroundFile = beatmap.Metadata.BackgroundFile,
AuthorString = beatmap.Metadata.AuthorString,
},
BeatmapSet = realmBeatmapSet,
};
realmBeatmapSet.Beatmaps.Add(realmBeatmap);
}
realm.Add(realmBeatmapSet);
}
}
// db.Context.RemoveRange(existingBeatmapSets);
// Intentionally don't clean up the files, so they don't get purged by EF.
transaction.Commit();
}
}
private void migrateScores(DatabaseWriteUsage db) private void migrateScores(DatabaseWriteUsage db)
{ {
// can be removed 20220730. // can be removed 20220730.
@ -94,7 +195,7 @@ namespace osu.Game.Database
} }
} }
db.Context.RemoveRange(existingScores); // db.Context.RemoveRange(existingScores);
// Intentionally don't clean up the files, so they don't get purged by EF. // Intentionally don't clean up the files, so they don't get purged by EF.
transaction.Commit(); transaction.Commit();