Browse Source

Merge pull request #13589 from JPVenson/feature/DatabaseRefactor

[Feature] Database code refactor
Cody Robibero 2 tháng trước cách đây
mục cha
commit
d848faeb75
100 tập tin đã thay đổi với 403 bổ sung848 xóa
  1. 6 2
      .devcontainer/devcontainer.json
  2. 3 0
      .vscode/settings.json
  3. 8 3
      Emby.Server.Implementations/ApplicationHost.cs
  4. 1 1
      Emby.Server.Implementations/Collections/CollectionManager.cs
  5. 1 1
      Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
  6. 1 1
      Emby.Server.Implementations/Dto/DtoService.cs
  7. 1 0
      Emby.Server.Implementations/Emby.Server.Implementations.csproj
  8. 1 1
      Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
  9. 2 1
      Emby.Server.Implementations/HttpServer/Security/AuthService.cs
  10. 1 0
      Emby.Server.Implementations/Images/BaseFolderImageProvider.cs
  11. 1 0
      Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs
  12. 1 0
      Emby.Server.Implementations/Images/GenreImageProvider.cs
  13. 1 0
      Emby.Server.Implementations/Images/MusicGenreImageProvider.cs
  14. 3 1
      Emby.Server.Implementations/Library/LibraryManager.cs
  15. 3 1
      Emby.Server.Implementations/Library/MediaSourceManager.cs
  16. 1 1
      Emby.Server.Implementations/Library/MediaStreamSelector.cs
  17. 2 1
      Emby.Server.Implementations/Library/MusicManager.cs
  18. 2 1
      Emby.Server.Implementations/Library/SearchEngine.cs
  19. 1 0
      Emby.Server.Implementations/Library/SplashscreenPostScanTask.cs
  20. 2 2
      Emby.Server.Implementations/Library/UserDataManager.cs
  21. 3 1
      Emby.Server.Implementations/Library/UserViewManager.cs
  22. 1 0
      Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs
  23. 1 1
      Emby.Server.Implementations/Playlists/PlaylistManager.cs
  24. 1 1
      Emby.Server.Implementations/Playlists/PlaylistsFolder.cs
  25. 7 16
      Emby.Server.Implementations/ScheduledTasks/Tasks/OptimizeDatabaseTask.cs
  26. 4 2
      Emby.Server.Implementations/Session/SessionManager.cs
  27. 1 1
      Emby.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs
  28. 1 1
      Emby.Server.Implementations/Sorting/DatePlayedComparer.cs
  29. 1 1
      Emby.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs
  30. 1 1
      Emby.Server.Implementations/Sorting/IsPlayedComparer.cs
  31. 1 1
      Emby.Server.Implementations/Sorting/IsUnplayedComparer.cs
  32. 1 1
      Emby.Server.Implementations/Sorting/PlayCountComparer.cs
  33. 1 1
      Emby.Server.Implementations/SyncPlay/Group.cs
  34. 3 1
      Emby.Server.Implementations/TV/TVSeriesManager.cs
  35. 2 1
      Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
  36. 2 1
      Jellyfin.Api/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandler.cs
  37. 1 0
      Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs
  38. 1 0
      Jellyfin.Api/Auth/UserPermissionPolicy/UserPermissionHandler.cs
  39. 1 1
      Jellyfin.Api/Auth/UserPermissionPolicy/UserPermissionRequirement.cs
  40. 2 1
      Jellyfin.Api/Controllers/ArtistsController.cs
  41. 1 0
      Jellyfin.Api/Controllers/ChannelsController.cs
  42. 2 2
      Jellyfin.Api/Controllers/DisplayPreferencesController.cs
  43. 2 1
      Jellyfin.Api/Controllers/GenresController.cs
  44. 1 1
      Jellyfin.Api/Controllers/ImageController.cs
  45. 1 1
      Jellyfin.Api/Controllers/InstantMixController.cs
  46. 2 0
      Jellyfin.Api/Controllers/ItemsController.cs
  47. 2 1
      Jellyfin.Api/Controllers/LibraryController.cs
  48. 1 0
      Jellyfin.Api/Controllers/LiveTvController.cs
  49. 1 1
      Jellyfin.Api/Controllers/MediaSegmentsController.cs
  50. 2 1
      Jellyfin.Api/Controllers/MoviesController.cs
  51. 2 1
      Jellyfin.Api/Controllers/MusicGenresController.cs
  52. 1 1
      Jellyfin.Api/Controllers/PersonsController.cs
  53. 1 1
      Jellyfin.Api/Controllers/PlaystateController.cs
  54. 1 1
      Jellyfin.Api/Controllers/StudiosController.cs
  55. 2 1
      Jellyfin.Api/Controllers/SuggestionsController.cs
  56. 1 0
      Jellyfin.Api/Controllers/TrailersController.cs
  57. 1 0
      Jellyfin.Api/Controllers/TvShowsController.cs
  58. 2 1
      Jellyfin.Api/Controllers/UserController.cs
  59. 1 1
      Jellyfin.Api/Controllers/UserLibraryController.cs
  60. 2 1
      Jellyfin.Api/Controllers/YearsController.cs
  61. 1 1
      Jellyfin.Api/Helpers/DynamicHlsHelper.cs
  62. 3 1
      Jellyfin.Api/Helpers/MediaInfoHelper.cs
  63. 2 1
      Jellyfin.Api/Helpers/RequestHelpers.cs
  64. 1 0
      Jellyfin.Api/Models/LiveTvDtos/GetProgramsDto.cs
  65. 2 1
      Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
  66. 2 1
      Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs
  67. 1 1
      Jellyfin.Data/DayOfWeekHelper.cs
  68. 0 33
      Jellyfin.Data/Enums/ArtKind.cs
  69. 0 18
      Jellyfin.Data/Enums/ChromecastVersion.cs
  70. 0 58
      Jellyfin.Data/Enums/DynamicDayOfWeek.cs
  71. 0 58
      Jellyfin.Data/Enums/HomeSectionType.cs
  72. 0 23
      Jellyfin.Data/Enums/IndexingKind.cs
  73. 0 33
      Jellyfin.Data/Enums/MediaFileKind.cs
  74. 0 128
      Jellyfin.Data/Enums/PermissionKind.cs
  75. 0 68
      Jellyfin.Data/Enums/PersonRoleType.cs
  76. 0 73
      Jellyfin.Data/Enums/PreferenceKind.cs
  77. 0 18
      Jellyfin.Data/Enums/ScrollDirection.cs
  78. 0 18
      Jellyfin.Data/Enums/SortOrder.cs
  79. 0 33
      Jellyfin.Data/Enums/SubtitlePlaybackMode.cs
  80. 0 23
      Jellyfin.Data/Enums/SyncPlayUserAccessType.cs
  81. 0 113
      Jellyfin.Data/Enums/ViewType.cs
  82. 1 1
      Jellyfin.Data/Events/Users/UserCreatedEventArgs.cs
  83. 1 1
      Jellyfin.Data/Events/Users/UserDeletedEventArgs.cs
  84. 1 1
      Jellyfin.Data/Events/Users/UserLockedOutEventArgs.cs
  85. 1 1
      Jellyfin.Data/Events/Users/UserPasswordChangedEventArgs.cs
  86. 1 1
      Jellyfin.Data/Events/Users/UserUpdatedEventArgs.cs
  87. 0 18
      Jellyfin.Data/Interfaces/IHasConcurrencyToken.cs
  88. 0 31
      Jellyfin.Data/Interfaces/IHasPermissions.cs
  89. 0 16
      Jellyfin.Data/Interfaces/IHasReleases.cs
  90. 4 0
      Jellyfin.Data/Jellyfin.Data.csproj
  91. 220 0
      Jellyfin.Data/UserEntityExtensions.cs
  92. 2 1
      Jellyfin.Server.Implementations/Activity/ActivityManager.cs
  93. 17 0
      Jellyfin.Server.Implementations/DbConfiguration/DatabaseConfigurationFactory.cs
  94. 26 0
      Jellyfin.Server.Implementations/DbConfiguration/DatabaseConfigurationStore.cs
  95. 5 3
      Jellyfin.Server.Implementations/Devices/DeviceManager.cs
  96. 1 1
      Jellyfin.Server.Implementations/Events/Consumers/Library/LyricDownloadFailureLogger.cs
  97. 1 1
      Jellyfin.Server.Implementations/Events/Consumers/Library/SubtitleDownloadFailureLogger.cs
  98. 1 1
      Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationFailedLogger.cs
  99. 1 1
      Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs
  100. 1 1
      Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs

