diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fd29806b..0fe164a85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix QSV HLS segment duration - This behavior caused extremely slow QSV stream starts - Fix displaying multiple languages in UI for movies, artists, shows +- Fix MySQL queries that could fail during media server library scans ### Changed - Upgrade ffmpeg to 6.1, which is now *required* for all installs diff --git a/ErsatzTV.Application/ErsatzTV.Application.csproj b/ErsatzTV.Application/ErsatzTV.Application.csproj index 11f101c74..75412a7a8 100644 --- a/ErsatzTV.Application/ErsatzTV.Application.csproj +++ b/ErsatzTV.Application/ErsatzTV.Application.csproj @@ -21,7 +21,7 @@ - + diff --git a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj index 671d75ea0..984bf0935 100644 --- a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj +++ b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/ErsatzTV.Core/ErsatzTV.Core.csproj b/ErsatzTV.Core/ErsatzTV.Core.csproj index b03bf10ca..addbba088 100644 --- a/ErsatzTV.Core/ErsatzTV.Core.csproj +++ b/ErsatzTV.Core/ErsatzTV.Core.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/ErsatzTV.Core/Interfaces/Repositories/IMediaServerMovieRepository.cs b/ErsatzTV.Core/Interfaces/Repositories/IMediaServerMovieRepository.cs index 5d6289a49..382247856 100644 --- a/ErsatzTV.Core/Interfaces/Repositories/IMediaServerMovieRepository.cs +++ b/ErsatzTV.Core/Interfaces/Repositories/IMediaServerMovieRepository.cs @@ -8,7 +8,7 @@ public interface IMediaServerMovieRepository where T where TEtag : MediaServerItemEtag { Task> GetExistingMovies(TLibrary library); - Task FlagNormal(TLibrary library, TMovie movie); + Task> FlagNormal(TLibrary library, TMovie movie); Task> FlagUnavailable(TLibrary library, TMovie movie); Task> FlagRemoteOnly(TLibrary library, TMovie movie); Task> FlagFileNotFound(TLibrary library, List movieItemIds); diff --git a/ErsatzTV.Core/Interfaces/Repositories/IMediaServerTelevisionRepository.cs b/ErsatzTV.Core/Interfaces/Repositories/IMediaServerTelevisionRepository.cs index 1b9479805..1fac8ecf4 100644 --- a/ErsatzTV.Core/Interfaces/Repositories/IMediaServerTelevisionRepository.cs +++ b/ErsatzTV.Core/Interfaces/Repositories/IMediaServerTelevisionRepository.cs @@ -18,9 +18,9 @@ public interface IMediaServerTelevisionRepository SetEtag(TShow show, string etag); Task SetEtag(TSeason season, string etag); Task SetEtag(TEpisode episode, string etag); - Task FlagNormal(TLibrary library, TEpisode episode); - Task FlagNormal(TLibrary library, TSeason season); - Task FlagNormal(TLibrary library, TShow show); + Task> FlagNormal(TLibrary library, TEpisode episode); + Task> FlagNormal(TLibrary library, TSeason season); + Task> FlagNormal(TLibrary library, TShow show); Task> FlagFileNotFoundShows(TLibrary library, List showItemIds); Task> FlagFileNotFoundSeasons(TLibrary library, List seasonItemIds); Task> FlagFileNotFoundEpisodes(TLibrary library, List episodeItemIds); diff --git a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj index 068847e73..058f07d3b 100644 --- a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj +++ b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj @@ -10,7 +10,7 @@ - + diff --git a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj index e3f26d87c..e1506cd56 100644 --- a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj +++ b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj @@ -18,7 +18,7 @@ - + diff --git a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj index 304bac943..cf4002885 100644 --- a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj +++ b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj @@ -14,9 +14,9 @@ - - - + + + diff --git a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj index 5f7459c63..22642ba50 100644 --- a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj +++ b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj @@ -14,7 +14,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ErsatzTV.Infrastructure/Data/Repositories/EmbyMovieRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/EmbyMovieRepository.cs index 0dd4bc39d..8e0d3f341 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/EmbyMovieRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/EmbyMovieRepository.cs @@ -35,19 +35,27 @@ public class EmbyMovieRepository : IEmbyMovieRepository .Map(result => result.ToList()); } - public async Task FlagNormal(EmbyLibrary library, EmbyMovie movie) + public async Task> FlagNormal(EmbyLibrary library, EmbyMovie movie) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); movie.State = MediaItemState.Normal; - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT EmbyMovie.Id FROM EmbyMovie - INNER JOIN MediaItem MI ON MI.Id = EmbyMovie.Id - INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE EmbyMovie.ItemId = @ItemId)", - new { LibraryId = library.Id, movie.ItemId }).Map(count => count > 0); + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT EmbyMovie.Id FROM EmbyMovie + INNER JOIN MediaItem MI ON MI.Id = EmbyMovie.Id + INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId + WHERE EmbyMovie.ItemId = @ItemId", + new { LibraryId = library.Id, movie.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } public async Task> FlagUnavailable(EmbyLibrary library, EmbyMovie movie) diff --git a/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs index 65a430bfc..baebf60e7 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs @@ -205,49 +205,73 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository new { Etag = etag, episode.Id }).Map(_ => Unit.Default); } - public async Task FlagNormal(EmbyLibrary library, EmbyEpisode episode) + public async Task> FlagNormal(EmbyLibrary library, EmbyEpisode episode) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); episode.State = MediaItemState.Normal; - - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT EmbyEpisode.Id FROM EmbyEpisode + + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT EmbyEpisode.Id FROM EmbyEpisode INNER JOIN MediaItem MI ON MI.Id = EmbyEpisode.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE EmbyEpisode.ItemId = @ItemId)", - new { LibraryId = library.Id, episode.ItemId }).Map(count => count > 0); + WHERE EmbyEpisode.ItemId = @ItemId", + new { LibraryId = library.Id, episode.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } - public async Task FlagNormal(EmbyLibrary library, EmbySeason season) + public async Task> FlagNormal(EmbyLibrary library, EmbySeason season) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); season.State = MediaItemState.Normal; - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT EmbySeason.Id FROM EmbySeason + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT EmbySeason.Id FROM EmbySeason INNER JOIN MediaItem MI ON MI.Id = EmbySeason.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE EmbySeason.ItemId = @ItemId)", - new { LibraryId = library.Id, season.ItemId }).Map(count => count > 0); + WHERE EmbySeason.ItemId = @ItemId", + new { LibraryId = library.Id, season.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } - public async Task FlagNormal(EmbyLibrary library, EmbyShow show) + public async Task> FlagNormal(EmbyLibrary library, EmbyShow show) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); show.State = MediaItemState.Normal; - - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT EmbyShow.Id FROM EmbyShow + + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT EmbyShow.Id FROM EmbyShow INNER JOIN MediaItem MI ON MI.Id = EmbyShow.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE EmbyShow.ItemId = @ItemId)", - new { LibraryId = library.Id, show.ItemId }).Map(count => count > 0); + WHERE EmbyShow.ItemId = @ItemId", + new { LibraryId = library.Id, show.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } public async Task> FlagFileNotFoundShows(EmbyLibrary library, List showItemIds) diff --git a/ErsatzTV.Infrastructure/Data/Repositories/JellyfinMovieRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/JellyfinMovieRepository.cs index 3e87fc428..3f5a6407f 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/JellyfinMovieRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/JellyfinMovieRepository.cs @@ -37,19 +37,27 @@ public class JellyfinMovieRepository : IJellyfinMovieRepository .Map(result => result.ToList()); } - public async Task FlagNormal(JellyfinLibrary library, JellyfinMovie movie) + public async Task> FlagNormal(JellyfinLibrary library, JellyfinMovie movie) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); movie.State = MediaItemState.Normal; - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT JellyfinMovie.Id FROM JellyfinMovie - INNER JOIN MediaItem MI ON MI.Id = JellyfinMovie.Id - INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE JellyfinMovie.ItemId = @ItemId)", - new { LibraryId = library.Id, movie.ItemId }).Map(count => count > 0); + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT JellyfinMovie.Id FROM JellyfinMovie + INNER JOIN MediaItem MI ON MI.Id = JellyfinMovie.Id + INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId + WHERE JellyfinMovie.ItemId = @ItemId", + new { LibraryId = library.Id, movie.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } public async Task> FlagUnavailable(JellyfinLibrary library, JellyfinMovie movie) diff --git a/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs index 65b8684b9..9dd542942 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs @@ -209,49 +209,73 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository new { Etag = etag, episode.Id }).Map(_ => Unit.Default); } - public async Task FlagNormal(JellyfinLibrary library, JellyfinEpisode episode) + public async Task> FlagNormal(JellyfinLibrary library, JellyfinEpisode episode) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); episode.State = MediaItemState.Normal; - - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT JellyfinEpisode.Id FROM JellyfinEpisode + + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT JellyfinEpisode.Id FROM JellyfinEpisode INNER JOIN MediaItem MI ON MI.Id = JellyfinEpisode.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE JellyfinEpisode.ItemId = @ItemId)", - new { LibraryId = library.Id, episode.ItemId }).Map(count => count > 0); + WHERE JellyfinEpisode.ItemId = @ItemId", + new { LibraryId = library.Id, episode.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } - public async Task FlagNormal(JellyfinLibrary library, JellyfinSeason season) + public async Task> FlagNormal(JellyfinLibrary library, JellyfinSeason season) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); season.State = MediaItemState.Normal; - - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT JellyfinSeason.Id FROM JellyfinSeason + + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT JellyfinSeason.Id FROM JellyfinSeason INNER JOIN MediaItem MI ON MI.Id = JellyfinSeason.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE JellyfinSeason.ItemId = @ItemId)", - new { LibraryId = library.Id, season.ItemId }).Map(count => count > 0); + WHERE JellyfinSeason.ItemId = @ItemId", + new { LibraryId = library.Id, season.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } - public async Task FlagNormal(JellyfinLibrary library, JellyfinShow show) + public async Task> FlagNormal(JellyfinLibrary library, JellyfinShow show) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); show.State = MediaItemState.Normal; - - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT JellyfinShow.Id FROM JellyfinShow + + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT JellyfinShow.Id FROM JellyfinShow INNER JOIN MediaItem MI ON MI.Id = JellyfinShow.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE JellyfinShow.ItemId = @ItemId)", - new { LibraryId = library.Id, show.ItemId }).Map(count => count > 0); + WHERE JellyfinShow.ItemId = @ItemId", + new { LibraryId = library.Id, show.ItemId }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } public async Task> FlagFileNotFoundShows(JellyfinLibrary library, List showItemIds) diff --git a/ErsatzTV.Infrastructure/Data/Repositories/PlexMovieRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/PlexMovieRepository.cs index d02ec1618..3068f70cd 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/PlexMovieRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/PlexMovieRepository.cs @@ -35,19 +35,27 @@ public class PlexMovieRepository : IPlexMovieRepository .Map(result => result.ToList()); } - public async Task FlagNormal(PlexLibrary library, PlexMovie movie) + public async Task> FlagNormal(PlexLibrary library, PlexMovie movie) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); movie.State = MediaItemState.Normal; - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT PlexMovie.Id FROM PlexMovie - INNER JOIN MediaItem MI ON MI.Id = PlexMovie.Id - INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE PlexMovie.Key = @Key)", - new { LibraryId = library.Id, movie.Key }).Map(count => count > 0); + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT PlexMovie.Id FROM PlexMovie + INNER JOIN MediaItem MI ON MI.Id = PlexMovie.Id + INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId + WHERE PlexMovie.Key = @Key", + new { LibraryId = library.Id, movie.Key }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } public async Task> FlagUnavailable(PlexLibrary library, PlexMovie movie) diff --git a/ErsatzTV.Infrastructure/Data/Repositories/PlexTelevisionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/PlexTelevisionRepository.cs index 8e6fff2c9..b7a5dc939 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/PlexTelevisionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/PlexTelevisionRepository.cs @@ -24,49 +24,73 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository _logger = logger; } - public async Task FlagNormal(PlexLibrary library, PlexEpisode episode) + public async Task> FlagNormal(PlexLibrary library, PlexEpisode episode) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); episode.State = MediaItemState.Normal; - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT PlexEpisode.Id FROM PlexEpisode + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT PlexEpisode.Id FROM PlexEpisode INNER JOIN MediaItem MI ON MI.Id = PlexEpisode.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE PlexEpisode.Key = @Key)", - new { LibraryId = library.Id, episode.Key }).Map(count => count > 0); + WHERE PlexEpisode.Key = @Key", + new { LibraryId = library.Id, episode.Key }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } - public async Task FlagNormal(PlexLibrary library, PlexSeason season) + public async Task> FlagNormal(PlexLibrary library, PlexSeason season) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); season.State = MediaItemState.Normal; - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT PlexSeason.Id FROM PlexSeason + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT PlexSeason.Id FROM PlexSeason INNER JOIN MediaItem MI ON MI.Id = PlexSeason.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE PlexSeason.Key = @Key)", - new { LibraryId = library.Id, season.Key }).Map(count => count > 0); + WHERE PlexSeason.Key = @Key", + new { LibraryId = library.Id, season.Key }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } - public async Task FlagNormal(PlexLibrary library, PlexShow show) + public async Task> FlagNormal(PlexLibrary library, PlexShow show) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); show.State = MediaItemState.Normal; - - return await dbContext.Connection.ExecuteAsync( - @"UPDATE MediaItem SET State = 0 WHERE Id IN - (SELECT PlexShow.Id FROM PlexShow + + Option maybeId = await dbContext.Connection.ExecuteScalarAsync( + @"SELECT PlexShow.Id FROM PlexShow INNER JOIN MediaItem MI ON MI.Id = PlexShow.Id INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId - WHERE PlexShow.Key = @Key)", - new { LibraryId = library.Id, show.Key }).Map(count => count > 0); + WHERE PlexShow.Key = @Key", + new { LibraryId = library.Id, show.Key }); + + foreach (int id in maybeId) + { + return await dbContext.Connection.ExecuteAsync( + @"UPDATE MediaItem SET State = 0 WHERE Id = @Id", + new { Id = id }).Map(count => count > 0 ? Some(id) : None); + } + + return None; } public async Task> FlagUnavailable(PlexLibrary library, PlexEpisode episode) diff --git a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj index aa675f21a..34d19c41e 100644 --- a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj +++ b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj @@ -12,18 +12,18 @@ - + - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj index ba0c066fd..b3886e14c 100644 --- a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj +++ b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj @@ -10,12 +10,12 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ErsatzTV.Scanner/Core/Metadata/MediaServerMovieLibraryScanner.cs b/ErsatzTV.Scanner/Core/Metadata/MediaServerMovieLibraryScanner.cs index d09ff38a5..85bb35b3b 100644 --- a/ErsatzTV.Scanner/Core/Metadata/MediaServerMovieLibraryScanner.cs +++ b/ErsatzTV.Scanner/Core/Metadata/MediaServerMovieLibraryScanner.cs @@ -178,7 +178,8 @@ public abstract class MediaServerMovieLibraryScanner flagResult = await movieRepository.FlagNormal(library, result.Item); + if (flagResult.IsSome) { result.IsUpdated = true; } diff --git a/ErsatzTV.Scanner/Core/Metadata/MediaServerTelevisionLibraryScanner.cs b/ErsatzTV.Scanner/Core/Metadata/MediaServerTelevisionLibraryScanner.cs index 5cd0a6852..d90c79c60 100644 --- a/ErsatzTV.Scanner/Core/Metadata/MediaServerTelevisionLibraryScanner.cs +++ b/ErsatzTV.Scanner/Core/Metadata/MediaServerTelevisionLibraryScanner.cs @@ -180,7 +180,8 @@ public abstract class MediaServerTelevisionLibraryScanner flagResult = await televisionRepository.FlagNormal(library, result.Item); + if (flagResult.IsSome) { result.IsUpdated = true; } @@ -364,7 +365,8 @@ public abstract class MediaServerTelevisionLibraryScanner flagResult = await televisionRepository.FlagNormal(library, result.Item); + if (flagResult.IsSome) { result.IsUpdated = true; } @@ -498,7 +500,8 @@ public abstract class MediaServerTelevisionLibraryScanner flagResult = await televisionRepository.FlagNormal(library, result.Item); + if (flagResult.IsSome) { result.IsUpdated = true; } diff --git a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj index 92db9621c..006dabd97 100644 --- a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj +++ b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj @@ -22,7 +22,7 @@ - + diff --git a/ErsatzTV/ErsatzTV.csproj b/ErsatzTV/ErsatzTV.csproj index 393b3238f..20e65c74c 100644 --- a/ErsatzTV/ErsatzTV.csproj +++ b/ErsatzTV/ErsatzTV.csproj @@ -57,17 +57,17 @@ - + - - + + - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -75,8 +75,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + +