SqliteDatabaseProvider.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System;
  2. using Jellyfin.Server.Implementations;
  3. using MediaBrowser.Common.Configuration;
  4. using Microsoft.Data.Sqlite;
  5. using Microsoft.EntityFrameworkCore;
  6. using Microsoft.Extensions.Logging;
  7. namespace Jellyfin.Database.Providers.SqLite;
  8. /// <summary>
  9. /// Configures jellyfin to use an SQLite database.
  10. /// </summary>
  11. [JellyfinDatabaseProviderKey("Jellyfin-SQLite")]
  12. public sealed class SqliteDatabaseProvider : IJellyfinDatabaseProvider
  13. {
  14. private readonly IApplicationPaths _applicationPaths;
  15. private readonly ILogger<SqliteDatabaseProvider> _logger;
  16. /// <summary>
  17. /// Initializes a new instance of the <see cref="SqliteDatabaseProvider"/> class.
  18. /// </summary>
  19. /// <param name="applicationPaths">Service to construct the fallback when the old data path configuration is used.</param>
  20. /// <param name="logger">A logger.</param>
  21. public SqliteDatabaseProvider(IApplicationPaths applicationPaths, ILogger<SqliteDatabaseProvider> logger)
  22. {
  23. _applicationPaths = applicationPaths;
  24. _logger = logger;
  25. }
  26. /// <inheritdoc/>
  27. public IDbContextFactory<JellyfinDbContext>? DbContextFactory { get; set; }
  28. /// <inheritdoc/>
  29. public void Initialise(DbContextOptionsBuilder options)
  30. {
  31. options.UseSqlite(
  32. $"Filename={Path.Combine(_applicationPaths.DataPath, "jellyfin.db")};Pooling=false",
  33. sqLiteOptions => sqLiteOptions.MigrationsAssembly(GetType().Assembly));
  34. }
  35. /// <inheritdoc/>
  36. public async Task RunScheduledOptimisation(CancellationToken cancellationToken)
  37. {
  38. var context = await DbContextFactory!.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
  39. await using (context.ConfigureAwait(false))
  40. {
  41. if (context.Database.IsSqlite())
  42. {
  43. await context.Database.ExecuteSqlRawAsync("PRAGMA optimize", cancellationToken).ConfigureAwait(false);
  44. await context.Database.ExecuteSqlRawAsync("VACUUM", cancellationToken).ConfigureAwait(false);
  45. _logger.LogInformation("jellyfin.db optimized successfully!");
  46. }
  47. else
  48. {
  49. _logger.LogInformation("This database doesn't support optimization");
  50. }
  51. }
  52. }
  53. /// <inheritdoc/>
  54. public void OnModelCreating(ModelBuilder modelBuilder)
  55. {
  56. modelBuilder.SetDefaultDateTimeKind(DateTimeKind.Utc);
  57. }
  58. /// <inheritdoc/>
  59. public async Task RunShutdownTask(CancellationToken cancellationToken)
  60. {
  61. // Run before disposing the application
  62. var context = await DbContextFactory!.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
  63. await using (context.ConfigureAwait(false))
  64. {
  65. await context.Database.ExecuteSqlRawAsync("PRAGMA optimize", cancellationToken).ConfigureAwait(false);
  66. }
  67. SqliteConnection.ClearAllPools();
  68. }
  69. }