+ 6 - 2
.devcontainer/devcontainer.json

@@ -1,6 +1,8 @@
 {
     "name": "Development Jellyfin Server",
-    "image":"mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
+    "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
+    "service": "app",
+    "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
     // restores nuget packages, installs the dotnet workloads and installs the dev https certificate
     "postStartCommand": "sudo dotnet restore; sudo dotnet workload update; sudo dotnet dev-certs https --trust; sudo bash \"./.devcontainer/install-ffmpeg.sh\"",
     // reads the extensions list and installs them
@@ -13,7 +15,9 @@
         },
         "ghcr.io/devcontainers-contrib/features/apt-packages:1": {
             "preserve_apt_list": false,
-            "packages": ["libfontconfig1"]
+            "packages": [
+                "libfontconfig1"
+            ]
         },
         "ghcr.io/devcontainers/features/docker-in-docker:2": {
             "dockerDashComposeVersion": "v2"

+ 3 - 0
.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "dotnet.preferVisualStudioCodeFileSystemWatcher": true
+}

+ 8 - 3
Emby.Server.Implementations/ApplicationHost.cs

@@ -35,11 +35,11 @@ using Emby.Server.Implementations.SyncPlay;
 using Emby.Server.Implementations.TV;
 using Emby.Server.Implementations.Updates;
 using Jellyfin.Api.Helpers;
+using Jellyfin.Database.Implementations;
 using Jellyfin.Drawing;
 using Jellyfin.MediaEncoding.Hls.Playlist;
 using Jellyfin.Networking.Manager;
 using Jellyfin.Networking.Udp;
-using Jellyfin.Server.Implementations;
 using Jellyfin.Server.Implementations.Item;
 using Jellyfin.Server.Implementations.MediaSegments;
 using MediaBrowser.Common;
@@ -574,10 +574,15 @@ namespace Emby.Server.Implementations
         /// <summary>
         /// Create services registered with the service container that need to be initialized at application startup.
         /// </summary>
+        /// <param name="startupConfig">The configuration used to initialise the application.</param>
         /// <returns>A task representing the service initialization operation.</returns>
