2020-05-14 23:30:28 +00:00
using System ;
2020-05-15 18:49:45 +00:00
using System.Globalization ;
2020-05-14 23:30:28 +00:00
using System.IO ;
using MediaBrowser.Controller ;
using Microsoft.Extensions.Logging ;
using SQLitePCL.pretty ;
namespace Jellyfin.Server.Migrations.Routines
{
/// <summary>
/// Remove duplicate entries which were caused by a bug where a file was considered to be an "Extra" to itself.
/// </summary>
2020-05-15 18:32:56 +00:00
internal class RemoveDuplicateExtras : IMigrationRoutine
2020-05-14 23:30:28 +00:00
{
private const string DbFilename = "library.db" ;
private readonly ILogger _logger ;
private readonly IServerApplicationPaths _paths ;
2020-05-15 18:49:45 +00:00
public RemoveDuplicateExtras ( ILogger < RemoveDuplicateExtras > logger , IServerApplicationPaths paths )
2020-05-14 23:30:28 +00:00
{
_logger = logger ;
_paths = paths ;
}
/// <inheritdoc/>
public Guid Id = > Guid . Parse ( "{ACBE17B7-8435-4A83-8B64-6FCF162CB9BD}" ) ;
/// <inheritdoc/>
2020-05-15 18:49:45 +00:00
public string Name = > "RemoveDuplicateExtras" ;
2020-05-14 23:30:28 +00:00
/// <inheritdoc/>
public void Perform ( )
{
var dataPath = _paths . DataPath ;
2020-05-15 18:49:45 +00:00
var dbPath = Path . Combine ( dataPath , DbFilename ) ;
2020-05-14 23:30:28 +00:00
using ( var connection = SQLite3 . Open (
2020-05-15 18:49:45 +00:00
dbPath ,
2020-05-14 23:30:28 +00:00
ConnectionFlags . ReadWrite ,
null ) )
{
var queryResult = connection . Query ( "SELECT t1.Path FROM TypedBaseItems AS t1, TypedBaseItems AS t2 WHERE t1.Path=t2.Path AND t1.Type!=t2.Type AND t1.Type='MediaBrowser.Controller.Entities.Video'" ) ;
var bads = string . Join ( ", " , queryResult . SelectScalarString ( ) ) ;
if ( bads . Length ! = 0 )
{
2020-05-15 18:49:45 +00:00
_logger . LogInformation ( "Found duplicate extras, making {Library} backup" , DbFilename ) ;
for ( int i = 1 ; ; i + + )
{
var bakPath = string . Format ( CultureInfo . InvariantCulture , "{0}.bak{1}" , dbPath , i ) ;
if ( ! File . Exists ( bakPath ) )
{
try
{
File . Copy ( dbPath , bakPath ) ;
break ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Cannot make a backup of {Library}" , DbFilename ) ;
throw ;
}
}
}
2020-05-15 18:32:56 +00:00
_logger . LogInformation ( "Removing found duplicated extras for the following items: {DuplicateExtras}" , bads ) ;
2020-05-14 23:30:28 +00:00
connection . Execute ( "DELETE FROM TypedBaseItems WHERE rowid IN (SELECT t1.rowid FROM TypedBaseItems AS t1, TypedBaseItems AS t2 WHERE t1.Path=t2.Path AND t1.Type!=t2.Type AND t1.Type='MediaBrowser.Controller.Entities.Video')" ) ;
}
}
}
}
}