diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseRepositoryFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseRepositoryFixture.cs new file mode 100644 index 000000000..22ffd2763 --- /dev/null +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseRepositoryFixture.cs @@ -0,0 +1,68 @@ +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Download.Pending; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.MediaFiles +{ + [TestFixture] + public class PendingReleaseRepositoryFixture : DbTest + { + private Movie _movie1; + private Movie _movie2; + + [SetUp] + public void Setup() + { + _movie1 = Builder.CreateNew() + .With(s => s.Id = 7) + .Build(); + + _movie2 = Builder.CreateNew() + .With(s => s.Id = 8) + .Build(); + } + + [Test] + public void should_delete_files_by_movieId() + { + var files = Builder.CreateListOfSize(5) + .All() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie1.Id) + .With(c => c.Release = new ReleaseInfo()) + .BuildListOfNew(); + + Db.InsertMany(files); + + Subject.DeleteByMovieId(_movie1.Id); + + var remainingFiles = Subject.AllByMovieId(_movie1.Id); + + remainingFiles.Should().HaveCount(0); + } + + [Test] + public void should_get_files_by_movieId() + { + var files = Builder.CreateListOfSize(5) + .All() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie1.Id) + .With(c => c.Release = new ReleaseInfo()) + .Random(2) + .With(c => c.MovieId = _movie2.Id) + .BuildListOfNew(); + + Db.InsertMany(files); + + var remainingFiles = Subject.AllByMovieId(_movie1.Id); + + remainingFiles.Should().HaveCount(3); + remainingFiles.Should().OnlyContain(c => c.MovieId == _movie1.Id); + } + } +} diff --git a/src/NzbDrone.Core.Test/Extras/SubtitleFileRepositoryFixture.cs b/src/NzbDrone.Core.Test/Extras/SubtitleFileRepositoryFixture.cs new file mode 100644 index 000000000..bae8f1e95 --- /dev/null +++ b/src/NzbDrone.Core.Test/Extras/SubtitleFileRepositoryFixture.cs @@ -0,0 +1,121 @@ +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Extras.Subtitles; +using NzbDrone.Core.Languages; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.MediaFiles +{ + [TestFixture] + public class SubtitleFileRepositoryFixture : DbTest + { + private Movie _movie; + private MovieFile _movieFile1; + private MovieFile _movieFile2; + + [SetUp] + public void Setup() + { + _movie = Builder.CreateNew() + .With(s => s.Id = 7) + .Build(); + + _movieFile1 = Builder.CreateNew() + .With(s => s.Id = 10) + .With(s => s.MovieId = _movie.Id) + .Build(); + + _movieFile2 = Builder.CreateNew() + .With(s => s.Id = 11) + .With(s => s.MovieId = _movie.Id) + .Build(); + } + + [Test] + public void should_delete_files_by_movieId() + { + var files = Builder.CreateListOfSize(5) + .All() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie.Id) + .With(c => c.MovieFileId = 11) + .With(c => c.Language = Language.English) + .BuildListOfNew(); + + Db.InsertMany(files); + + Subject.DeleteForMovie(_movie.Id); + + var remainingFiles = Subject.GetFilesByMovie(_movie.Id); + + remainingFiles.Should().HaveCount(0); + } + + [Test] + public void should_delete_files_by_movieFileId() + { + var files = Builder.CreateListOfSize(5) + .All() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie.Id) + .With(c => c.MovieFileId = _movieFile2.Id) + .With(c => c.Language = Language.English) + .Random(2) + .With(c => c.MovieFileId = _movieFile1.Id) + .BuildListOfNew(); + + Db.InsertMany(files); + + Subject.DeleteForMovieFile(_movieFile2.Id); + + var remainingFiles = Subject.GetFilesByMovie(_movie.Id); + + remainingFiles.Should().HaveCount(2); + } + + [Test] + public void should_get_files_by_movieFileId() + { + var files = Builder.CreateListOfSize(5) + .All() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie.Id) + .With(c => c.MovieFileId = _movieFile2.Id) + .With(c => c.Language = Language.English) + .Random(2) + .With(c => c.MovieFileId = _movieFile1.Id) + .BuildListOfNew(); + + Db.InsertMany(files); + + var remainingFiles = Subject.GetFilesByMovieFile(_movieFile2.Id); + + remainingFiles.Should().HaveCount(3); + remainingFiles.Should().OnlyContain(c => c.MovieFileId == _movieFile2.Id); + } + + [Test] + public void should_get_files_by_movieId() + { + var files = Builder.CreateListOfSize(5) + .All() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie.Id) + .With(c => c.MovieFileId = _movieFile2.Id) + .With(c => c.Language = Language.English) + .Random(2) + .With(c => c.MovieFileId = _movieFile1.Id) + .BuildListOfNew(); + + Db.InsertMany(files); + + var remainingFiles = Subject.GetFilesByMovie(_movie.Id); + + remainingFiles.Should().HaveCount(5); + remainingFiles.Should().OnlyContain(c => c.MovieId == _movie.Id); + } + } +} diff --git a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedExtraFilesFixture.cs b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedExtraFilesFixture.cs new file mode 100644 index 000000000..81acea20d --- /dev/null +++ b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedExtraFilesFixture.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Extras.Others; +using NzbDrone.Core.Housekeeping.Housekeepers; +using NzbDrone.Core.Languages; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Qualities; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.Housekeeping.Housekeepers +{ + [TestFixture] + public class CleanupOrphanedExtraFilesFixture : DbTest + { + [Test] + public void should_delete_extra_files_that_dont_have_a_coresponding_movie() + { + var extraFile = Builder.CreateNew() + .With(m => m.MovieFileId = 0) + .BuildNew(); + + Db.Insert(extraFile); + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_extra_files_that_have_a_coresponding_movie() + { + var movie = Builder.CreateNew() + .BuildNew(); + + Db.Insert(movie); + + var extraFile = Builder.CreateNew() + .With(m => m.MovieId = movie.Id) + .With(m => m.MovieFileId = 0) + .BuildNew(); + + Db.Insert(extraFile); + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + } + + [Test] + public void should_delete_extra_files_that_dont_have_a_coresponding_movie_file() + { + var movie = Builder.CreateNew() + .BuildNew(); + + Db.Insert(movie); + + var extraFile = Builder.CreateNew() + .With(m => m.MovieId = movie.Id) + .With(m => m.MovieFileId = 10) + .BuildNew(); + + Db.Insert(extraFile); + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_extra_files_that_have_a_coresponding_movie_file() + { + var movie = Builder.CreateNew() + .BuildNew(); + + var movieFile = Builder.CreateNew() + .With(h => h.Quality = new QualityModel()) + .With(h => h.Languages = new List()) + .BuildNew(); + + Db.Insert(movie); + Db.Insert(movieFile); + + var extraFile = Builder.CreateNew() + .With(m => m.MovieId = movie.Id) + .With(m => m.MovieFileId = movieFile.Id) + .BuildNew(); + + Db.Insert(extraFile); + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + } + } +} diff --git a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedSubtitleFilesFixture.cs b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedSubtitleFilesFixture.cs new file mode 100644 index 000000000..28787c63d --- /dev/null +++ b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedSubtitleFilesFixture.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Extras.Subtitles; +using NzbDrone.Core.Housekeeping.Housekeepers; +using NzbDrone.Core.Languages; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Qualities; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.Housekeeping.Housekeepers +{ + [TestFixture] + public class CleanupOrphanedSubtitleFilesFixture : DbTest + { + [Test] + public void should_delete_subtitle_files_that_dont_have_a_coresponding_movie() + { + var subtitleFile = Builder.CreateNew() + .With(m => m.MovieFileId = 0) + .With(m => m.Language = Language.English) + .BuildNew(); + + Db.Insert(subtitleFile); + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_subtitle_files_that_have_a_coresponding_movie() + { + var movie = Builder.CreateNew() + .BuildNew(); + + Db.Insert(movie); + + var subtitleFile = Builder.CreateNew() + .With(m => m.MovieId = movie.Id) + .With(m => m.MovieFileId = 0) + .With(m => m.Language = Language.English) + .BuildNew(); + + Db.Insert(subtitleFile); + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + } + + [Test] + public void should_delete_subtitle_files_that_dont_have_a_coresponding_movie_file() + { + var movie = Builder.CreateNew() + .BuildNew(); + + Db.Insert(movie); + + var subtitleFile = Builder.CreateNew() + .With(m => m.MovieId = movie.Id) + .With(m => m.MovieFileId = 10) + .With(m => m.Language = Language.English) + .BuildNew(); + + Db.Insert(subtitleFile); + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_subtitle_files_that_have_a_coresponding_movie_file() + { + var movie = Builder.CreateNew() + .BuildNew(); + + var movieFile = Builder.CreateNew() + .With(h => h.Quality = new QualityModel()) + .With(h => h.Languages = new List()) + .BuildNew(); + + Db.Insert(movie); + Db.Insert(movieFile); + + var subtitleFile = Builder.CreateNew() + .With(m => m.MovieId = movie.Id) + .With(m => m.MovieFileId = movieFile.Id) + .With(m => m.Language = Language.English) + .BuildNew(); + + Db.Insert(subtitleFile); + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + } + } +} diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs index bdade04f9..681529bab 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs @@ -20,7 +20,7 @@ namespace NzbDrone.Core.Download.Pending public void DeleteByMovieId(int movieId) { - Delete(movieId); + Delete(x => x.MovieId == movieId); } public List AllByMovieId(int movieId) diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs index f05d6261f..667b294fb 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs @@ -25,12 +25,12 @@ namespace NzbDrone.Core.Extras.Files public void DeleteForMovie(int movieId) { - Delete(movieId); + Delete(x => x.MovieId == movieId); } public void DeleteForMovieFile(int movieFileId) { - Delete(c => c.MovieFileId == movieFileId); + Delete(x => x.MovieFileId == movieFileId); } public List GetFilesByMovie(int movieId) diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedExtraFiles.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedExtraFiles.cs new file mode 100644 index 000000000..1a16d0499 --- /dev/null +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedExtraFiles.cs @@ -0,0 +1,48 @@ +using Dapper; +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.Housekeeping.Housekeepers +{ + public class CleanupOrphanedExtraFiles : IHousekeepingTask + { + private readonly IMainDatabase _database; + + public CleanupOrphanedExtraFiles(IMainDatabase database) + { + _database = database; + } + + public void Clean() + { + DeleteOrphanedByMovie(); + DeleteOrphanedByMovieFile(); + } + + private void DeleteOrphanedByMovie() + { + using (var mapper = _database.OpenConnection()) + { + mapper.Execute(@"DELETE FROM ExtraFiles + WHERE Id IN ( + SELECT ExtraFiles.Id FROM ExtraFiles + LEFT OUTER JOIN Movies + ON ExtraFiles.MovieId = Movies.Id + WHERE Movies.Id IS NULL)"); + } + } + + private void DeleteOrphanedByMovieFile() + { + using (var mapper = _database.OpenConnection()) + { + mapper.Execute(@"DELETE FROM ExtraFiles + WHERE Id IN ( + SELECT ExtraFiles.Id FROM ExtraFiles + LEFT OUTER JOIN MovieFiles + ON ExtraFiles.MovieFileId = MovieFiles.Id + WHERE ExtraFiles.MovieFileId > 0 + AND MovieFiles.Id IS NULL)"); + } + } + } +} diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedSubtitleFiles.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedSubtitleFiles.cs new file mode 100644 index 000000000..28c61aea1 --- /dev/null +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedSubtitleFiles.cs @@ -0,0 +1,48 @@ +using Dapper; +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.Housekeeping.Housekeepers +{ + public class CleanupOrphanedSubtitleFiles : IHousekeepingTask + { + private readonly IMainDatabase _database; + + public CleanupOrphanedSubtitleFiles(IMainDatabase database) + { + _database = database; + } + + public void Clean() + { + DeleteOrphanedByMovie(); + DeleteOrphanedByMovieFile(); + } + + private void DeleteOrphanedByMovie() + { + using (var mapper = _database.OpenConnection()) + { + mapper.Execute(@"DELETE FROM SubtitleFiles + WHERE Id IN ( + SELECT SubtitleFiles.Id FROM SubtitleFiles + LEFT OUTER JOIN Movies + ON SubtitleFiles.MovieId = Movies.Id + WHERE Movies.Id IS NULL)"); + } + } + + private void DeleteOrphanedByMovieFile() + { + using (var mapper = _database.OpenConnection()) + { + mapper.Execute(@"DELETE FROM SubtitleFiles + WHERE Id IN ( + SELECT SubtitleFiles.Id FROM SubtitleFiles + LEFT OUTER JOIN MovieFiles + ON SubtitleFiles.MovieFileId = MovieFiles.Id + WHERE SubtitleFiles.MovieFileId > 0 + AND MovieFiles.Id IS NULL)"); + } + } + } +}