-        public async Task InitializeServices()
+        public async Task InitializeServices(IConfiguration startupConfig)
         {
-            var jellyfinDb = await Resolve<IDbContextFactory<JellyfinDbContext>>().CreateDbContextAsync().ConfigureAwait(false);
+            var factory = Resolve<IDbContextFactory<JellyfinDbContext>>();
+            var provider = Resolve<IJellyfinDatabaseProvider>();
+            provider.DbContextFactory = factory;
+
+            var jellyfinDb = await factory.CreateDbContextAsync().ConfigureAwait(false);
             await using (jellyfinDb.ConfigureAwait(false))
             {
                 if ((await jellyfinDb.Database.GetPendingMigrationsAsync().ConfigureAwait(false)).Any())

+ 1 - 1
Emby.Server.Implementations/Collections/CollectionManager.cs

@@ -4,7 +4,7 @@ using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Collections;
 using MediaBrowser.Controller.Entities;

+ 1 - 1
Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs

@@ -4,7 +4,7 @@ using System;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using Jellyfin.Server.Implementations;
+using Jellyfin.Database.Implementations;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;

+ 1 - 1
Emby.Server.Implementations/Dto/DtoService.cs

@@ -5,8 +5,8 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Common;
 using MediaBrowser.Controller.Channels;

+ 1 - 0
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -18,6 +18,7 @@
     <ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj" />
     <ProjectReference Include="..\src\Jellyfin.Drawing\Jellyfin.Drawing.csproj" />
     <ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj" />
+    <ProjectReference Include="..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
   </ItemGroup>
 
   <ItemGroup>

+ 1 - 1
Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs

@@ -5,8 +5,8 @@ using System.Globalization;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Events;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;

+ 2 - 1
Emby.Server.Implementations/HttpServer/Security/AuthService.cs

@@ -1,7 +1,8 @@
 #pragma warning disable CS1591
 
 using System.Threading.Tasks;
-using Jellyfin.Data.Enums;
+using Jellyfin.Data;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Controller.Net;
 using Microsoft.AspNetCore.Http;
 

+ 1 - 0
Emby.Server.Implementations/Images/BaseFolderImageProvider.cs

@@ -2,6 +2,7 @@
 
 using System.Collections.Generic;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;

+ 1 - 0
Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs

@@ -6,6 +6,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;

+ 1 - 0
Emby.Server.Implementations/Images/GenreImageProvider.cs

@@ -2,6 +2,7 @@
 
 using System.Collections.Generic;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;

+ 1 - 0
Emby.Server.Implementations/Images/MusicGenreImageProvider.cs

@@ -4,6 +4,7 @@
 
 using System.Collections.Generic;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;

+ 3 - 1
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -18,8 +18,10 @@ using Emby.Server.Implementations.Library.Validators;
 using Emby.Server.Implementations.Playlists;
 using Emby.Server.Implementations.ScheduledTasks.Tasks;
 using Emby.Server.Implementations.Sorting;
-using Jellyfin.Data.Entities;
+using Jellyfin.Data;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller;

+ 3 - 1
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -13,8 +13,10 @@ using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using AsyncKeyedLock;
-using Jellyfin.Data.Entities;
+using Jellyfin.Data;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using Jellyfin.Extensions.Json;
 using MediaBrowser.Common.Configuration;

+ 1 - 1
Emby.Server.Implementations/Library/MediaStreamSelector.cs

@@ -3,7 +3,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Model.Entities;
 

+ 2 - 1
Emby.Server.Implementations/Library/MusicManager.cs

@@ -4,8 +4,9 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Linq;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 2 - 1
Emby.Server.Implementations/Library/SearchEngine.cs

@@ -3,8 +3,9 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 0
Emby.Server.Implementations/Library/SplashscreenPostScanTask.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 2 - 2
Emby.Server.Implementations/Library/UserDataManager.cs

@@ -6,9 +6,9 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
 using System.Threading;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
-using Jellyfin.Server.Implementations;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 3 - 1
Emby.Server.Implementations/Library/UserViewManager.cs

@@ -6,8 +6,10 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
-using Jellyfin.Data.Entities;
+using Jellyfin.Data;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;

+ 1 - 0
Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Controller.Collections;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;

+ 1 - 1
Emby.Server.Implementations/Playlists/PlaylistManager.cs

@@ -9,8 +9,8 @@ using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 1
Emby.Server.Implementations/Playlists/PlaylistsFolder.cs

@@ -3,8 +3,8 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text.Json.Serialization;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Common;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Playlists;

+ 7 - 16
Emby.Server.Implementations/ScheduledTasks/Tasks/OptimizeDatabaseTask.cs

@@ -2,7 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
-using Jellyfin.Server.Implementations;
+using Jellyfin.Database.Implementations;
 using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.Tasks;
 using Microsoft.EntityFrameworkCore;
@@ -18,6 +18,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
         private readonly ILogger<OptimizeDatabaseTask> _logger;
         private readonly ILocalizationManager _localization;
         private readonly IDbContextFactory<JellyfinDbContext> _provider;
+        private readonly IJellyfinDatabaseProvider _jellyfinDatabaseProvider;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="OptimizeDatabaseTask" /> class.
@@ -25,14 +26,17 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
         /// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
         /// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
         /// <param name="provider">Instance of the <see cref="IDbContextFactory{JellyfinDbContext}"/> interface.</param>
+        /// <param name="jellyfinDatabaseProvider">Instance of the JellyfinDatabaseProvider that can be used for provider specific operations.</param>
         public OptimizeDatabaseTask(
             ILogger<OptimizeDatabaseTask> logger,
             ILocalizationManager localization,
-            IDbContextFactory<JellyfinDbContext> provider)
+            IDbContextFactory<JellyfinDbContext> provider,
+            IJellyfinDatabaseProvider jellyfinDatabaseProvider)
         {
             _logger = logger;
             _localization = localization;
             _provider = provider;
+            _jellyfinDatabaseProvider = jellyfinDatabaseProvider;
         }
 
         /// <inheritdoc />
@@ -73,20 +77,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
 
             try
             {
-                var context = await _provider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
-                await using (context.ConfigureAwait(false))
-                {
-                    if (context.Database.IsSqlite())
-                    {
-                        await context.Database.ExecuteSqlRawAsync("PRAGMA optimize", cancellationToken).ConfigureAwait(false);
-                        await context.Database.ExecuteSqlRawAsync("VACUUM", cancellationToken).ConfigureAwait(false);
-                        _logger.LogInformation("jellyfin.db optimized successfully!");
-                    }
-                    else
-                    {
-                        _logger.LogInformation("This database doesn't support optimization");
-                    }
-                }
+                await _jellyfinDatabaseProvider.RunScheduledOptimisation(cancellationToken).ConfigureAwait(false);
             }
             catch (Exception e)
             {

+ 4 - 2
Emby.Server.Implementations/Session/SessionManager.cs

@@ -7,11 +7,13 @@ using System.Globalization;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
-using Jellyfin.Data.Entities.Security;
+using Jellyfin.Data;
 using Jellyfin.Data.Enums;
 using Jellyfin.Data.Events;
 using Jellyfin.Data.Queries;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Entities.Security;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Extensions;

+ 1 - 1
Emby.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs

@@ -2,8 +2,8 @@
 #pragma warning disable CS1591
 
 using System;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Sorting;

+ 1 - 1
Emby.Server.Implementations/Sorting/DatePlayedComparer.cs

@@ -1,8 +1,8 @@
 #nullable disable
 
 using System;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Sorting;

+ 1 - 1
Emby.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs

@@ -1,8 +1,8 @@
 #nullable disable
 #pragma warning disable CS1591
 
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Sorting;

+ 1 - 1
Emby.Server.Implementations/Sorting/IsPlayedComparer.cs

@@ -2,8 +2,8 @@
 
 #pragma warning disable CS1591
 
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Sorting;

+ 1 - 1
Emby.Server.Implementations/Sorting/IsUnplayedComparer.cs

@@ -2,8 +2,8 @@
 
 #pragma warning disable CS1591
 
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Sorting;

+ 1 - 1
Emby.Server.Implementations/Sorting/PlayCountComparer.cs

@@ -1,7 +1,7 @@
 #nullable disable
 
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Sorting;

+ 1 - 1
Emby.Server.Implementations/SyncPlay/Group.cs

@@ -5,7 +5,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Session;

+ 3 - 1
Emby.Server.Implementations/TV/TVSeriesManager.cs

@@ -3,8 +3,10 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using Jellyfin.Data.Entities;
+using Jellyfin.Data;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;

+ 2 - 1
Jellyfin.Api/Auth/CustomAuthenticationHandler.cs

@@ -3,7 +3,8 @@ using System.Security.Claims;
 using System.Text.Encodings.Web;
 using System.Threading.Tasks;
 using Jellyfin.Api.Constants;
-using Jellyfin.Data.Enums;
+using Jellyfin.Data;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Controller.Authentication;
 using MediaBrowser.Controller.Net;
 using Microsoft.AspNetCore.Authentication;

+ 2 - 1
Jellyfin.Api/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandler.cs

@@ -1,7 +1,8 @@
 using System.Threading.Tasks;
 using Jellyfin.Api.Constants;
 using Jellyfin.Api.Extensions;
-using Jellyfin.Data.Enums;
+using Jellyfin.Data;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Net;

+ 1 - 0
Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs

@@ -1,6 +1,7 @@
 using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.SyncPlay;

+ 1 - 0
Jellyfin.Api/Auth/UserPermissionPolicy/UserPermissionHandler.cs

@@ -1,5 +1,6 @@
 using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
+using Jellyfin.Data;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Library;

+ 1 - 1
Jellyfin.Api/Auth/UserPermissionPolicy/UserPermissionRequirement.cs

@@ -1,5 +1,5 @@
 using Jellyfin.Api.Auth.DefaultAuthorizationPolicy;
-using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 
 namespace Jellyfin.Api.Auth.UserPermissionPolicy
 {

+ 2 - 1
Jellyfin.Api/Controllers/ArtistsController.cs

@@ -4,8 +4,9 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 0
Jellyfin.Api/Controllers/ChannelsController.cs

@@ -6,6 +6,7 @@ using System.Threading.Tasks;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Dto;

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

@@ -4,8 +4,8 @@ using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.Linq;
 using Jellyfin.Api.Helpers;
-using Jellyfin.Data.Entities;
-using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller;
 using MediaBrowser.Model.Dto;

+ 2 - 1
Jellyfin.Api/Controllers/GenresController.cs

@@ -4,8 +4,9 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 1
Jellyfin.Api/Controllers/ImageController.cs

@@ -130,7 +130,7 @@ public class ImageController : BaseJellyfinApiController
                 await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
             }
 
-            user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + extension));
+            user.ProfileImage = new Database.Implementations.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + extension));
 
             await _providerManager
                 .SaveImage(stream, mimeType, user.ProfileImage.Path)

