diff --git a/NzbDrone.Core.Test/Framework/DbTest.cs b/NzbDrone.Core.Test/Framework/DbTest.cs index af5330c8b..4fdd67869 100644 --- a/NzbDrone.Core.Test/Framework/DbTest.cs +++ b/NzbDrone.Core.Test/Framework/DbTest.cs @@ -60,8 +60,6 @@ protected TSubject Subject } } - - [Category("DbTest")] public abstract class DbTest : CoreTest { diff --git a/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs b/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs index 3a15958bc..9b8a90643 100644 --- a/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs +++ b/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs @@ -42,71 +42,5 @@ public void should_read_write_dictionary() StoredModel.Data.Should().HaveCount(2); } - - [Test] - public void should_delete_orphaned_items_by_series() - { - var history = Builder.CreateNew().BuildNew(); - Subject.Insert(history); - - Subject.CleanupOrphanedBySeries(); - Subject.All().Should().BeEmpty(); - } - - [Test] - public void should_delete_orphaned_items_by_episode() - { - var history = Builder.CreateNew().BuildNew(); - Subject.Insert(history); - - Subject.CleanupOrphanedByEpisode(); - Subject.All().Should().BeEmpty(); - } - - [Test] - public void should_not_delete_unorphaned_data_by_series() - { - var series = Builder.CreateNew() - .BuildNew(); - - Db.Insert(series); - - var history = Builder.CreateListOfSize(2) - .All() - .With(h => h.Id = 0) - .TheFirst(1) - .With(h => h.SeriesId = series.Id) - .Build(); - - - Subject.InsertMany(history); - - Subject.CleanupOrphanedBySeries(); - Subject.All().Should().HaveCount(1); - Subject.All().Should().Contain(h => h.SeriesId == series.Id); - } - - [Test] - public void should_not_delete_unorphaned_data_by_episode() - { - var episode = Builder.CreateNew() - .BuildNew(); - - Db.Insert(episode); - - var history = Builder.CreateListOfSize(2) - .All() - .With(h => h.Id = 0) - .TheFirst(1) - .With(h => h.EpisodeId = episode.Id) - .Build(); - - - Subject.InsertMany(history); - - Subject.CleanupOrphanedByEpisode(); - Subject.All().Should().HaveCount(1); - Subject.All().Should().Contain(h => h.EpisodeId == episode.Id); - } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/TvTests/EpisodeRepositoryTests/CleanupOrphanedEpisodesFixture.cs b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedEpisodesFixture.cs similarity index 55% rename from NzbDrone.Core.Test/TvTests/EpisodeRepositoryTests/CleanupOrphanedEpisodesFixture.cs rename to NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedEpisodesFixture.cs index d21ef817d..03f8b395e 100644 --- a/NzbDrone.Core.Test/TvTests/EpisodeRepositoryTests/CleanupOrphanedEpisodesFixture.cs +++ b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedEpisodesFixture.cs @@ -1,13 +1,14 @@ using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; +using NzbDrone.Core.Housekeeping.Housekeepers; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Tv; -namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests +namespace NzbDrone.Core.Test.Housekeeping.Housekeepers { [TestFixture] - public class CleanupOrphanedEpisodesFixture : DbTest + public class CleanupOrphanedEpisodesFixture : DbTest { [Test] public void should_delete_orphaned_episodes() @@ -15,9 +16,9 @@ public void should_delete_orphaned_episodes() var episode = Builder.CreateNew() .BuildNew(); - Subject.Insert(episode); - Subject.CleanupOrphanedEpisodes(); - Subject.All().Should().BeEmpty(); + Db.Insert(episode); + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); } [Test] @@ -29,16 +30,14 @@ public void should_not_delete_unorphaned_episodes() Db.Insert(series); var episodes = Builder.CreateListOfSize(2) - .All() - .With(e => e.Id = 0) .TheFirst(1) .With(e => e.SeriesId = series.Id) - .Build(); + .BuildListOfNew(); - Subject.InsertMany(episodes); - Subject.CleanupOrphanedEpisodes(); - Subject.All().Should().HaveCount(1); - Subject.All().Should().Contain(e => e.SeriesId == series.Id); + Db.InsertMany(episodes); + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + AllStoredModels.Should().Contain(e => e.SeriesId == series.Id); } } } diff --git a/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs new file mode 100644 index 000000000..df24add3e --- /dev/null +++ b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs @@ -0,0 +1,105 @@ +using System; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Housekeeping.Housekeepers; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.Housekeeping.Housekeepers +{ + [TestFixture] + public class CleanupOrphanedHistoryItemsFixture : DbTest + { + private Series _series; + private Episode _episode; + + [SetUp] + public void Setup() + { + _series = Builder.CreateNew() + .BuildNew(); + + _episode = Builder.CreateNew() + .BuildNew(); + } + + private void GivenSeries() + { + Db.Insert(_series); + } + + private void GivenEpisode() + { + Db.Insert(_episode); + } + + [Test] + public void should_delete_orphaned_items_by_series() + { + GivenEpisode(); + + var history = Builder.CreateNew() + .With(h => h.EpisodeId = _episode.Id) + .BuildNew(); + Db.Insert(history); + + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_delete_orphaned_items_by_episode() + { + GivenSeries(); + + var history = Builder.CreateNew() + .With(h => h.SeriesId = _series.Id) + .BuildNew(); + Db.Insert(history); + + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_unorphaned_data_by_series() + { + GivenSeries(); + GivenEpisode(); + + var history = Builder.CreateListOfSize(2) + .All() + .With(h => h.EpisodeId = _episode.Id) + .TheFirst(1) + .With(h => h.SeriesId = _series.Id) + .BuildListOfNew(); + + Db.InsertMany(history); + + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + AllStoredModels.Should().Contain(h => h.SeriesId == _series.Id); + } + + [Test] + public void should_not_delete_unorphaned_data_by_episode() + { + GivenSeries(); + GivenEpisode(); + + var history = Builder.CreateListOfSize(2) + .All() + .With(h => h.SeriesId = _series.Id) + .TheFirst(1) + .With(h => h.EpisodeId = _episode.Id) + .BuildListOfNew(); + + Db.InsertMany(history); + + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + AllStoredModels.Should().Contain(h => h.EpisodeId == _episode.Id); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index b81a12de0..22ee553f8 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -125,6 +125,7 @@ + @@ -179,7 +180,7 @@ - + diff --git a/NzbDrone.Core/History/HistoryRepository.cs b/NzbDrone.Core/History/HistoryRepository.cs index 50ad32994..a39e117ea 100644 --- a/NzbDrone.Core/History/HistoryRepository.cs +++ b/NzbDrone.Core/History/HistoryRepository.cs @@ -12,8 +12,6 @@ public interface IHistoryRepository : IBasicRepository { void Trim(); List GetEpisodeHistory(int episodeId); - void CleanupOrphanedBySeries(); - void CleanupOrphanedByEpisode(); } public class HistoryRepository : BasicRepository, IHistoryRepository @@ -39,30 +37,6 @@ public List GetEpisodeHistory(int episodeId) return history.Select(h => h.Quality).ToList(); } - public void CleanupOrphanedBySeries() - { - var mapper = _database.GetDataMapper(); - - mapper.ExecuteNonQuery(@"DELETE FROM History - WHERE Id IN ( - SELECT History.Id FROM History - LEFT OUTER JOIN Series - ON History.SeriesId = Series.Id - WHERE Series.Id IS NULL)"); - } - - public void CleanupOrphanedByEpisode() - { - var mapper = _database.GetDataMapper(); - - mapper.ExecuteNonQuery(@"DELETE FROM History - WHERE Id IN ( - SELECT History.Id FROM History - LEFT OUTER JOIN Episodes - ON History.EpisodeId = Episodes.Id - WHERE Episodes.Id IS NULL)"); - } - public override PagingSpec GetPaged(PagingSpec pagingSpec) { var pagingQuery = Query.Join(JoinType.Inner, h => h.Series, (h, s) => h.SeriesId == s.Id) diff --git a/NzbDrone.Core/History/HistoryService.cs b/NzbDrone.Core/History/HistoryService.cs index ee73ad987..64736c9f0 100644 --- a/NzbDrone.Core/History/HistoryService.cs +++ b/NzbDrone.Core/History/HistoryService.cs @@ -17,7 +17,6 @@ public interface IHistoryService void Trim(); QualityModel GetBestQualityInHistory(int episodeId); PagingSpec Paged(PagingSpec pagingSpec); - void CleanupOrphaned(); } public class HistoryService : IHistoryService, IHandle, IHandle @@ -41,12 +40,6 @@ public PagingSpec Paged(PagingSpec pagingSpec) return _historyRepository.GetPaged(pagingSpec); } - public void CleanupOrphaned() - { - _historyRepository.CleanupOrphanedBySeries(); - _historyRepository.CleanupOrphanedByEpisode(); - } - public void Purge() { _historyRepository.Purge(); diff --git a/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedEpisodes.cs b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedEpisodes.cs index 69cb713ca..0965fc33c 100644 --- a/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedEpisodes.cs +++ b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedEpisodes.cs @@ -1,23 +1,32 @@ using NLog; +using NzbDrone.Core.Datastore; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Housekeeping.Housekeepers { public class CleanupOrphanedEpisodes : IHousekeepingTask { - private readonly IEpisodeService _episodeService; + private readonly IDatabase _database; private readonly Logger _logger; - public CleanupOrphanedEpisodes(IEpisodeService episodeService, Logger logger) + public CleanupOrphanedEpisodes(IDatabase database, Logger logger) { - _episodeService = episodeService; + _database = database; _logger = logger; } public void Clean() { _logger.Trace("Running orphaned episodes cleanup"); - _episodeService.CleanupOrphanedEpisodes(); + + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM Episodes + WHERE Id IN ( + SELECT Episodes.Id FROM Episodes + LEFT OUTER JOIN Series + ON Episodes.SeriesId = Series.Id + WHERE Series.Id IS NULL)"); } } } diff --git a/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs index 0df2e5c1f..11567a2ba 100644 --- a/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs +++ b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs @@ -1,23 +1,49 @@ using NLog; +using NzbDrone.Core.Datastore; using NzbDrone.Core.History; namespace NzbDrone.Core.Housekeeping.Housekeepers { public class CleanupOrphanedHistoryItems : IHousekeepingTask { - private readonly IHistoryService _historyService; + private readonly IDatabase _database; private readonly Logger _logger; - public CleanupOrphanedHistoryItems(IHistoryService historyService, Logger logger) + public CleanupOrphanedHistoryItems(IDatabase database, Logger logger) { - _historyService = historyService; + _database = database; _logger = logger; } public void Clean() { _logger.Trace("Running orphaned history cleanup"); - _historyService.CleanupOrphaned(); + CleanupOrphanedBySeries(); + CleanupOrphanedByEpisode(); + } + + private void CleanupOrphanedBySeries() + { + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM History + WHERE Id IN ( + SELECT History.Id FROM History + LEFT OUTER JOIN Series + ON History.SeriesId = Series.Id + WHERE Series.Id IS NULL)"); + } + + private void CleanupOrphanedByEpisode() + { + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM History + WHERE Id IN ( + SELECT History.Id FROM History + LEFT OUTER JOIN Episodes + ON History.EpisodeId = Episodes.Id + WHERE Episodes.Id IS NULL)"); } } } diff --git a/NzbDrone.Core/Tv/EpisodeRepository.cs b/NzbDrone.Core/Tv/EpisodeRepository.cs index db9984a0b..3a9ade8d9 100644 --- a/NzbDrone.Core/Tv/EpisodeRepository.cs +++ b/NzbDrone.Core/Tv/EpisodeRepository.cs @@ -22,7 +22,6 @@ public interface IEpisodeRepository : IBasicRepository void SetMonitoredFlat(Episode episode, bool monitored); void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored); void SetFileId(int episodeId, int fileId); - void CleanupOrphanedEpisodes(); } public class EpisodeRepository : BasicRepository, IEpisodeRepository @@ -124,18 +123,6 @@ public void SetFileId(int episodeId, int fileId) SetFields(new Episode { Id = episodeId, EpisodeFileId = fileId }, episode => episode.EpisodeFileId); } - public void CleanupOrphanedEpisodes() - { - var mapper = _database.GetDataMapper(); - - mapper.ExecuteNonQuery(@"DELETE FROM Episodes - WHERE Id IN ( - SELECT Episodes.Id FROM Episodes - LEFT OUTER JOIN Series - ON Episodes.SeriesId = Series.Id - WHERE Series.Id IS NULL)"); - } - private SortBuilder GetEpisodesWithoutFilesQuery(PagingSpec pagingSpec, DateTime currentTime, int startingSeasonNumber) { return Query.Join(JoinType.Inner, e => e.Series, (e, s) => e.SeriesId == s.Id) diff --git a/NzbDrone.Core/Tv/EpisodeService.cs b/NzbDrone.Core/Tv/EpisodeService.cs index 2f521a1ea..8bd88187d 100644 --- a/NzbDrone.Core/Tv/EpisodeService.cs +++ b/NzbDrone.Core/Tv/EpisodeService.cs @@ -29,7 +29,6 @@ public interface IEpisodeService void UpdateMany(List episodes); void DeleteMany(List episodes); void SetEpisodeMonitoredBySeason(int seriesId, int seasonNumber, bool monitored); - void CleanupOrphanedEpisodes(); } public class EpisodeService : IEpisodeService, @@ -113,11 +112,6 @@ public void SetEpisodeMonitoredBySeason(int seriesId, int seasonNumber, bool mon _episodeRepository.SetMonitoredBySeason(seriesId, seasonNumber, monitored); } - public void CleanupOrphanedEpisodes() - { - _episodeRepository.CleanupOrphanedEpisodes(); - } - public bool IsFirstOrLastEpisodeOfSeason(int episodeId) { var episode = GetEpisode(episodeId);