Browse Source

Refactor Display preference manager (#14056)

JPVenson 1 week ago
parent
commit
20f7ddbf8f

+ 2 - 5
Jellyfin.Api/Controllers/DisplayPreferencesController.cs

@@ -96,9 +96,6 @@ public class DisplayPreferencesController : BaseJellyfinApiController
             dto.CustomPrefs.TryAdd(key, value);
         }
 
-        // This will essentially be a noop if no changes have been made, but new prefs must be saved at least.
-        _displayPreferencesManager.SaveChanges();
-
         return dto;
     }
 
@@ -210,8 +207,8 @@ public class DisplayPreferencesController : BaseJellyfinApiController
 
         // Set all remaining custom preferences.
         _displayPreferencesManager.SetCustomItemDisplayPreferences(userId.Value, itemId, existingDisplayPreferences.Client, displayPreferences.CustomPrefs);
-        _displayPreferencesManager.SaveChanges();
-
+        _displayPreferencesManager.UpdateItemDisplayPreferences(itemPrefs);
+        _displayPreferencesManager.UpdateDisplayPreferences(existingDisplayPreferences);
         return NoContent();
     }
 }

+ 86 - 79
Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs

@@ -1,109 +1,116 @@
-#pragma warning disable CA1307
-#pragma warning disable CA1309
-
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Threading.Tasks;
 using Jellyfin.Database.Implementations;
 using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller;
 using Microsoft.EntityFrameworkCore;
 
-namespace Jellyfin.Server.Implementations.Users
+namespace Jellyfin.Server.Implementations.Users;
+
+/// <summary>
+/// Manages the storage and retrieval of display preferences through Entity Framework.
+/// </summary>
+public sealed class DisplayPreferencesManager : IDisplayPreferencesManager
 {
+    private readonly IDbContextFactory<JellyfinDbContext> _dbContextFactory;
+
     /// <summary>
-    /// Manages the storage and retrieval of display preferences through Entity Framework.
+    /// Initializes a new instance of the <see cref="DisplayPreferencesManager"/> class.
     /// </summary>
-    public sealed class DisplayPreferencesManager : IDisplayPreferencesManager, IAsyncDisposable
+    /// <param name="dbContextFactory">The database context factory.</param>
+    public DisplayPreferencesManager(IDbContextFactory<JellyfinDbContext> dbContextFactory)
+    {
+        _dbContextFactory = dbContextFactory;
+    }
+
+    /// <inheritdoc />
+    public DisplayPreferences GetDisplayPreferences(Guid userId, Guid itemId, string client)
     {
-        private readonly JellyfinDbContext _dbContext;
+        using var dbContext = _dbContextFactory.CreateDbContext();
+        var prefs = dbContext.DisplayPreferences
+            .Include(pref => pref.HomeSections)
+            .FirstOrDefault(pref =>
+                pref.UserId.Equals(userId) && pref.Client == client && pref.ItemId.Equals(itemId));
 
-        /// <summary>
-        /// Initializes a new instance of the <see cref="DisplayPreferencesManager"/> class.
-        /// </summary>
-        /// <param name="dbContextFactory">The database context factory.</param>
-        public DisplayPreferencesManager(IDbContextFactory<JellyfinDbContext> dbContextFactory)
+        if (prefs is null)
         {
-            _dbContext = dbContextFactory.CreateDbContext();
+            prefs = new DisplayPreferences(userId, itemId, client);
+            dbContext.DisplayPreferences.Add(prefs);
+            dbContext.SaveChanges();
         }
 
-        /// <inheritdoc />
-        public DisplayPreferences GetDisplayPreferences(Guid userId, Guid itemId, string client)
+        return prefs;
+    }
+
+    /// <inheritdoc />
+    public ItemDisplayPreferences GetItemDisplayPreferences(Guid userId, Guid itemId, string client)
+    {
+        using var dbContext = _dbContextFactory.CreateDbContext();
+        var prefs = dbContext.ItemDisplayPreferences
+            .FirstOrDefault(pref => pref.UserId.Equals(userId) && pref.ItemId.Equals(itemId) && pref.Client == client);
+
+        if (prefs is null)
         {
-            var prefs = _dbContext.DisplayPreferences
-                .Include(pref => pref.HomeSections)
-                .FirstOrDefault(pref =>
-                    pref.UserId.Equals(userId) && string.Equals(pref.Client, client) && pref.ItemId.Equals(itemId));
-
-            if (prefs is null)
-            {
-                prefs = new DisplayPreferences(userId, itemId, client);
-                _dbContext.DisplayPreferences.Add(prefs);
-            }
-
-            return prefs;
+            prefs = new ItemDisplayPreferences(userId, Guid.Empty, client);
+            dbContext.ItemDisplayPreferences.Add(prefs);
+            dbContext.SaveChanges();
         }
 
-        /// <inheritdoc />
-        public ItemDisplayPreferences GetItemDisplayPreferences(Guid userId, Guid itemId, string client)
-        {
-            var prefs = _dbContext.ItemDisplayPreferences
-                .FirstOrDefault(pref => pref.UserId.Equals(userId) && pref.ItemId.Equals(itemId) && string.Equals(pref.Client, client));
+        return prefs;
+    }
 
-            if (prefs is null)
-            {
-                prefs = new ItemDisplayPreferences(userId, Guid.Empty, client);
-                _dbContext.ItemDisplayPreferences.Add(prefs);
-            }
+    /// <inheritdoc />
+    public IList<ItemDisplayPreferences> ListItemDisplayPreferences(Guid userId, string client)
+    {
+        using var dbContext = _dbContextFactory.CreateDbContext();
+        return dbContext.ItemDisplayPreferences
+            .Where(prefs => prefs.UserId.Equals(userId) && !prefs.ItemId.Equals(default) && prefs.Client == client)
+            .ToList();
+    }
 
-            return prefs;
-        }
+    /// <inheritdoc />
+    public Dictionary<string, string?> ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client)
+    {
+        using var dbContext = _dbContextFactory.CreateDbContext();
+        return dbContext.CustomItemDisplayPreferences
+            .Where(prefs => prefs.UserId.Equals(userId)
+                            && prefs.ItemId.Equals(itemId)
+                            && prefs.Client == client)
+            .ToDictionary(prefs => prefs.Key, prefs => prefs.Value);
+    }
 