+ 1 - 1
Jellyfin.Api/Controllers/InstantMixController.cs

@@ -6,7 +6,7 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 2 - 0
Jellyfin.Api/Controllers/ItemsController.cs

@@ -4,7 +4,9 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
+using Jellyfin.Data;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Dto;

+ 2 - 1
Jellyfin.Api/Controllers/LibraryController.cs

@@ -11,8 +11,9 @@ using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
 using Jellyfin.Api.Models.LibraryDtos;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Api;
 using MediaBrowser.Common.Extensions;

+ 1 - 0
Jellyfin.Api/Controllers/LiveTvController.cs

@@ -15,6 +15,7 @@ using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
 using Jellyfin.Api.Models.LiveTvDtos;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Api;
 using MediaBrowser.Common.Configuration;

+ 1 - 1
Jellyfin.Api/Controllers/MediaSegmentsController.cs

@@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
-using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;

+ 2 - 1
Jellyfin.Api/Controllers/MoviesController.cs

@@ -5,8 +5,9 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Configuration;

+ 2 - 1
Jellyfin.Api/Controllers/MusicGenresController.cs

@@ -4,8 +4,9 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 1
Jellyfin.Api/Controllers/PersonsController.cs

@@ -4,7 +4,7 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 1
Jellyfin.Api/Controllers/PlaystateController.cs

@@ -5,7 +5,7 @@ using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;

+ 1 - 1
Jellyfin.Api/Controllers/StudiosController.cs

@@ -3,8 +3,8 @@ using System.ComponentModel.DataAnnotations;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 2 - 1
Jellyfin.Api/Controllers/SuggestionsController.cs

@@ -3,8 +3,9 @@ using System.ComponentModel.DataAnnotations;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 0
Jellyfin.Api/Controllers/TrailersController.cs

@@ -1,6 +1,7 @@
 using System;
 using Jellyfin.Api.ModelBinders;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;

+ 1 - 0
Jellyfin.Api/Controllers/TvShowsController.cs

@@ -7,6 +7,7 @@ using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 2 - 1
Jellyfin.Api/Controllers/UserController.cs

@@ -7,7 +7,8 @@ using Jellyfin.Api.Constants;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.Models.UserDtos;
-using Jellyfin.Data.Enums;
+using Jellyfin.Data;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Api;
 using MediaBrowser.Common.Extensions;

+ 1 - 1
Jellyfin.Api/Controllers/UserLibraryController.cs

@@ -7,8 +7,8 @@ using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 2 - 1
Jellyfin.Api/Controllers/YearsController.cs

@@ -6,8 +6,9 @@ using System.Linq;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;

+ 1 - 1
Jellyfin.Api/Helpers/DynamicHlsHelper.cs

@@ -8,8 +8,8 @@ using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;

+ 3 - 1
Jellyfin.Api/Helpers/MediaInfoHelper.cs

@@ -7,8 +7,10 @@ using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
-using Jellyfin.Data.Entities;
+using Jellyfin.Data;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Net;

+ 2 - 1
Jellyfin.Api/Helpers/RequestHelpers.cs

@@ -5,8 +5,9 @@ using System.Security.Claims;
 using System.Threading.Tasks;
 using Jellyfin.Api.Constants;
 using Jellyfin.Api.Extensions;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Dto;

+ 1 - 0
Jellyfin.Api/Models/LiveTvDtos/GetProgramsDto.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.ComponentModel;
 using System.Text.Json.Serialization;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions.Json.Converters;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;

+ 2 - 1
Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs

@@ -1,7 +1,8 @@
 using System;
 using System.Threading.Tasks;
-using Jellyfin.Data.Enums;
+using Jellyfin.Data;
 using Jellyfin.Data.Events;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Controller.Authentication;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Activity;

+ 2 - 1
Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs

@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using System.Threading.Tasks;
-using Jellyfin.Data.Enums;
+using Jellyfin.Data;
+using Jellyfin.Database.Implementations.Enums;
 using MediaBrowser.Controller.Authentication;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;

+ 1 - 1
Jellyfin.Data/DayOfWeekHelper.cs

@@ -1,7 +1,7 @@
 #pragma warning disable CS1591
 
 using System;
-using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Enums;
 
 namespace Jellyfin.Data
 {

+ 0 - 33
Jellyfin.Data/Enums/ArtKind.cs

@@ -1,33 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing types of art.
-    /// </summary>
-    public enum ArtKind
-    {
-        /// <summary>
-        /// Another type of art, not covered by the other members.
-        /// </summary>
-        Other = 0,
-
-        /// <summary>
-        /// A poster.
-        /// </summary>
-        Poster = 1,
-
-        /// <summary>
-        /// A banner.
-        /// </summary>
-        Banner = 2,
-
-        /// <summary>
-        /// A thumbnail.
-        /// </summary>
-        Thumbnail = 3,
-
-        /// <summary>
-        /// A logo.
-        /// </summary>
-        Logo = 4
-    }
-}

+ 0 - 18
Jellyfin.Data/Enums/ChromecastVersion.cs

@@ -1,18 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing the version of Chromecast to be used by clients.
-    /// </summary>
-    public enum ChromecastVersion
-    {
-        /// <summary>
-        /// Stable Chromecast version.
-        /// </summary>
-        Stable = 0,
-
-        /// <summary>
-        /// Unstable Chromecast version.
-        /// </summary>
-        Unstable = 1
-    }
-}

+ 0 - 58
Jellyfin.Data/Enums/DynamicDayOfWeek.cs

@@ -1,58 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum that represents a day of the week, weekdays, weekends, or all days.
-    /// </summary>
-    public enum DynamicDayOfWeek
-    {
-        /// <summary>
-        /// Sunday.
-        /// </summary>
-        Sunday = 0,
-
-        /// <summary>
-        /// Monday.
-        /// </summary>
-        Monday = 1,
-
-        /// <summary>
-        /// Tuesday.
-        /// </summary>
-        Tuesday = 2,
-
-        /// <summary>
-        /// Wednesday.
-        /// </summary>
-        Wednesday = 3,
-
-        /// <summary>
-        /// Thursday.
-        /// </summary>
-        Thursday = 4,
-
-        /// <summary>
-        /// Friday.
-        /// </summary>
-        Friday = 5,
-
-        /// <summary>
-        /// Saturday.
-        /// </summary>
-        Saturday = 6,
-
-        /// <summary>
-        /// All days of the week.
-        /// </summary>
-        Everyday = 7,
-
-        /// <summary>
-        /// A week day, or Monday-Friday.
-        /// </summary>
-        Weekday = 8,
-
-        /// <summary>
-        /// Saturday and Sunday.
-        /// </summary>
-        Weekend = 9
-    }
-}

+ 0 - 58
Jellyfin.Data/Enums/HomeSectionType.cs

