diff options
| author | Cody Robibero <cody@robibe.ro> | 2025-03-25 21:34:26 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-25 21:34:26 -0600 |
| commit | d848faeb75f0109b5616f1f8405fa85cf734f860 (patch) | |
| tree | 59671ffe495d438cbb9ce095f1c3f26247095291 /Jellyfin.Server | |
| parent | 035ecbdde33ce5b71cd580ebb0c3e1df320f80c7 (diff) | |
| parent | 1b388d729682435b92cb10eba67a1170ecbfcc6c (diff) | |
Merge pull request #13589 from JPVenson/feature/DatabaseRefactor
[Feature] Database code refactor
Diffstat (limited to 'Jellyfin.Server')
| -rw-r--r-- | Jellyfin.Server/CoreAppHost.cs | 8 | ||||
| -rw-r--r-- | Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs | 1 | ||||
| -rw-r--r-- | Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs | 2 | ||||
| -rw-r--r-- | Jellyfin.Server/Jellyfin.Server.csproj | 1 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs | 4 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs | 4 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs | 6 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs | 28 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs | 7 | ||||
| -rw-r--r-- | Jellyfin.Server/Program.cs | 24 | ||||
| -rw-r--r-- | Jellyfin.Server/Startup.cs | 9 |
11 files changed, 45 insertions, 49 deletions
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index d5b6e93b8..f3bf6b805 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -4,13 +4,14 @@ using System.Reflection; using Emby.Server.Implementations; using Emby.Server.Implementations.Session; using Jellyfin.Api.WebSocketListeners; +using Jellyfin.Database.Implementations; using Jellyfin.Drawing; using Jellyfin.Drawing.Skia; using Jellyfin.LiveTv; -using Jellyfin.Server.Implementations; using Jellyfin.Server.Implementations.Activity; using Jellyfin.Server.Implementations.Devices; using Jellyfin.Server.Implementations.Events; +using Jellyfin.Server.Implementations.Extensions; using Jellyfin.Server.Implementations.Security; using Jellyfin.Server.Implementations.Trickplay; using Jellyfin.Server.Implementations.Users; @@ -116,9 +117,12 @@ namespace Jellyfin.Server // Jellyfin.Server yield return typeof(CoreAppHost).Assembly; - // Jellyfin.Server.Implementations + // Jellyfin.Database.Implementations yield return typeof(JellyfinDbContext).Assembly; + // Jellyfin.Server.Implementations + yield return typeof(ServiceCollectionExtensions).Assembly; + // Jellyfin.LiveTv yield return typeof(LiveTvManager).Assembly; } diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 1a327e0f9..c6c3f21fe 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -19,6 +19,7 @@ using Jellyfin.Api.Controllers; using Jellyfin.Api.Formatters; using Jellyfin.Api.ModelBinders; using Jellyfin.Data.Enums; +using Jellyfin.Database.Implementations.Enums; using Jellyfin.Extensions.Json; using Jellyfin.Server.Configuration; using Jellyfin.Server.Filters; diff --git a/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs b/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs index 6b95770ed..7695c0d9e 100644 --- a/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/WebHostBuilderExtensions.cs @@ -85,6 +85,6 @@ public static class WebHostBuilderExtensions logger.LogInformation("Kestrel listening to unix socket {SocketPath}", socketPath); } }) - .UseStartup(_ => new Startup(appHost)); + .UseStartup(context => new Startup(appHost, context.Configuration)); } } diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index ebb12ba4e..452b03efb 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -66,6 +66,7 @@ <ProjectReference Include="..\src\Jellyfin.LiveTv\Jellyfin.LiveTv.csproj" /> <ProjectReference Include="..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" /> <ProjectReference Include="..\src\Jellyfin.MediaEncoding.Hls\Jellyfin.MediaEncoding.Hls.csproj" /> + <ProjectReference Include="..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" /> </ItemGroup> <ItemGroup> diff --git a/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs index 2f23cb1f8..e9fe9abce 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.IO; using Emby.Server.Implementations.Data; -using Jellyfin.Data.Entities; -using Jellyfin.Server.Implementations; +using Jellyfin.Database.Implementations; +using Jellyfin.Database.Implementations.Entities; using MediaBrowser.Controller; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; diff --git a/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs index c845beef2..feaf46c84 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.IO; using Emby.Server.Implementations.Data; -using Jellyfin.Data.Entities.Security; -using Jellyfin.Server.Implementations; +using Jellyfin.Database.Implementations; +using Jellyfin.Database.Implementations.Entities.Security; using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using Microsoft.Data.Sqlite; diff --git a/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs index 502a37cde..a8fa2e52a 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs @@ -5,9 +5,9 @@ using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using Emby.Server.Implementations.Data; -using Jellyfin.Data.Entities; -using Jellyfin.Data.Enums; -using Jellyfin.Server.Implementations; +using Jellyfin.Database.Implementations; +using Jellyfin.Database.Implementations.Entities; +using Jellyfin.Database.Implementations.Enums; using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; diff --git a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs index 9e33eb2a7..214a2f4e6 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs @@ -9,10 +9,11 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text; +using System.Threading; using Emby.Server.Implementations.Data; -using Jellyfin.Data.Entities; +using Jellyfin.Database.Implementations; +using Jellyfin.Database.Implementations.Entities; using Jellyfin.Extensions; -using Jellyfin.Server.Implementations; using Jellyfin.Server.Implementations.Item; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; @@ -20,7 +21,8 @@ using MediaBrowser.Model.Entities; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using Chapter = Jellyfin.Data.Entities.Chapter; +using BaseItemEntity = Jellyfin.Database.Implementations.Entities.BaseItemEntity; +using Chapter = Jellyfin.Database.Implementations.Entities.Chapter; namespace Jellyfin.Server.Migrations.Routines; @@ -33,6 +35,7 @@ public class MigrateLibraryDb : IMigrationRoutine private readonly ILogger<MigrateLibraryDb> _logger; private readonly IServerApplicationPaths _paths; + private readonly IJellyfinDatabaseProvider _jellyfinDatabaseProvider; private readonly IDbContextFactory<JellyfinDbContext> _provider; /// <summary> @@ -41,14 +44,17 @@ public class MigrateLibraryDb : IMigrationRoutine /// <param name="logger">The logger.</param> /// <param name="provider">The database provider.</param> /// <param name="paths">The server application paths.</param> + /// <param name="jellyfinDatabaseProvider">The database provider for special access.</param> public MigrateLibraryDb( ILogger<MigrateLibraryDb> logger, IDbContextFactory<JellyfinDbContext> provider, - IServerApplicationPaths paths) + IServerApplicationPaths paths, + IJellyfinDatabaseProvider jellyfinDatabaseProvider) { _logger = logger; _provider = provider; _paths = paths; + _jellyfinDatabaseProvider = jellyfinDatabaseProvider; } /// <inheritdoc/> @@ -120,7 +126,7 @@ public class MigrateLibraryDb : IMigrationRoutine dbContext.ItemValues.ExecuteDelete(); // EFCores local lookup sucks. We cannot use context.ItemValues.Local here because its just super slow. - var localItems = new Dictionary<(int Type, string CleanValue), (ItemValue ItemValue, List<Guid> ItemIds)>(); + var localItems = new Dictionary<(int Type, string CleanValue), (Database.Implementations.Entities.ItemValue ItemValue, List<Guid> ItemIds)>(); foreach (SqliteDataReader dto in connection.Query(itemValueQuery)) { @@ -323,17 +329,7 @@ public class MigrateLibraryDb : IMigrationRoutine _logger.LogInformation("Migrating Library db took {0}.", migrationTotalTime); - if (dbContext.Database.IsSqlite()) - { - _logger.LogInformation("Vacuum and Optimise jellyfin.db now."); - dbContext.Database.ExecuteSqlRaw("PRAGMA optimize"); - dbContext.Database.ExecuteSqlRaw("VACUUM"); - _logger.LogInformation("jellyfin.db optimized successfully!"); - } - else - { - _logger.LogInformation("This database doesn't support optimization"); - } + _jellyfinDatabaseProvider.RunScheduledOptimisation(CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); } private UserData? GetUserData(ImmutableArray<User> users, SqliteDataReader dto) diff --git a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs index 7dcae5bd9..c40560660 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs @@ -1,10 +1,11 @@ using System; using System.IO; using Emby.Server.Implementations.Data; -using Jellyfin.Data.Entities; -using Jellyfin.Data.Enums; +using Jellyfin.Data; +using Jellyfin.Database.Implementations; +using Jellyfin.Database.Implementations.Entities; +using Jellyfin.Database.Implementations.Enums; using Jellyfin.Extensions.Json; -using Jellyfin.Server.Implementations; using Jellyfin.Server.Implementations.Users; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 7e50100b0..32814393c 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -4,12 +4,13 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Threading; using System.Threading.Tasks; using CommandLine; using Emby.Server.Implementations; +using Jellyfin.Database.Implementations; using Jellyfin.Server.Extensions; using Jellyfin.Server.Helpers; -using Jellyfin.Server.Implementations; using Jellyfin.Server.ServerSetupApp; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; @@ -164,7 +165,7 @@ namespace Jellyfin.Server // Re-use the host service provider in the app host since ASP.NET doesn't allow a custom service collection. appHost.ServiceProvider = _jellyfinHost.Services; - await appHost.InitializeServices().ConfigureAwait(false); + await appHost.InitializeServices(startupConfig).ConfigureAwait(false); Migrations.MigrationRunner.Run(appHost, _loggerFactory); try @@ -204,23 +205,12 @@ namespace Jellyfin.Server // Don't throw additional exception if startup failed. if (appHost.ServiceProvider is not null) { - var isSqlite = false; _logger.LogInformation("Running query planner optimizations in the database... This might take a while"); - // Run before disposing the application - var context = await appHost.ServiceProvider.GetRequiredService<IDbContextFactory<JellyfinDbContext>>().CreateDbContextAsync().ConfigureAwait(false); - await using (context.ConfigureAwait(false)) - { - if (context.Database.IsSqlite()) - { - isSqlite = true; - await context.Database.ExecuteSqlRawAsync("PRAGMA optimize").ConfigureAwait(false); - } - } - if (isSqlite) - { - SqliteConnection.ClearAllPools(); - } + var databaseProvider = appHost.ServiceProvider.GetRequiredService<IJellyfinDatabaseProvider>(); + using var shutdownSource = new CancellationTokenSource(); + shutdownSource.CancelAfter((int)TimeSpan.FromSeconds(60).TotalMicroseconds); + await databaseProvider.RunShutdownTask(shutdownSource.Token).ConfigureAwait(false); } _appHost = null; diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index c68661469..688b16935 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -6,6 +6,7 @@ using System.Net.Mime; using System.Text; using Emby.Server.Implementations.EntryPoints; using Jellyfin.Api.Middleware; +using Jellyfin.Database.Implementations; using Jellyfin.LiveTv.Extensions; using Jellyfin.LiveTv.Recordings; using Jellyfin.MediaEncoding.Hls.Extensions; @@ -13,7 +14,6 @@ using Jellyfin.Networking; using Jellyfin.Networking.HappyEyeballs; using Jellyfin.Server.Extensions; using Jellyfin.Server.HealthChecks; -using Jellyfin.Server.Implementations; using Jellyfin.Server.Implementations.Extensions; using Jellyfin.Server.Infrastructure; using MediaBrowser.Common.Net; @@ -39,15 +39,18 @@ namespace Jellyfin.Server public class Startup { private readonly CoreAppHost _serverApplicationHost; + private readonly IConfiguration _configuration; private readonly IServerConfigurationManager _serverConfigurationManager; /// <summary> /// Initializes a new instance of the <see cref="Startup" /> class. /// </summary> /// <param name="appHost">The server application host.</param> - public Startup(CoreAppHost appHost) + /// <param name="configuration">The used Configuration.</param> + public Startup(CoreAppHost appHost, IConfiguration configuration) { _serverApplicationHost = appHost; + _configuration = configuration; _serverConfigurationManager = appHost.ConfigurationManager; } @@ -67,7 +70,7 @@ namespace Jellyfin.Server // TODO remove once this is fixed upstream https://github.com/dotnet/aspnetcore/issues/34371 services.AddSingleton<IActionResultExecutor<PhysicalFileResult>, SymlinkFollowingPhysicalFileResultExecutor>(); services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.GetNetworkConfiguration()); - services.AddJellyfinDbContext(); + services.AddJellyfinDbContext(_serverApplicationHost.ConfigurationManager, _configuration); services.AddJellyfinApiSwagger(); // configure custom legacy authentication |