-        /// <inheritdoc />
-        public IList<ItemDisplayPreferences> ListItemDisplayPreferences(Guid userId, string client)
-        {
-            return _dbContext.ItemDisplayPreferences
-                .Where(prefs => prefs.UserId.Equals(userId) && !prefs.ItemId.Equals(default) && string.Equals(prefs.Client, client))
-                .ToList();
-        }
+    /// <inheritdoc />
+    public void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary<string, string?> customPreferences)
+    {
+        using var dbContext = _dbContextFactory.CreateDbContext();
+        dbContext.CustomItemDisplayPreferences.Where(prefs => prefs.UserId.Equals(userId)
+                            && prefs.ItemId.Equals(itemId)
+                            && prefs.Client == client)
+                            .ExecuteDelete();
 
-        /// <inheritdoc />
-        public Dictionary<string, string?> ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client)
+        foreach (var (key, value) in customPreferences)
         {
-            return _dbContext.CustomItemDisplayPreferences
-                .Where(prefs => prefs.UserId.Equals(userId)
-                                && prefs.ItemId.Equals(itemId)
-                                && string.Equals(prefs.Client, client))
-                .ToDictionary(prefs => prefs.Key, prefs => prefs.Value);
+            dbContext.CustomItemDisplayPreferences
+                .Add(new CustomItemDisplayPreferences(userId, itemId, client, key, value));
         }
 
-        /// <inheritdoc />
-        public void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary<string, string?> customPreferences)
-        {
-            var existingPrefs = _dbContext.CustomItemDisplayPreferences
-                .Where(prefs => prefs.UserId.Equals(userId)
-                                && prefs.ItemId.Equals(itemId)
-                                && string.Equals(prefs.Client, client));
-            _dbContext.CustomItemDisplayPreferences.RemoveRange(existingPrefs);
-
-            foreach (var (key, value) in customPreferences)
-            {
-                _dbContext.CustomItemDisplayPreferences
-                    .Add(new CustomItemDisplayPreferences(userId, itemId, client, key, value));
-            }
-        }
+        dbContext.SaveChanges();
+    }
 
-        /// <inheritdoc />
-        public void SaveChanges()
-        {
-            _dbContext.SaveChanges();
-        }
+    /// <inheritdoc/>
+    public void UpdateDisplayPreferences(DisplayPreferences displayPreferences)
+    {
+        using var dbContext = _dbContextFactory.CreateDbContext();
+        dbContext.DisplayPreferences.Attach(displayPreferences).State = EntityState.Modified;
+        dbContext.SaveChanges();
+    }
 
-        /// <inheritdoc />
-        public async ValueTask DisposeAsync()
-        {
-            await _dbContext.DisposeAsync().ConfigureAwait(false);
-        }
+    /// <inheritdoc/>
+    public void UpdateItemDisplayPreferences(ItemDisplayPreferences itemDisplayPreferences)
+    {
+        using var dbContext = _dbContextFactory.CreateDbContext();
+        dbContext.ItemDisplayPreferences.Attach(itemDisplayPreferences).State = EntityState.Modified;
+        dbContext.SaveChanges();
     }
 }

+ 1 - 1
Jellyfin.Server/CoreAppHost.cs

@@ -84,7 +84,7 @@ namespace Jellyfin.Server
             serviceCollection.AddSingleton<IAuthenticationProvider, DefaultAuthenticationProvider>();
             serviceCollection.AddSingleton<IAuthenticationProvider, InvalidAuthProvider>();
             serviceCollection.AddSingleton<IPasswordResetProvider, DefaultPasswordResetProvider>();
-            serviceCollection.AddScoped<IDisplayPreferencesManager, DisplayPreferencesManager>();
+            serviceCollection.AddSingleton<IDisplayPreferencesManager, DisplayPreferencesManager>();
             serviceCollection.AddSingleton<IDeviceManager, DeviceManager>();
             serviceCollection.AddSingleton<ITrickplayManager, TrickplayManager>();
 

+ 9 - 2
MediaBrowser.Controller/IDisplayPreferencesManager.cs

@@ -60,8 +60,15 @@ namespace MediaBrowser.Controller
         void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary<string, string?> customPreferences);
 
         /// <summary>
-        /// Saves changes made to the database.
+        /// Updates or Creates the display preferences.
         /// </summary>
-        void SaveChanges();
+        /// <param name="displayPreferences">The entity to update or create.</param>
+        void UpdateDisplayPreferences(DisplayPreferences displayPreferences);
+
+        /// <summary>
+        /// Updates or Creates the display preferences for the given item.
+        /// </summary>
+        /// <param name="itemDisplayPreferences">The entity to update or create.</param>
+        void UpdateItemDisplayPreferences(ItemDisplayPreferences itemDisplayPreferences);
     }
 }