@@ -1,58 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing the different options for the home screen sections.
-    /// </summary>
-    public enum HomeSectionType
-    {
-        /// <summary>
-        /// None.
-        /// </summary>
-        None = 0,
-
-        /// <summary>
-        /// My Media.
-        /// </summary>
-        SmallLibraryTiles = 1,
-
-        /// <summary>
-        /// My Media Small.
-        /// </summary>
-        LibraryButtons = 2,
-
-        /// <summary>
-        /// Active Recordings.
-        /// </summary>
-        ActiveRecordings = 3,
-
-        /// <summary>
-        /// Continue Watching.
-        /// </summary>
-        Resume = 4,
-
-        /// <summary>
-        /// Continue Listening.
-        /// </summary>
-        ResumeAudio = 5,
-
-        /// <summary>
-        /// Latest Media.
-        /// </summary>
-        LatestMedia = 6,
-
-        /// <summary>
-        /// Next Up.
-        /// </summary>
-        NextUp = 7,
-
-        /// <summary>
-        /// Live TV.
-        /// </summary>
-        LiveTv = 8,
-
-        /// <summary>
-        /// Continue Reading.
-        /// </summary>
-        ResumeBook = 9
-    }
-}

+ 0 - 23
Jellyfin.Data/Enums/IndexingKind.cs

@@ -1,23 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing a type of indexing in a user's display preferences.
-    /// </summary>
-    public enum IndexingKind
-    {
-        /// <summary>
-        /// Index by the premiere date.
-        /// </summary>
-        PremiereDate = 0,
-
-        /// <summary>
-        /// Index by the production year.
-        /// </summary>
-        ProductionYear = 1,
-
-        /// <summary>
-        /// Index by the community rating.
-        /// </summary>
-        CommunityRating = 2
-    }
-}

+ 0 - 33
Jellyfin.Data/Enums/MediaFileKind.cs

@@ -1,33 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing the type of media file.
-    /// </summary>
-    public enum MediaFileKind
-    {
-        /// <summary>
-        /// The main file.
-        /// </summary>
-        Main = 0,
-
-        /// <summary>
-        /// A sidecar file.
-        /// </summary>
-        Sidecar = 1,
-
-        /// <summary>
-        /// An additional part to the main file.
-        /// </summary>
-        AdditionalPart = 2,
-
-        /// <summary>
-        /// An alternative format to the main file.
-        /// </summary>
-        AlternativeFormat = 3,
-
-        /// <summary>
-        /// An additional stream for the main file.
-        /// </summary>
-        AdditionalStream = 4
-    }
-}

+ 0 - 128
Jellyfin.Data/Enums/PermissionKind.cs

@@ -1,128 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// The types of user permissions.
-    /// </summary>
-    public enum PermissionKind
-    {
-        /// <summary>
-        /// Whether the user is an administrator.
-        /// </summary>
-        IsAdministrator = 0,
-
-        /// <summary>
-        /// Whether the user is hidden.
-        /// </summary>
-        IsHidden = 1,
-
-        /// <summary>
-        /// Whether the user is disabled.
-        /// </summary>
-        IsDisabled = 2,
-
-        /// <summary>
-        /// Whether the user can control shared devices.
-        /// </summary>
-        EnableSharedDeviceControl = 3,
-
-        /// <summary>
-        /// Whether the user can access the server remotely.
-        /// </summary>
-        EnableRemoteAccess = 4,
-
-        /// <summary>
-        /// Whether the user can manage live tv.
-        /// </summary>
-        EnableLiveTvManagement = 5,
-
-        /// <summary>
-        /// Whether the user can access live tv.
-        /// </summary>
-        EnableLiveTvAccess = 6,
-
-        /// <summary>
-        /// Whether the user can play media.
-        /// </summary>
-        EnableMediaPlayback = 7,
-
-        /// <summary>
-        /// Whether the server should transcode audio for the user if requested.
-        /// </summary>
-        EnableAudioPlaybackTranscoding = 8,
-
-        /// <summary>
-        /// Whether the server should transcode video for the user if requested.
-        /// </summary>
-        EnableVideoPlaybackTranscoding = 9,
-
-        /// <summary>
-        /// Whether the user can delete content.
-        /// </summary>
-        EnableContentDeletion = 10,
-
-        /// <summary>
-        /// Whether the user can download content.
-        /// </summary>
-        EnableContentDownloading = 11,
-
-        /// <summary>
-        /// Whether to enable sync transcoding for the user.
-        /// </summary>
-        EnableSyncTranscoding = 12,
-
-        /// <summary>
-        /// Whether the user can do media conversion.
-        /// </summary>
-        EnableMediaConversion = 13,
-
-        /// <summary>
-        /// Whether the user has access to all devices.
-        /// </summary>
-        EnableAllDevices = 14,
-
-        /// <summary>
-        /// Whether the user has access to all channels.
-        /// </summary>
-        EnableAllChannels = 15,
-
-        /// <summary>
-        /// Whether the user has access to all folders.
-        /// </summary>
-        EnableAllFolders = 16,
-
-        /// <summary>
-        /// Whether to enable public sharing for the user.
-        /// </summary>
-        EnablePublicSharing = 17,
-
-        /// <summary>
-        /// Whether the user can remotely control other users.
-        /// </summary>
-        EnableRemoteControlOfOtherUsers = 18,
-
-        /// <summary>
-        /// Whether the user is permitted to do playback remuxing.
-        /// </summary>
-        EnablePlaybackRemuxing = 19,
-
-        /// <summary>
-        /// Whether the server should force transcoding on remote connections for the user.
-        /// </summary>
-        ForceRemoteSourceTranscoding = 20,
-
-        /// <summary>
-        /// Whether the user can create, modify and delete collections.
-        /// </summary>
-        EnableCollectionManagement = 21,
-
-        /// <summary>
-        /// Whether the user can edit subtitles.
-        /// </summary>
-        EnableSubtitleManagement = 22,
-
-        /// <summary>
-        /// Whether the user can edit lyrics.
-        /// </summary>
-        EnableLyricManagement = 23,
-    }
-}

+ 0 - 68
Jellyfin.Data/Enums/PersonRoleType.cs

@@ -1,68 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing a person's role in a specific media item.
-    /// </summary>
-    public enum PersonRoleType
-    {
-        /// <summary>
-        /// Another role, not covered by the other types.
-        /// </summary>
-        Other = 0,
-
-        /// <summary>
-        /// The director of the media.
-        /// </summary>
-        Director = 1,
-
-        /// <summary>
-        /// An artist.
-        /// </summary>
-        Artist = 2,
-
-        /// <summary>
-        /// The original artist.
-        /// </summary>
-        OriginalArtist = 3,
-
-        /// <summary>
-        /// An actor.
-        /// </summary>
-        Actor = 4,
-
-        /// <summary>
-        /// A voice actor.
-        /// </summary>
-        VoiceActor = 5,
-
-        /// <summary>
-        /// A producer.
-        /// </summary>
-        Producer = 6,
-
-        /// <summary>
-        /// A remixer.
-        /// </summary>
-        Remixer = 7,
-
-        /// <summary>
-        /// A conductor.
-        /// </summary>
-        Conductor = 8,
-
-        /// <summary>
-        /// A composer.
-        /// </summary>
-        Composer = 9,
-
-        /// <summary>
-        /// An author.
-        /// </summary>
-        Author = 10,
-
-        /// <summary>
-        /// An editor.
-        /// </summary>
-        Editor = 11
-    }
-}

