From aa811eb1e3c78bdf8f4a751311c1bb6d639e851e Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sun, 26 Jan 2025 20:45:28 +0000 Subject: Prepared Seperation of Database components for future multi provider support --- .../SqliteDatabaseProvider.cs | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Jellyfin.Database/Jellyfin.Database.Providers.SqLite/SqliteDatabaseProvider.cs (limited to 'Jellyfin.Database/Jellyfin.Database.Providers.SqLite/SqliteDatabaseProvider.cs') diff --git a/Jellyfin.Database/Jellyfin.Database.Providers.SqLite/SqliteDatabaseProvider.cs b/Jellyfin.Database/Jellyfin.Database.Providers.SqLite/SqliteDatabaseProvider.cs new file mode 100644 index 0000000000..8bc025a0bf --- /dev/null +++ b/Jellyfin.Database/Jellyfin.Database.Providers.SqLite/SqliteDatabaseProvider.cs @@ -0,0 +1,78 @@ +using System; +using Jellyfin.Server.Implementations; +using MediaBrowser.Common.Configuration; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Database.Providers.SqLite; + +/// +/// Configures jellyfin to use an SqLite database. +/// +public sealed class SqliteDatabaseProvider : IJellyfinDatabaseProvider +{ + private readonly IApplicationPaths _applicationPaths; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The Db context to interact with the database. + /// Service to construct the fallback when the old data path configuration is used. + /// A logger. + public SqliteDatabaseProvider(IDbContextFactory dbContextFactory, IApplicationPaths applicationPaths, ILogger logger) + { + DbContextFactory = dbContextFactory; + _applicationPaths = applicationPaths; + _logger = logger; + } + + private IDbContextFactory DbContextFactory { get; } + + /// + public void Initialise(DbContextOptionsBuilder options) + { + options.UseSqlite( + $"Filename={Path.Combine(_applicationPaths.DataPath, "jellyfin.db")};Pooling=false", + sqLiteOptions => sqLiteOptions.MigrationsAssembly(GetType().Assembly)); + } + + /// + public async Task RunScheduledOptimisation(CancellationToken cancellationToken) + { + var context = await DbContextFactory.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"); + } + } + } + + /// + public void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.SetDefaultDateTimeKind(DateTimeKind.Utc); + } + + /// + public async ValueTask DisposeAsync() + { + // Run before disposing the application + var context = await DbContextFactory.CreateDbContextAsync().ConfigureAwait(false); + await using (context.ConfigureAwait(false)) + { + await context.Database.ExecuteSqlRawAsync("PRAGMA optimize").ConfigureAwait(false); + } + + SqliteConnection.ClearAllPools(); + } +} -- cgit v1.2.3