From 487b888f4fdd41de533c0ceca43865ba3b75d9c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 25 Oct 2017 15:51:39 +0900 Subject: [PATCH 1/2] Add missing database indices Also add missing unique constraints where applicable. --- osu.Game/Database/OsuDbContext.cs | 7 +- ...025071459_AddMissingIndexRules.Designer.cs | 299 ++++++++++++++++++ .../20171025071459_AddMissingIndexRules.cs | 82 +++++ .../Migrations/OsuDbContextModelSnapshot.cs | 12 +- osu.Game/osu.Game.csproj | 4 + 5 files changed, 398 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Migrations/20171025071459_AddMissingIndexRules.Designer.cs create mode 100644 osu.Game/Migrations/20171025071459_AddMissingIndexRules.cs diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs index be58319a56..cb2bdf5c9f 100644 --- a/osu.Game/Database/OsuDbContext.cs +++ b/osu.Game/Database/OsuDbContext.cs @@ -78,11 +78,12 @@ namespace osu.Game.Database { base.OnModelCreating(modelBuilder); - modelBuilder.Entity().HasIndex(b => b.MD5Hash); - modelBuilder.Entity().HasIndex(b => b.Hash); + modelBuilder.Entity().HasIndex(b => b.MD5Hash).IsUnique(); + modelBuilder.Entity().HasIndex(b => b.Hash).IsUnique(); + modelBuilder.Entity().HasIndex(b => b.OnlineBeatmapSetID).IsUnique(); modelBuilder.Entity().HasIndex(b => b.DeletePending); - modelBuilder.Entity().HasIndex(b => b.Hash); + modelBuilder.Entity().HasIndex(b => b.Hash).IsUnique(); modelBuilder.Entity().HasIndex(b => b.Variant); modelBuilder.Entity().HasIndex(b => b.IntAction); diff --git a/osu.Game/Migrations/20171025071459_AddMissingIndexRules.Designer.cs b/osu.Game/Migrations/20171025071459_AddMissingIndexRules.Designer.cs new file mode 100644 index 0000000000..478f27e82c --- /dev/null +++ b/osu.Game/Migrations/20171025071459_AddMissingIndexRules.Designer.cs @@ -0,0 +1,299 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using osu.Game.Database; +using System; + +namespace osu.Game.Migrations +{ + [DbContext(typeof(OsuDbContext))] + [Migration("20171025071459_AddMissingIndexRules")] + partial class AddMissingIndexRules + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.0.0-rtm-26452"); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("ApproachRate"); + + b.Property("CircleSize"); + + b.Property("DrainRate"); + + b.Property("OverallDifficulty"); + + b.Property("SliderMultiplier"); + + b.Property("SliderTickRate"); + + b.HasKey("ID"); + + b.ToTable("BeatmapDifficulty"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("AudioLeadIn"); + + b.Property("BaseDifficultyID"); + + b.Property("BeatDivisor"); + + b.Property("BeatmapSetInfoID"); + + b.Property("Countdown"); + + b.Property("DistanceSpacing"); + + b.Property("GridSize"); + + b.Property("Hash"); + + b.Property("Hidden"); + + b.Property("LetterboxInBreaks"); + + b.Property("MD5Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapID"); + + b.Property("Path"); + + b.Property("RulesetID"); + + b.Property("SpecialStyle"); + + b.Property("StackLeniency"); + + b.Property("StarDifficulty"); + + b.Property("StoredBookmarks"); + + b.Property("TimelineZoom"); + + b.Property("Version"); + + b.Property("WidescreenStoryboard"); + + b.HasKey("ID"); + + b.HasIndex("BaseDifficultyID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("MD5Hash") + .IsUnique(); + + b.HasIndex("MetadataID"); + + b.HasIndex("RulesetID"); + + b.ToTable("BeatmapInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Artist"); + + b.Property("ArtistUnicode"); + + b.Property("AudioFile"); + + b.Property("AuthorString") + .HasColumnName("Author"); + + b.Property("BackgroundFile"); + + b.Property("PreviewTime"); + + b.Property("Source"); + + b.Property("Tags"); + + b.Property("Title"); + + b.Property("TitleUnicode"); + + b.HasKey("ID"); + + b.ToTable("BeatmapMetadata"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("BeatmapSetInfoID"); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.HasKey("ID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("FileInfoID"); + + b.ToTable("BeatmapSetFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapSetID"); + + b.Property("Protected"); + + b.HasKey("ID"); + + b.HasIndex("DeletePending"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapSetID") + .IsUnique(); + + b.ToTable("BeatmapSetInfo"); + }); + + modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntAction") + .HasColumnName("Action"); + + b.Property("KeysString") + .HasColumnName("Keys"); + + b.Property("RulesetID"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("IntAction"); + + b.HasIndex("Variant"); + + b.ToTable("KeyBinding"); + }); + + modelBuilder.Entity("osu.Game.IO.FileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Hash"); + + b.Property("ReferenceCount"); + + b.HasKey("ID"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("ReferenceCount"); + + b.ToTable("FileInfo"); + }); + + modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Available"); + + b.Property("InstantiationInfo"); + + b.Property("Name"); + + b.HasKey("ID"); + + b.HasIndex("Available"); + + b.ToTable("RulesetInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty") + .WithMany() + .HasForeignKey("BaseDifficultyID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet") + .WithMany("Beatmaps") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("Beatmaps") + .HasForeignKey("MetadataID"); + + b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") + .WithMany() + .HasForeignKey("RulesetID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo") + .WithMany("Files") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("BeatmapSets") + .HasForeignKey("MetadataID"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/osu.Game/Migrations/20171025071459_AddMissingIndexRules.cs b/osu.Game/Migrations/20171025071459_AddMissingIndexRules.cs new file mode 100644 index 0000000000..a20652eedc --- /dev/null +++ b/osu.Game/Migrations/20171025071459_AddMissingIndexRules.cs @@ -0,0 +1,82 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; +using System.Collections.Generic; + +namespace osu.Game.Migrations +{ + public partial class AddMissingIndexRules : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_BeatmapSetInfo_Hash", + table: "BeatmapSetInfo"); + + migrationBuilder.DropIndex( + name: "IX_BeatmapInfo_Hash", + table: "BeatmapInfo"); + + migrationBuilder.DropIndex( + name: "IX_BeatmapInfo_MD5Hash", + table: "BeatmapInfo"); + + migrationBuilder.CreateIndex( + name: "IX_BeatmapSetInfo_Hash", + table: "BeatmapSetInfo", + column: "Hash", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_BeatmapSetInfo_OnlineBeatmapSetID", + table: "BeatmapSetInfo", + column: "OnlineBeatmapSetID", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_BeatmapInfo_Hash", + table: "BeatmapInfo", + column: "Hash", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_BeatmapInfo_MD5Hash", + table: "BeatmapInfo", + column: "MD5Hash", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_BeatmapSetInfo_Hash", + table: "BeatmapSetInfo"); + + migrationBuilder.DropIndex( + name: "IX_BeatmapSetInfo_OnlineBeatmapSetID", + table: "BeatmapSetInfo"); + + migrationBuilder.DropIndex( + name: "IX_BeatmapInfo_Hash", + table: "BeatmapInfo"); + + migrationBuilder.DropIndex( + name: "IX_BeatmapInfo_MD5Hash", + table: "BeatmapInfo"); + + migrationBuilder.CreateIndex( + name: "IX_BeatmapSetInfo_Hash", + table: "BeatmapSetInfo", + column: "Hash"); + + migrationBuilder.CreateIndex( + name: "IX_BeatmapInfo_Hash", + table: "BeatmapInfo", + column: "Hash"); + + migrationBuilder.CreateIndex( + name: "IX_BeatmapInfo_MD5Hash", + table: "BeatmapInfo", + column: "MD5Hash"); + } + } +} diff --git a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs index 0576242648..7029dcdcd5 100644 --- a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs +++ b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs @@ -95,9 +95,11 @@ namespace osu.Game.Migrations b.HasIndex("BeatmapSetInfoID"); - b.HasIndex("Hash"); + b.HasIndex("Hash") + .IsUnique(); - b.HasIndex("MD5Hash"); + b.HasIndex("MD5Hash") + .IsUnique(); b.HasIndex("MetadataID"); @@ -177,10 +179,14 @@ namespace osu.Game.Migrations b.HasIndex("DeletePending"); - b.HasIndex("Hash"); + b.HasIndex("Hash") + .IsUnique(); b.HasIndex("MetadataID"); + b.HasIndex("OnlineBeatmapSetID") + .IsUnique(); + b.ToTable("BeatmapSetInfo"); }); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8f519d8915..26c0751f91 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -286,6 +286,10 @@ 20171019041408_InitialCreate.cs + + + 20171025071459_AddMissingIndexRules.cs + From c30dc77b2801c4879f3cbfa65bff45ddba766ac2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 25 Oct 2017 22:25:28 +0900 Subject: [PATCH 2/2] Unique MD5s for unit test --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index a722974c07..37dd60a25c 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -3,8 +3,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Text; using osu.Framework.Allocation; +using osu.Framework.Extensions; using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Database; @@ -61,7 +64,7 @@ namespace osu.Game.Tests.Visual return new BeatmapSetInfo { OnlineBeatmapSetID = 1234 + i, - Hash = "d8e8fca2dc0f896fd7cb4cb0031ba249", + Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), Metadata = new BeatmapMetadata { OnlineBeatmapSetID = 1234 + i,