+ 0 - 73
Jellyfin.Data/Enums/PreferenceKind.cs

@@ -1,73 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// The types of user preferences.
-    /// </summary>
-    public enum PreferenceKind
-    {
-        /// <summary>
-        /// A list of blocked tags.
-        /// </summary>
-        BlockedTags = 0,
-
-        /// <summary>
-        /// A list of blocked channels.
-        /// </summary>
-        BlockedChannels = 1,
-
-        /// <summary>
-        /// A list of blocked media folders.
-        /// </summary>
-        BlockedMediaFolders = 2,
-
-        /// <summary>
-        /// A list of enabled devices.
-        /// </summary>
-        EnabledDevices = 3,
-
-        /// <summary>
-        /// A list of enabled channels.
-        /// </summary>
-        EnabledChannels = 4,
-
-        /// <summary>
-        /// A list of enabled folders.
-        /// </summary>
-        EnabledFolders = 5,
-
-        /// <summary>
-        /// A list of folders to allow content deletion from.
-        /// </summary>
-        EnableContentDeletionFromFolders = 6,
-
-        /// <summary>
-        /// A list of latest items to exclude.
-        /// </summary>
-        LatestItemExcludes = 7,
-
-        /// <summary>
-        /// A list of media to exclude.
-        /// </summary>
-        MyMediaExcludes = 8,
-
-        /// <summary>
-        /// A list of grouped folders.
-        /// </summary>
-        GroupedFolders = 9,
-
-        /// <summary>
-        /// A list of unrated items to block.
-        /// </summary>
-        BlockUnratedItems = 10,
-
-        /// <summary>
-        /// A list of ordered views.
-        /// </summary>
-        OrderedViews = 11,
-
-        /// <summary>
-        /// A list of allowed tags.
-        /// </summary>
-        AllowedTags = 12
-    }
-}

+ 0 - 18
Jellyfin.Data/Enums/ScrollDirection.cs

@@ -1,18 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing the axis that should be scrolled.
-    /// </summary>
-    public enum ScrollDirection
-    {
-        /// <summary>
-        /// Horizontal scrolling direction.
-        /// </summary>
-        Horizontal = 0,
-
-        /// <summary>
-        /// Vertical scrolling direction.
-        /// </summary>
-        Vertical = 1
-    }
-}

+ 0 - 18
Jellyfin.Data/Enums/SortOrder.cs

@@ -1,18 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing the sorting order.
-    /// </summary>
-    public enum SortOrder
-    {
-        /// <summary>
-        /// Sort in increasing order.
-        /// </summary>
-        Ascending = 0,
-
-        /// <summary>
-        /// Sort in decreasing order.
-        /// </summary>
-        Descending = 1
-    }
-}

+ 0 - 33
Jellyfin.Data/Enums/SubtitlePlaybackMode.cs

@@ -1,33 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing a subtitle playback mode.
-    /// </summary>
-    public enum SubtitlePlaybackMode
-    {
-        /// <summary>
-        /// The default subtitle playback mode.
-        /// </summary>
-        Default = 0,
-
-        /// <summary>
-        /// Always show subtitles.
-        /// </summary>
-        Always = 1,
-
-        /// <summary>
-        /// Only show forced subtitles.
-        /// </summary>
-        OnlyForced = 2,
-
-        /// <summary>
-        /// Don't show subtitles.
-        /// </summary>
-        None = 3,
-
-        /// <summary>
-        /// Only show subtitles when the current audio stream is in a different language.
-        /// </summary>
-        Smart = 4
-    }
-}

+ 0 - 23
Jellyfin.Data/Enums/SyncPlayUserAccessType.cs

@@ -1,23 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// Enum SyncPlayUserAccessType.
-    /// </summary>
-    public enum SyncPlayUserAccessType
-    {
-        /// <summary>
-        /// User can create groups and join them.
-        /// </summary>
-        CreateAndJoinGroups = 0,
-
-        /// <summary>
-        /// User can only join already existing groups.
-        /// </summary>
-        JoinGroups = 1,
-
-        /// <summary>
-        /// SyncPlay is disabled for the user.
-        /// </summary>
-        None = 2
-    }
-}

+ 0 - 113
Jellyfin.Data/Enums/ViewType.cs

@@ -1,113 +0,0 @@
-namespace Jellyfin.Data.Enums
-{
-    /// <summary>
-    /// An enum representing the type of view for a library or collection.
-    /// </summary>
-    public enum ViewType
-    {
-        /// <summary>
-        /// Shows albums.
-        /// </summary>
-        Albums = 0,
-
-        /// <summary>
-        /// Shows album artists.
-        /// </summary>
-        AlbumArtists = 1,
-
-        /// <summary>
-        /// Shows artists.
-        /// </summary>
-        Artists = 2,
-
-        /// <summary>
-        /// Shows channels.
-        /// </summary>
-        Channels = 3,
-
-        /// <summary>
-        /// Shows collections.
-        /// </summary>
-        Collections = 4,
-
-        /// <summary>
-        /// Shows episodes.
-        /// </summary>
-        Episodes = 5,
-
-        /// <summary>
-        /// Shows favorites.
-        /// </summary>
-        Favorites = 6,
-
-        /// <summary>
-        /// Shows genres.
-        /// </summary>
-        Genres = 7,
-
-        /// <summary>
-        /// Shows guide.
-        /// </summary>
-        Guide = 8,
-
-        /// <summary>
-        /// Shows movies.
-        /// </summary>
-        Movies = 9,
-
-        /// <summary>
-        /// Shows networks.
-        /// </summary>
-        Networks = 10,
-
-        /// <summary>
-        /// Shows playlists.
-        /// </summary>
-        Playlists = 11,
-
-        /// <summary>
-        /// Shows programs.
-        /// </summary>
-        Programs = 12,
-
-        /// <summary>
-        /// Shows recordings.
-        /// </summary>
-        Recordings = 13,
-
-        /// <summary>
-        /// Shows schedule.
-        /// </summary>
-        Schedule = 14,
-
-        /// <summary>
-        /// Shows series.
-        /// </summary>
-        Series = 15,
-
-        /// <summary>
-        /// Shows shows.
-        /// </summary>
-        Shows = 16,
-
-        /// <summary>
-        /// Shows songs.
-        /// </summary>
-        Songs = 17,
-
-        /// <summary>
-        /// Shows songs.
-        /// </summary>
-        Suggestions = 18,
-
-        /// <summary>
-        /// Shows trailers.
-        /// </summary>
-        Trailers = 19,
-
-        /// <summary>
-        /// Shows upcoming.
-        /// </summary>
-        Upcoming = 20
-    }
-}

+ 1 - 1
Jellyfin.Data/Events/Users/UserCreatedEventArgs.cs

