diff --git a/Jellyfin.Data/Entities/Permission.cs b/Jellyfin.Data/Entities/Permission.cs
index 2c58943181..6d2e68077c 100644
--- a/Jellyfin.Data/Entities/Permission.cs
+++ b/Jellyfin.Data/Entities/Permission.cs
@@ -37,7 +37,7 @@ namespace Jellyfin.Data.Entities
///
/// Gets or sets the id of the associated user.
///
- public Guid UserId { get; set; }
+ public Guid? UserId { get; set; }
///
/// Gets the type of this permission.
diff --git a/Jellyfin.Data/Entities/Preference.cs b/Jellyfin.Data/Entities/Preference.cs
index a7d93f32c6..a6ab275d31 100644
--- a/Jellyfin.Data/Entities/Preference.cs
+++ b/Jellyfin.Data/Entities/Preference.cs
@@ -35,7 +35,7 @@ namespace Jellyfin.Data.Entities
///
/// Gets or sets the id of the associated user.
///
- public Guid UserId { get; set; }
+ public Guid? UserId { get; set; }
///
/// Gets the type of this preference.
diff --git a/Jellyfin.Server.Implementations/JellyfinDb.cs b/Jellyfin.Server.Implementations/JellyfinDb.cs
index 499d99a502..db648472d1 100644
--- a/Jellyfin.Server.Implementations/JellyfinDb.cs
+++ b/Jellyfin.Server.Implementations/JellyfinDb.cs
@@ -184,6 +184,16 @@ namespace Jellyfin.Server.Implementations
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
+ modelBuilder.Entity()
+ .HasMany(u => u.ItemDisplayPreferences)
+ .WithOne()
+ .OnDelete(DeleteBehavior.Cascade);
+
+ modelBuilder.Entity()
+ .HasMany(d => d.HomeSections)
+ .WithOne()
+ .OnDelete(DeleteBehavior.Cascade);
+
// Indexes
modelBuilder.Entity()
diff --git a/Jellyfin.Server.Implementations/Migrations/20210320181425_AddIndexesAndCollations.Designer.cs b/Jellyfin.Server.Implementations/Migrations/20210320181425_AddIndexesAndCollations.Designer.cs
new file mode 100644
index 0000000000..8696768245
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20210320181425_AddIndexesAndCollations.Designer.cs
@@ -0,0 +1,535 @@
+#pragma warning disable CS1591
+
+//
+using System;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ [DbContext(typeof(JellyfinDb))]
+ [Migration("20210320181425_AddIndexesAndCollations")]
+ partial class AddIndexesAndCollations
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("jellyfin")
+ .HasAnnotation("ProductVersion", "5.0.3");
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("DayOfWeek")
+ .HasColumnType("INTEGER");
+
+ b.Property("EndHour")
+ .HasColumnType("REAL");
+
+ b.Property("StartHour")
+ .HasColumnType("REAL");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AccessSchedules");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("ItemId")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("Overview")
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("ShortOverview")
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ActivityLogs");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemDisplayPreferences", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "ItemId", "Client", "Key")
+ .IsUnique();
+
+ b.ToTable("CustomItemDisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChromecastVersion")
+ .HasColumnType("INTEGER");
+
+ b.Property("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("DashboardTheme")
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("EnableNextVideoInfoOverlay")
+ .HasColumnType("INTEGER");
+
+ b.Property("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property("ScrollDirection")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShowBackdrop")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShowSidebar")
+ .HasColumnType("INTEGER");
+
+ b.Property("SkipBackwardLength")
+ .HasColumnType("INTEGER");
+
+ b.Property("SkipForwardLength")
+ .HasColumnType("INTEGER");
+
+ b.Property("TvHome")
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "ItemId", "Client")
+ .IsUnique();
+
+ b.ToTable("DisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("DisplayPreferencesId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Order")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DisplayPreferencesId");
+
+ b.ToTable("HomeSection");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("LastModified")
+ .HasColumnType("TEXT");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ImageInfos");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property("RememberIndexing")
+ .HasColumnType("INTEGER");
+
+ b.Property("RememberSorting")
+ .HasColumnType("INTEGER");
+
+ b.Property("SortBy")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.Property("SortOrder")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("ViewType")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("ItemDisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property("Permission_Permissions_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "Kind")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
+
+ b.ToTable("Permissions");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property("Preference_Preferences_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(65535)
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "Kind")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
+
+ b.ToTable("Preferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("AudioLanguagePreference")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("AuthenticationProviderId")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("DisplayCollectionsView")
+ .HasColumnType("INTEGER");
+
+ b.Property("DisplayMissingEpisodes")
+ .HasColumnType("INTEGER");
+
+ b.Property("EasyPassword")
+ .HasMaxLength(65535)
+ .HasColumnType("TEXT");
+
+ b.Property("EnableAutoLogin")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnableLocalPassword")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnableNextEpisodeAutoPlay")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnableUserPreferenceAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property("HidePlayedInLatest")
+ .HasColumnType("INTEGER");
+
+ b.Property("InternalId")
+ .HasColumnType("INTEGER");
+
+ b.Property("InvalidLoginAttemptCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("LastActivityDate")
+ .HasColumnType("TEXT");
+
+ b.Property("LastLoginDate")
+ .HasColumnType("TEXT");
+
+ b.Property("LoginAttemptsBeforeLockout")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxActiveSessions")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxParentalAgeRating")
+ .HasColumnType("INTEGER");
+
+ b.Property("MustUpdatePassword")
+ .HasColumnType("INTEGER");
+
+ b.Property("Password")
+ .HasMaxLength(65535)
+ .HasColumnType("TEXT");
+
+ b.Property("PasswordResetProviderId")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("PlayDefaultAudioTrack")
+ .HasColumnType("INTEGER");
+
+ b.Property("RememberAudioSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property("RememberSubtitleSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property("RemoteClientBitrateLimit")
+ .HasColumnType("INTEGER");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("SubtitleLanguagePreference")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("SubtitleMode")
+ .HasColumnType("INTEGER");
+
+ b.Property("SyncPlayAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property("Username")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT")
+ .UseCollation("NOCASE");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Username")
+ .IsUnique();
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("AccessSchedules")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("DisplayPreferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.DisplayPreferences", null)
+ .WithMany("HomeSections")
+ .HasForeignKey("DisplayPreferencesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithOne("ProfileImage")
+ .HasForeignKey("Jellyfin.Data.Entities.ImageInfo", "UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("ItemDisplayPreferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Permissions")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Preferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.Navigation("HomeSections");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Navigation("AccessSchedules");
+
+ b.Navigation("DisplayPreferences");
+
+ b.Navigation("ItemDisplayPreferences");
+
+ b.Navigation("Permissions");
+
+ b.Navigation("Preferences");
+
+ b.Navigation("ProfileImage");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/20210320181425_AddIndexesAndCollations.cs b/Jellyfin.Server.Implementations/Migrations/20210320181425_AddIndexesAndCollations.cs
new file mode 100644
index 0000000000..506e4ae661
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20210320181425_AddIndexesAndCollations.cs
@@ -0,0 +1,240 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1601
+
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ public partial class AddIndexesAndCollations : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_ImageInfos_Users_UserId",
+ schema: "jellyfin",
+ table: "ImageInfos");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Permissions_Users_Permission_Permissions_Guid",
+ schema: "jellyfin",
+ table: "Permissions");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Preferences_Users_Preference_Preferences_Guid",
+ schema: "jellyfin",
+ table: "Preferences");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Preferences_Preference_Preferences_Guid",
+ schema: "jellyfin",
+ table: "Preferences");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Permissions_Permission_Permissions_Guid",
+ schema: "jellyfin",
+ table: "Permissions");
+
+ migrationBuilder.DropIndex(
+ name: "IX_DisplayPreferences_UserId",
+ schema: "jellyfin",
+ table: "DisplayPreferences");
+
+ migrationBuilder.DropIndex(
+ name: "IX_CustomItemDisplayPreferences_UserId",
+ schema: "jellyfin",
+ table: "CustomItemDisplayPreferences");
+
+ migrationBuilder.AlterColumn(
+ name: "Username",
+ schema: "jellyfin",
+ table: "Users",
+ type: "TEXT",
+ maxLength: 255,
+ nullable: false,
+ collation: "NOCASE",
+ oldClrType: typeof(string),
+ oldType: "TEXT",
+ oldMaxLength: 255);
+
+ migrationBuilder.AddColumn(
+ name: "UserId",
+ schema: "jellyfin",
+ table: "Preferences",
+ type: "TEXT",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "UserId",
+ schema: "jellyfin",
+ table: "Permissions",
+ type: "TEXT",
+ nullable: true);
+
+ migrationBuilder.Sql("UPDATE Preferences SET UserId = Preference_Preferences_Guid");
+ migrationBuilder.Sql("UPDATE Permissions SET UserId = Permission_Permissions_Guid");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_Username",
+ schema: "jellyfin",
+ table: "Users",
+ column: "Username",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Preferences_UserId_Kind",
+ schema: "jellyfin",
+ table: "Preferences",
+ columns: new[] { "UserId", "Kind" },
+ unique: true,
+ filter: "[UserId] IS NOT NULL");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Permissions_UserId_Kind",
+ schema: "jellyfin",
+ table: "Permissions",
+ columns: new[] { "UserId", "Kind" },
+ unique: true,
+ filter: "[UserId] IS NOT NULL");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_ImageInfos_Users_UserId",
+ schema: "jellyfin",
+ table: "ImageInfos",
+ column: "UserId",
+ principalSchema: "jellyfin",
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Permissions_Users_UserId",
+ schema: "jellyfin",
+ table: "Permissions",
+ column: "UserId",
+ principalSchema: "jellyfin",
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Preferences_Users_UserId",
+ schema: "jellyfin",
+ table: "Preferences",
+ column: "UserId",
+ principalSchema: "jellyfin",
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_ImageInfos_Users_UserId",
+ schema: "jellyfin",
+ table: "ImageInfos");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Permissions_Users_UserId",
+ schema: "jellyfin",
+ table: "Permissions");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Preferences_Users_UserId",
+ schema: "jellyfin",
+ table: "Preferences");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Users_Username",
+ schema: "jellyfin",
+ table: "Users");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Preferences_UserId_Kind",
+ schema: "jellyfin",
+ table: "Preferences");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Permissions_UserId_Kind",
+ schema: "jellyfin",
+ table: "Permissions");
+
+ migrationBuilder.DropColumn(
+ name: "UserId",
+ schema: "jellyfin",
+ table: "Preferences");
+
+ migrationBuilder.DropColumn(
+ name: "UserId",
+ schema: "jellyfin",
+ table: "Permissions");
+
+ migrationBuilder.AlterColumn(
+ name: "Username",
+ schema: "jellyfin",
+ table: "Users",
+ type: "TEXT",
+ maxLength: 255,
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "TEXT",
+ oldMaxLength: 255,
+ oldCollation: "NOCASE");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Preferences_Preference_Preferences_Guid",
+ schema: "jellyfin",
+ table: "Preferences",
+ column: "Preference_Preferences_Guid");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Permissions_Permission_Permissions_Guid",
+ schema: "jellyfin",
+ table: "Permissions",
+ column: "Permission_Permissions_Guid");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_DisplayPreferences_UserId",
+ schema: "jellyfin",
+ table: "DisplayPreferences",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_CustomItemDisplayPreferences_UserId",
+ schema: "jellyfin",
+ table: "CustomItemDisplayPreferences",
+ column: "UserId");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_ImageInfos_Users_UserId",
+ schema: "jellyfin",
+ table: "ImageInfos",
+ column: "UserId",
+ principalSchema: "jellyfin",
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Permissions_Users_Permission_Permissions_Guid",
+ schema: "jellyfin",
+ table: "Permissions",
+ column: "Permission_Permissions_Guid",
+ principalSchema: "jellyfin",
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Preferences_Users_Preference_Preferences_Guid",
+ schema: "jellyfin",
+ table: "Preferences",
+ column: "Preference_Preferences_Guid",
+ principalSchema: "jellyfin",
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
index 1614a88efb..d8e13ba0c6 100644
--- a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
+++ b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
@@ -15,7 +15,7 @@ namespace Jellyfin.Server.Implementations.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasDefaultSchema("jellyfin")
- .HasAnnotation("ProductVersion", "5.0.0");
+ .HasAnnotation("ProductVersion", "5.0.3");
modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
{
@@ -115,8 +115,6 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasKey("Id");
- b.HasIndex("UserId");
-
b.HasIndex("UserId", "ItemId", "Client", "Key")
.IsUnique();
@@ -174,8 +172,6 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasKey("Id");
- b.HasIndex("UserId");
-
b.HasIndex("UserId", "ItemId", "Client")
.IsUnique();
@@ -289,12 +285,17 @@ namespace Jellyfin.Server.Implementations.Migrations
.IsConcurrencyToken()
.HasColumnType("INTEGER");
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
b.Property("Value")
.HasColumnType("INTEGER");
b.HasKey("Id");
- b.HasIndex("Permission_Permissions_Guid");
+ b.HasIndex("UserId", "Kind")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
b.ToTable("Permissions");
});
@@ -315,6 +316,9 @@ namespace Jellyfin.Server.Implementations.Migrations
.IsConcurrencyToken()
.HasColumnType("INTEGER");
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
b.Property("Value")
.IsRequired()
.HasMaxLength(65535)
@@ -322,7 +326,9 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasKey("Id");
- b.HasIndex("Preference_Preferences_Guid");
+ b.HasIndex("UserId", "Kind")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
b.ToTable("Preferences");
});
@@ -429,10 +435,14 @@ namespace Jellyfin.Server.Implementations.Migrations
b.Property("Username")
.IsRequired()
.HasMaxLength(255)
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .UseCollation("NOCASE");
b.HasKey("Id");
+ b.HasIndex("Username")
+ .IsUnique();
+
b.ToTable("Users");
});
@@ -448,8 +458,8 @@ namespace Jellyfin.Server.Implementations.Migrations
modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
{
b.HasOne("Jellyfin.Data.Entities.User", null)
- .WithOne("DisplayPreferences")
- .HasForeignKey("Jellyfin.Data.Entities.DisplayPreferences", "UserId")
+ .WithMany("DisplayPreferences")
+ .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
@@ -467,7 +477,8 @@ namespace Jellyfin.Server.Implementations.Migrations
{
b.HasOne("Jellyfin.Data.Entities.User", null)
.WithOne("ProfileImage")
- .HasForeignKey("Jellyfin.Data.Entities.ImageInfo", "UserId");
+ .HasForeignKey("Jellyfin.Data.Entities.ImageInfo", "UserId")
+ .OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b =>
@@ -483,14 +494,16 @@ namespace Jellyfin.Server.Implementations.Migrations
{
b.HasOne("Jellyfin.Data.Entities.User", null)
.WithMany("Permissions")
- .HasForeignKey("Permission_Permissions_Guid");
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
{
b.HasOne("Jellyfin.Data.Entities.User", null)
.WithMany("Preferences")
- .HasForeignKey("Preference_Preferences_Guid");
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
@@ -502,8 +515,7 @@ namespace Jellyfin.Server.Implementations.Migrations
{
b.Navigation("AccessSchedules");
- b.Navigation("DisplayPreferences")
- .IsRequired();
+ b.Navigation("DisplayPreferences");
b.Navigation("ItemDisplayPreferences");