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(); } }