@@ -1,4 +1,4 @@
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 
 namespace Jellyfin.Data.Events.Users
 {

+ 1 - 1
Jellyfin.Data/Events/Users/UserDeletedEventArgs.cs

@@ -1,4 +1,4 @@
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 
 namespace Jellyfin.Data.Events.Users
 {

+ 1 - 1
Jellyfin.Data/Events/Users/UserLockedOutEventArgs.cs

@@ -1,4 +1,4 @@
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 
 namespace Jellyfin.Data.Events.Users
 {

+ 1 - 1
Jellyfin.Data/Events/Users/UserPasswordChangedEventArgs.cs

@@ -1,4 +1,4 @@
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 
 namespace Jellyfin.Data.Events.Users
 {

+ 1 - 1
Jellyfin.Data/Events/Users/UserUpdatedEventArgs.cs

@@ -1,4 +1,4 @@
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 
 namespace Jellyfin.Data.Events.Users
 {

+ 0 - 18
Jellyfin.Data/Interfaces/IHasConcurrencyToken.cs

@@ -1,18 +0,0 @@
-namespace Jellyfin.Data.Interfaces
-{
-    /// <summary>
-    /// An interface abstracting an entity that has a concurrency token.
-    /// </summary>
-    public interface IHasConcurrencyToken
-    {
-        /// <summary>
-        /// Gets the version of this row. Acts as a concurrency token.
-        /// </summary>
-        uint RowVersion { get; }
-
-        /// <summary>
-        /// Called when saving changes to this entity.
-        /// </summary>
-        void OnSavingChanges();
-    }
-}

+ 0 - 31
Jellyfin.Data/Interfaces/IHasPermissions.cs

@@ -1,31 +0,0 @@
-using System.Collections.Generic;
-using Jellyfin.Data.Entities;
-using Jellyfin.Data.Enums;
-
-namespace Jellyfin.Data.Interfaces
-{
-    /// <summary>
-    /// An abstraction representing an entity that has permissions.
-    /// </summary>
-    public interface IHasPermissions
-    {
-        /// <summary>
-        /// Gets a collection containing this entity's permissions.
-        /// </summary>
-        ICollection<Permission> Permissions { get; }
-
-        /// <summary>
-        /// Checks whether this entity has the specified permission kind.
-        /// </summary>
-        /// <param name="kind">The kind of permission.</param>
-        /// <returns><c>true</c> if this entity has the specified permission, <c>false</c> otherwise.</returns>
-        bool HasPermission(PermissionKind kind);
-
-        /// <summary>
-        /// Sets the specified permission to the provided value.
-        /// </summary>
-        /// <param name="kind">The kind of permission.</param>
-        /// <param name="value">The value to set.</param>
-        void SetPermission(PermissionKind kind, bool value);
-    }
-}

+ 0 - 16
Jellyfin.Data/Interfaces/IHasReleases.cs

@@ -1,16 +0,0 @@
-using System.Collections.Generic;
-using Jellyfin.Data.Entities.Libraries;
-
-namespace Jellyfin.Data.Interfaces
-{
-    /// <summary>
-    /// An abstraction representing an entity that has releases.
-    /// </summary>
-    public interface IHasReleases
-    {
-        /// <summary>
-        /// Gets a collection containing this entity's releases.
-        /// </summary>
-        ICollection<Release> Releases { get; }
-    }
-}

+ 4 - 0
Jellyfin.Data/Jellyfin.Data.csproj

@@ -38,6 +38,10 @@
     <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" />
   </ItemGroup>
 
+  <ItemGroup>
+    <ProjectReference Include="..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
+  </ItemGroup>
+
   <ItemGroup>
     <PackageReference Include="Microsoft.Extensions.Logging" />
   </ItemGroup>

+ 220 - 0
Jellyfin.Data/UserEntityExtensions.cs

@@ -0,0 +1,220 @@
+using System;
+using System.ComponentModel;
+using System.Linq;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Enums;
+using Jellyfin.Database.Implementations.Interfaces;
+
+namespace Jellyfin.Data;
+
+/// <summary>
+/// Contains extension methods for manipulation of <see cref="User"/> entities.
+/// </summary>
+public static class UserEntityExtensions
+{
+    /// <summary>
+    /// The values being delimited here are Guids, so commas work as they do not appear in Guids.
+    /// </summary>
+    private const char Delimiter = ',';
+
+    /// <summary>
+    /// Checks whether the user has the specified permission.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <param name="kind">The permission kind.</param>
+    /// <returns><c>True</c> if the user has the specified permission.</returns>
+    public static bool HasPermission(this IHasPermissions entity, PermissionKind kind)
+    {
+        return entity.Permissions.FirstOrDefault(p => p.Kind == kind)?.Value ?? false;
+    }
+
+    /// <summary>
+    /// Sets the given permission kind to the provided value.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <param name="kind">The permission kind.</param>
+    /// <param name="value">The value to set.</param>
+    public static void SetPermission(this IHasPermissions entity, PermissionKind kind, bool value)
+    {
+        var currentPermission = entity.Permissions.FirstOrDefault(p => p.Kind == kind);
+        if (currentPermission is null)
+        {
+            entity.Permissions.Add(new Permission(kind, value));
+        }
+        else
+        {
+            currentPermission.Value = value;
+        }
+    }
+
+    /// <summary>
+    /// Gets the user's preferences for the given preference kind.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <param name="preference">The preference kind.</param>
+    /// <returns>A string array containing the user's preferences.</returns>
+    public static string[] GetPreference(this User entity, PreferenceKind preference)
+    {
+        var val = entity.Preferences.FirstOrDefault(p => p.Kind == preference)?.Value;
+
+        return string.IsNullOrEmpty(val) ? Array.Empty<string>() : val.Split(Delimiter);
+    }
+
+    /// <summary>
+    /// Gets the user's preferences for the given preference kind.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <param name="preference">The preference kind.</param>
+    /// <typeparam name="T">Type of preference.</typeparam>
+    /// <returns>A {T} array containing the user's preference.</returns>
+    public static T[] GetPreferenceValues<T>(this User entity, PreferenceKind preference)
+    {
+        var val = entity.Preferences.FirstOrDefault(p => p.Kind == preference)?.Value;
+        if (string.IsNullOrEmpty(val))
+        {
+            return Array.Empty<T>();
+        }
+
+        // Convert array of {string} to array of {T}
+        var converter = TypeDescriptor.GetConverter(typeof(T));
+        var stringValues = val.Split(Delimiter);
+        var convertedCount = 0;
+        var parsedValues = new T[stringValues.Length];
+        for (var i = 0; i < stringValues.Length; i++)
+        {
+            try
+            {
+                var parsedValue = converter.ConvertFromString(stringValues[i].Trim());
+                if (parsedValue is not null)
+                {
+                    parsedValues[convertedCount++] = (T)parsedValue;
+                }
+            }
+            catch (FormatException)
+            {
+                // Unable to convert value
+            }
+        }
+
+        return parsedValues[..convertedCount];
+    }
+
+    /// <summary>
+    /// Sets the specified preference to the given value.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <param name="preference">The preference kind.</param>
+    /// <param name="values">The values.</param>
+    public static void SetPreference(this User entity, PreferenceKind preference, string[] values)
+    {
+        var value = string.Join(Delimiter, values);
+        var currentPreference = entity.Preferences.FirstOrDefault(p => p.Kind == preference);
+        if (currentPreference is null)
+        {
+            entity.Preferences.Add(new Preference(preference, value));
+        }
+        else
+        {
+            currentPreference.Value = value;
+        }
+    }
+
+    /// <summary>
+    /// Sets the specified preference to the given value.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <param name="preference">The preference kind.</param>
+    /// <param name="values">The values.</param>
+    /// <typeparam name="T">The type of value.</typeparam>
+    public static void SetPreference<T>(this User entity, PreferenceKind preference, T[] values)
+    {
+        var value = string.Join(Delimiter, values);
+        var currentPreference = entity.Preferences.FirstOrDefault(p => p.Kind == preference);
+        if (currentPreference is null)
+        {
+            entity.Preferences.Add(new Preference(preference, value));
+        }
+        else
+        {
+            currentPreference.Value = value;
+        }
+    }
+
+    /// <summary>
+    /// Checks whether this user is currently allowed to use the server.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <returns><c>True</c> if the current time is within an access schedule, or there are no access schedules.</returns>
+    public static bool IsParentalScheduleAllowed(this User entity)
+    {
+        return entity.AccessSchedules.Count == 0
+               || entity.AccessSchedules.Any(i => IsParentalScheduleAllowed(i, DateTime.UtcNow));
+    }
+
+    /// <summary>
+    /// Checks whether the provided folder is in this user's grouped folders.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    /// <param name="id">The Guid of the folder.</param>
+    /// <returns><c>True</c> if the folder is in the user's grouped folders.</returns>
+    public static bool IsFolderGrouped(this User entity, Guid id)
+    {
+        return Array.IndexOf(GetPreferenceValues<Guid>(entity, PreferenceKind.GroupedFolders), id) != -1;
+    }
+
+    /// <summary>
+    /// Initializes the default permissions for a user. Should only be called on user creation.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    // TODO: make these user configurable?
+    public static void AddDefaultPermissions(this User entity)
+    {
+        entity.Permissions.Add(new Permission(PermissionKind.IsAdministrator, false));
+        entity.Permissions.Add(new Permission(PermissionKind.IsDisabled, false));
+        entity.Permissions.Add(new Permission(PermissionKind.IsHidden, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableAllChannels, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableAllDevices, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableAllFolders, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableContentDeletion, false));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableContentDownloading, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableMediaConversion, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableMediaPlayback, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnablePlaybackRemuxing, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnablePublicSharing, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableRemoteAccess, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableSyncTranscoding, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableAudioPlaybackTranscoding, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableLiveTvAccess, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableLiveTvManagement, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableSharedDeviceControl, true));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableVideoPlaybackTranscoding, true));
+        entity.Permissions.Add(new Permission(PermissionKind.ForceRemoteSourceTranscoding, false));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableRemoteControlOfOtherUsers, false));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableCollectionManagement, false));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableSubtitleManagement, false));
+        entity.Permissions.Add(new Permission(PermissionKind.EnableLyricManagement, false));
+    }
+
+    /// <summary>
+    /// Initializes the default preferences. Should only be called on user creation.
+    /// </summary>
+    /// <param name="entity">The entity to update.</param>
+    public static void AddDefaultPreferences(this User entity)
+    {
+        foreach (var val in Enum.GetValues<PreferenceKind>())
+        {
+            entity.Preferences.Add(new Preference(val, string.Empty));
+        }
+    }
+
+    private static bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date)
+    {
+        var localTime = date.ToLocalTime();
+        var hour = localTime.TimeOfDay.TotalHours;
+        var currentDayOfWeek = localTime.DayOfWeek;
+
+        return schedule.DayOfWeek.Contains(currentDayOfWeek)
+               && hour >= schedule.StartHour
+               && hour <= schedule.EndHour;
+    }
+}

