diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/161_fix_pending_releasesFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/161_fix_pending_releasesFixture.cs new file mode 100644 index 000000000..a77097adb --- /dev/null +++ b/src/NzbDrone.Core.Test/Datastore/Migration/161_fix_pending_releasesFixture.cs @@ -0,0 +1,85 @@ +using System; +using System.Linq; +using Dapper; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Datastore.Migration; +using NzbDrone.Core.Download.Pending; +using NzbDrone.Core.Languages; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Qualities; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.Datastore.Migration +{ + [TestFixture] + public class fix_pending_releasesFixture : MigrationTest + { + [Test] + public void should_fix_quality_for_pending_releases() + { + var db = WithDapperMigrationTestDb(c => + { + c.Insert.IntoTable("PendingReleases").Row(new + { + SeriesId = 1, + Title = "Test Series", + Added = DateTime.UtcNow, + ParsedEpisodeInfo = @"{ + ""releaseTitle"": ""Nurses.2020.S02E10.720p.HDTV.x264 - SYNCOPY"", + ""seriesTitle"": ""Nurses 2020"", + ""seriesTitleInfo"": { + ""title"": ""Nurses 2020"", + ""titleWithoutYear"": ""Nurses"", + ""year"": 2020 + }, + ""quality"": { + ""quality"": { + ""id"": 4, + ""name"": ""HDTV-720p"", + ""source"": ""television"", + ""resolution"": 720 + }, + ""revision"": { + ""version"": 1, + ""real"": 0, + ""isRepack"": false + } + }, + ""seasonNumber"": 2, + ""episodeNumbers"": [ + 10 + ], + ""absoluteEpisodeNumbers"": [], + ""specialAbsoluteEpisodeNumbers"": [], + ""language"": { + ""id"": 1, + ""name"": ""English"" + }, + ""fullSeason"": false, + ""isPartialSeason"": false, + ""isMultiSeason"": false, + ""isSeasonExtra"": false, + ""special"": false, + ""releaseGroup"": ""SYNCOPY"", + ""releaseHash"": """", + ""seasonPart"": 0, + ""releaseTokens"": "".720p.HDTV.x264-SYNCOPY"", + ""isDaily"": false, + ""isAbsoluteNumbering"": false, + ""isPossibleSpecialEpisode"": false, + ""isPossibleSceneSeasonSpecial"": false +}", + Release = "{}", + Reason = PendingReleaseReason.Delay + }); + }); + + var json = db.Query("SELECT ParsedEpisodeInfo FROM PendingReleases").First(); + + var pending = db.Query("SELECT ParsedEpisodeInfo FROM PendingReleases").First(); + pending.Quality.Quality.Should().Be(Quality.HDTV720p); + pending.Language.Should().Be(Language.English); + } + } +} diff --git a/src/NzbDrone.Core/Datastore/Migration/161_remove_plex_hometheater.cs b/src/NzbDrone.Core/Datastore/Migration/161_remove_plex_hometheater.cs index 5829089ee..49161c511 100644 --- a/src/NzbDrone.Core/Datastore/Migration/161_remove_plex_hometheater.cs +++ b/src/NzbDrone.Core/Datastore/Migration/161_remove_plex_hometheater.cs @@ -1,4 +1,8 @@ -using FluentMigrator; +using System.Collections.Generic; +using System.Data; +using Dapper; +using FluentMigrator; +using NzbDrone.Core.Datastore.Converters; using NzbDrone.Core.Datastore.Migration.Framework; namespace NzbDrone.Core.Datastore.Migration @@ -10,6 +14,161 @@ namespace NzbDrone.Core.Datastore.Migration { Delete.FromTable("Notifications").Row(new { Implementation = "PlexHomeTheater" }); Delete.FromTable("Notifications").Row(new { Implementation = "PlexClient" }); + + // Switch Quality and Language to int in pending releases + Execute.WithConnection(FixPendingReleases); + } + + private void FixPendingReleases(IDbConnection conn, IDbTransaction tran) + { + SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter()); + SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter()); + var rows = conn.Query("SELECT Id, ParsedEpisodeInfo from PendingReleases"); + + var newRows = new List(); + + foreach (var row in rows) + { + var old = row.ParsedEpisodeInfo; + + var newQuality = new QualityModel162 + { + Quality = old.Quality.Quality.Id, + Revision = old.Quality.Revision + }; + + var correct = new ParsedEpisodeInfo162 + { + SeriesTitle = old.SeriesTitle, + SeriesTitleInfo = old.SeriesTitleInfo, + Quality = newQuality, + SeasonNumber = old.SeasonNumber, + SeasonPart = old.SeasonPart, + EpisodeNumbers = old.EpisodeNumbers, + AbsoluteEpisodeNumbers = old.AbsoluteEpisodeNumbers, + SpecialAbsoluteEpisodeNumbers = old.SpecialAbsoluteEpisodeNumbers, + Language = old.Language?.Id ?? 0, + FullSeason = old.FullSeason, + IsPartialSeason = old.IsPartialSeason, + IsMultiSeason = old.IsMultiSeason, + IsSeasonExtra = old.IsSeasonExtra, + Speacial = old.Speacial, + ReleaseGroup = old.ReleaseGroup, + ReleaseHash = old.ReleaseHash, + ReleaseTokens = old.ReleaseTokens, + IsDaily = old.IsDaily, + IsAbsoluteNumbering = old.IsAbsoluteNumbering, + IsPossibleSpecialEpisode = old.IsPossibleSpecialEpisode, + IsPossibleSceneSeasonSpecial = old.IsPossibleSceneSeasonSpecial + }; + + newRows.Add(new ParsedEpisodeInfoData162 + { + Id = row.Id, + ParsedEpisodeInfo = correct + }); + } + + var sql = $"UPDATE PendingReleases SET ParsedEpisodeInfo = @ParsedEpisodeInfo WHERE Id = @Id"; + + conn.Execute(sql, newRows, transaction: tran); + } + + private class ParsedEpisodeInfoData161 : ModelBase + { + public ParsedEpisodeInfo161 ParsedEpisodeInfo { get; set; } + } + + private class ParsedEpisodeInfo161 + { + public string SeriesTitle { get; set; } + public SeriesTitleInfo161 SeriesTitleInfo { get; set; } + public QualityModel161 Quality { get; set; } + public int SeasonNumber { get; set; } + public List EpisodeNumbers { get; set; } + public List AbsoluteEpisodeNumbers { get; set; } + public List SpecialAbsoluteEpisodeNumbers { get; set; } + public Language161 Language { get; set; } + public bool FullSeason { get; set; } + public bool IsPartialSeason { get; set; } + public bool IsMultiSeason { get; set; } + public bool IsSeasonExtra { get; set; } + public bool Speacial { get; set; } + public string ReleaseGroup { get; set; } + public string ReleaseHash { get; set; } + public int SeasonPart { get; set; } + public string ReleaseTokens { get; set; } + public bool IsDaily { get; set; } + public bool IsAbsoluteNumbering { get; set; } + public bool IsPossibleSpecialEpisode { get; set; } + public bool IsPossibleSceneSeasonSpecial { get; set; } + } + + private class SeriesTitleInfo161 + { + public string Title { get; set; } + public string TitleWithoutYear { get; set; } + public int Year { get; set; } + } + + private class QualityModel161 + { + public Quality161 Quality { get; set; } + public Revision162 Revision { get; set; } + } + + private class Language161 + { + public int Id { get; set; } + public string Name { get; set; } + } + + private class Quality161 + { + public int Id { get; set; } + } + + private class ParsedEpisodeInfoData162 : ModelBase + { + public ParsedEpisodeInfo162 ParsedEpisodeInfo { get; set; } + } + + private class ParsedEpisodeInfo162 + { + public string SeriesTitle { get; set; } + public SeriesTitleInfo161 SeriesTitleInfo { get; set; } + public QualityModel162 Quality { get; set; } + public int SeasonNumber { get; set; } + public List EpisodeNumbers { get; set; } + public List AbsoluteEpisodeNumbers { get; set; } + public List SpecialAbsoluteEpisodeNumbers { get; set; } + public int Language { get; set; } + public bool FullSeason { get; set; } + public bool IsPartialSeason { get; set; } + public bool IsMultiSeason { get; set; } + public bool IsSeasonExtra { get; set; } + public bool Speacial { get; set; } + public string ReleaseGroup { get; set; } + public string ReleaseHash { get; set; } + public int SeasonPart { get; set; } + public string ReleaseTokens { get; set; } + public bool IsDaily { get; set; } + public bool IsAbsoluteNumbering { get; set; } + public bool IsPossibleSpecialEpisode { get; set; } + public bool IsPossibleSceneSeasonSpecial { get; set; } + } + + private class QualityModel162 + { + public int Quality { get; set; } + public Revision162 Revision { get; set; } + } + + private class Revision162 + { + public int Version { get; set; } + public int Real { get; set; } + public bool IsRepack { get; set; } } } }