Add scripts for PostgreSQL migration and SQLite removal; update project references

- Introduced `publish-with-sql.ps1` to publish Jellyfin with SQL files.
- Added `remove-sqlite.ps1` to facilitate the removal of SQLite dependencies for PostgreSQL-only deployment.
- Created `rollback-to-net10.ps1` to revert .NET 11 changes back to .NET 10.
- Implemented `test_api.py` for testing API interactions.
- Added `verify-migration.ps1` to verify PostgreSQL migration steps.
- Updated various `.csproj` files to include `Microsoft.Kiota.Abstractions` package.
- Enhanced `JellyfinDbContext` to handle concurrency exceptions during save operations.
- Updated tests to include new package references and ensure compatibility with changes.
This commit is contained in:
2026-07-07 10:59:40 -04:00
parent bf51bff748
commit 9bcb8501ab
70 changed files with 1370 additions and 13 deletions
@@ -3,12 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Queries;
using Jellyfin.Extensions.Dapper;
using Jellyfin.Database.Implementations;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Server.Implementations.ScheduledTasks
@@ -19,17 +19,17 @@ namespace Jellyfin.Server.Implementations.ScheduledTasks
public class PostgresPeriodicTuner : IScheduledTask, IConfigurableScheduledTask
{
private readonly ILogger<PostgresPeriodicTuner> _logger;
private readonly IDbContext _dbContext;
private readonly IDbContextFactory<JellyfinDbContext> _dbContextFactory;
/// <summary>
/// Initializes a new instance of the <see cref="PostgresPeriodicTuner"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="dbContext">The database context.</param>
public PostgresPeriodicTuner(ILogger<PostgresPeriodicTuner> logger, IDbContext dbContext)
/// <param name="dbContextFactory">The database context factory.</param>
public PostgresPeriodicTuner(ILogger<PostgresPeriodicTuner> logger, IDbContextFactory<JellyfinDbContext> dbContextFactory)
{
_logger = logger;
_dbContext = dbContext;
_dbContextFactory = dbContextFactory;
}
/// <inheritdoc />
@@ -56,15 +56,17 @@ namespace Jellyfin.Server.Implementations.ScheduledTasks
/// <summary>
/// Executes the task.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task ExecuteAsync(CancellationToken cancellationToken, IProgress<double> progress)
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
_logger.LogInformation("PostgreSQL Periodic Tuner task started.");
try
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
const string DeadTupleQuery = @"
SELECT
relname AS TableName,
@@ -76,7 +78,7 @@ namespace Jellyfin.Server.Implementations.ScheduledTasks
ORDER BY
n_dead_tup DESC;";
var tablesToVacuum = (await _dbContext.QueryAsync<(string TableName, long DeadTuples)>(DeadTupleQuery)).ToList();
var tablesToVacuum = (await dbContext.Database.SqlQueryRaw<(string TableName, long DeadTuples)>(DeadTupleQuery).ToListAsync(cancellationToken).ConfigureAwait(false)).ToList();
if (tablesToVacuum.Count == 0)
{
@@ -96,7 +98,7 @@ namespace Jellyfin.Server.Implementations.ScheduledTasks
try
{
await _dbContext.ExecuteAsync($"VACUUM ANALYZE \"{table.TableName}\"");
await dbContext.Database.ExecuteSqlInterpolatedAsync($"VACUUM ANALYZE \"{table.TableName}\"", cancellationToken).ConfigureAwait(false);
_logger.LogInformation("Successfully vacuumed and analyzed table {TableName}.", table.TableName);
}
catch (Exception ex)
@@ -129,7 +131,7 @@ namespace Jellyfin.Server.Implementations.ScheduledTasks
{
new TaskTriggerInfo
{
Type = TaskTriggerInfo.TriggerInterval,
Type = TaskTriggerInfoType.IntervalTrigger,
IntervalTicks = TimeSpan.FromHours(24).Ticks
}
};