+ 2 - 1
Jellyfin.Server.Implementations/Activity/ActivityManager.cs

@@ -1,9 +1,10 @@
 using System;
 using System.Linq;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Events;
 using Jellyfin.Data.Queries;
+using Jellyfin.Database.Implementations;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Querying;
 using Microsoft.EntityFrameworkCore;

+ 17 - 0
Jellyfin.Server.Implementations/DbConfiguration/DatabaseConfigurationFactory.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Common.Configuration;
+
+namespace Jellyfin.Server.Implementations.DatabaseConfiguration;
+
+/// <summary>
+/// Factory for constructing a database configuration.
+/// </summary>
+public class DatabaseConfigurationFactory : IConfigurationFactory
+{
+    /// <inheritdoc/>
+    public IEnumerable<ConfigurationStore> GetConfigurations()
+    {
+        yield return new DatabaseConfigurationStore();
+    }
+}

+ 26 - 0
Jellyfin.Server.Implementations/DbConfiguration/DatabaseConfigurationStore.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using Jellyfin.Database.Implementations.DbConfiguration;
+using MediaBrowser.Common.Configuration;
+
+namespace Jellyfin.Server.Implementations.DatabaseConfiguration;
+
+/// <summary>
+/// A configuration that stores database related settings.
+/// </summary>
+public class DatabaseConfigurationStore : ConfigurationStore
+{
+    /// <summary>
+    /// The name of the configuration in the storage.
+    /// </summary>
+    public const string StoreKey = "database";
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DatabaseConfigurationStore"/> class.
+    /// </summary>
+    public DatabaseConfigurationStore()
+    {
+        ConfigurationType = typeof(DatabaseConfigurationOptions);
+        Key = StoreKey;
+    }
+}

+ 5 - 3
Jellyfin.Server.Implementations/Devices/DeviceManager.cs

@@ -3,12 +3,14 @@ using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
+using Jellyfin.Data;
 using Jellyfin.Data.Dtos;
-using Jellyfin.Data.Entities;
-using Jellyfin.Data.Entities.Security;
-using Jellyfin.Data.Enums;
 using Jellyfin.Data.Events;
 using Jellyfin.Data.Queries;
+using Jellyfin.Database.Implementations;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Database.Implementations.Entities.Security;
+using Jellyfin.Database.Implementations.Enums;
 using Jellyfin.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Devices;

+ 1 - 1
Jellyfin.Server.Implementations/Events/Consumers/Library/LyricDownloadFailureLogger.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Globalization;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Events;

+ 1 - 1
Jellyfin.Server.Implementations/Events/Consumers/Library/SubtitleDownloadFailureLogger.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Globalization;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Events;

+ 1 - 1
Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationFailedLogger.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Globalization;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Events;
 using MediaBrowser.Controller.Events.Authentication;
 using MediaBrowser.Model.Activity;

+ 1 - 1
Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs

@@ -1,6 +1,6 @@
 using System.Globalization;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Events;
 using MediaBrowser.Controller.Events.Authentication;
 using MediaBrowser.Model.Activity;

+ 1 - 1
Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs

@@ -1,8 +1,8 @@
 using System;
 using System.Globalization;
 using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
 using MediaBrowser.Controller.Events;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Activity;

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác