< Summary - Jellyfin

Information
Class: Jellyfin.Server.Migrations.Routines.RemoveDuplicateExtras
Assembly: jellyfin
File(s): /srv/git/jellyfin/Jellyfin.Server/Migrations/Routines/RemoveDuplicateExtras.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 30
Coverable lines: 30
Total lines: 83
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 4
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
get_Id()100%210%
get_Name()100%210%
get_PerformOnNewInstall()100%210%
Perform()0%2040%

File(s)

/srv/git/jellyfin/Jellyfin.Server/Migrations/Routines/RemoveDuplicateExtras.cs

#LineLine coverage
 1using System;
 2using System.Globalization;
 3using System.IO;
 4using System.Linq;
 5using Emby.Server.Implementations.Data;
 6using MediaBrowser.Controller;
 7using Microsoft.Data.Sqlite;
 8using Microsoft.Extensions.Logging;
 9
 10namespace Jellyfin.Server.Migrations.Routines
 11{
 12    /// <summary>
 13    /// Remove duplicate entries which were caused by a bug where a file was considered to be an "Extra" to itself.
 14    /// </summary>
 15    internal class RemoveDuplicateExtras : IMigrationRoutine
 16    {
 17        private const string DbFilename = "library.db";
 18        private readonly ILogger<RemoveDuplicateExtras> _logger;
 19        private readonly IServerApplicationPaths _paths;
 20
 21        public RemoveDuplicateExtras(ILogger<RemoveDuplicateExtras> logger, IServerApplicationPaths paths)
 22        {
 023            _logger = logger;
 024            _paths = paths;
 025        }
 26
 27        /// <inheritdoc/>
 028        public Guid Id => Guid.Parse("{ACBE17B7-8435-4A83-8B64-6FCF162CB9BD}");
 29
 30        /// <inheritdoc/>
 031        public string Name => "RemoveDuplicateExtras";
 32
 33        /// <inheritdoc/>
 034        public bool PerformOnNewInstall => false;
 35
 36        /// <inheritdoc/>
 37        public void Perform()
 38        {
 039            var dataPath = _paths.DataPath;
 040            var dbPath = Path.Combine(dataPath, DbFilename);
 041            using var connection = new SqliteConnection($"Filename={dbPath}");
 042            connection.Open();
 043            using (var transaction = connection.BeginTransaction())
 44            {
 45                // Query the database for the ids of duplicate extras
 046                var queryResult = connection.Query("SELECT t1.Path FROM TypedBaseItems AS t1, TypedBaseItems AS t2 WHERE
 047                var bads = string.Join(", ", queryResult.Select(x => x.GetString(0)));
 48
 49                // Do nothing if no duplicate extras were detected
 050                if (bads.Length == 0)
 51                {
 052                    _logger.LogInformation("No duplicate extras detected, skipping migration.");
 053                    return;
 54                }
 55
 56                // Back up the database before deleting any entries
 057                for (int i = 1; ; i++)
 58                {
 059                    var bakPath = string.Format(CultureInfo.InvariantCulture, "{0}.bak{1}", dbPath, i);
 060                    if (!File.Exists(bakPath))
 61                    {
 62                        try
 63                        {
 064                            File.Copy(dbPath, bakPath);
 065                            _logger.LogInformation("Library database backed up to {BackupPath}", bakPath);
 066                            break;
 67                        }
 068                        catch (Exception ex)
 69                        {
 070                            _logger.LogError(ex, "Cannot make a backup of {Library} at path {BackupPath}", DbFilename, b
 071                            throw;
 72                        }
 73                    }
 74                }
 75
 76                // Delete all duplicate extras
 077                _logger.LogInformation("Removing found duplicated extras for the following items: {DuplicateExtras}", ba
 078                connection.Execute("DELETE FROM TypedBaseItems WHERE rowid IN (SELECT t1.rowid FROM TypedBaseItems AS t1
 079                transaction.Commit();
 080            }
 081        }
 82    }
 83}