From 3af8051e3ceaeee0e6dd68a971d807bb9d0d602a Mon Sep 17 00:00:00 2001 From: Qstick Date: Sun, 13 Dec 2020 22:09:51 -0500 Subject: [PATCH] Improve use of All() for Path related queries Signed-off-by: Robin Dadswell --- .../HealthCheck/Checks/DeleteBadMediaCovers.cs | 8 ++++---- .../HealthCheck/Checks/RootFolderCheckFixture.cs | 8 ++++---- .../Books/Repositories/AuthorRepository.cs | 10 ++++++++++ src/NzbDrone.Core/Books/Services/AuthorService.cs | 6 ++++++ src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs | 4 ++-- .../HealthCheck/Checks/RootFolderCheck.cs | 4 ++-- .../Housekeeping/Housekeepers/DeleteBadMediaCovers.cs | 6 +++--- .../MediaFiles/MediaFileDeletionService.cs | 8 ++++---- .../Validation/Paths/AuthorAncestorValidator.cs | 2 +- .../Validation/Paths/AuthorPathValidator.cs | 5 +++-- 10 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs index 6a03484b4..fffff81f9 100644 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs @@ -33,9 +33,9 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks _metadata = Builder.CreateListOfSize(1) .Build().ToList(); - Mocker.GetMock() - .Setup(c => c.GetAllAuthors()) - .Returns(_artist); + Mocker.GetMock() + .Setup(c => c.AllArtistPaths()) + .Returns(_artist.ToDictionary(x => x.Id, x => x.Path)); Mocker.GetMock() .Setup(c => c.GetFilesByAuthor(_artist.First().Id)) @@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks Subject.Clean(); Mocker.GetMock().VerifySet(c => c.CleanupMetadataImages = true, Times.Never()); - Mocker.GetMock().Verify(c => c.GetAllAuthors(), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAllAuthors(), Times.Never()); AssertImageWasNotRemoved(); } diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs index e900b2475..9440093d1 100644 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs @@ -25,8 +25,8 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks .ToList(); Mocker.GetMock() - .Setup(s => s.GetAllAuthors()) - .Returns(artist); + .Setup(s => s.AllAuthorPaths()) + .Returns(artist.ToDictionary(x => x.Id, x => x.Path)); Mocker.GetMock() .Setup(s => s.All()) @@ -45,8 +45,8 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks public void should_not_return_error_when_no_artist() { Mocker.GetMock() - .Setup(s => s.GetAllAuthors()) - .Returns(new List()); + .Setup(s => s.AllAuthorPaths()) + .Returns(new Dictionary()); Mocker.GetMock() .Setup(s => s.All()) diff --git a/src/NzbDrone.Core/Books/Repositories/AuthorRepository.cs b/src/NzbDrone.Core/Books/Repositories/AuthorRepository.cs index a5acebf2e..312a76854 100644 --- a/src/NzbDrone.Core/Books/Repositories/AuthorRepository.cs +++ b/src/NzbDrone.Core/Books/Repositories/AuthorRepository.cs @@ -12,6 +12,7 @@ namespace NzbDrone.Core.Books bool AuthorPathExists(string path); Author FindByName(string cleanName); Author FindById(string foreignAuthorId); + Dictionary AllAuthorPaths(); Author GetAuthorByMetadataId(int authorMetadataId); List GetAuthorsByMetadataId(IEnumerable authorMetadataId); } @@ -55,6 +56,15 @@ namespace NzbDrone.Core.Books return Query(s => s.CleanName == cleanName).ExclusiveOrDefault(); } + public Dictionary AllAuthorPaths() + { + using (var conn = _database.OpenConnection()) + { + var strSql = "SELECT Id AS [Key], Path AS [Value] FROM Authors"; + return conn.Query>(strSql).ToDictionary(x => x.Key, x => x.Value); + } + } + public Author GetAuthorByMetadataId(int authorMetadataId) { return Query(s => s.AuthorMetadataId == authorMetadataId).SingleOrDefault(); diff --git a/src/NzbDrone.Core/Books/Services/AuthorService.cs b/src/NzbDrone.Core/Books/Services/AuthorService.cs index 1509351bf..526c8c174 100644 --- a/src/NzbDrone.Core/Books/Services/AuthorService.cs +++ b/src/NzbDrone.Core/Books/Services/AuthorService.cs @@ -27,6 +27,7 @@ namespace NzbDrone.Core.Books List AllForTag(int tagId); Author UpdateAuthor(Author author); List UpdateAuthors(List authors, bool useExistingRelativeFolder); + Dictionary AllAuthorPaths(); bool AuthorPathExists(string folder); void RemoveAddOptions(Author author); } @@ -194,6 +195,11 @@ namespace NzbDrone.Core.Books return _cache.Get("GetAllAuthors", () => _authorRepository.All().ToList(), TimeSpan.FromSeconds(30)); } + public Dictionary AllAuthorPaths() + { + return _authorRepository.AllAuthorPaths(); + } + public List AllForTag(int tagId) { return GetAllAuthors().Where(s => s.Tags.Contains(tagId)) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs index 5c642825a..459e08e1b 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs @@ -19,8 +19,8 @@ namespace NzbDrone.Core.HealthCheck.Checks public override HealthCheck Check() { // Not best for optimization but due to possible symlinks and junctions, we get mounts based on series path so internals can handle mount resolution. - var mounts = _authorService.GetAllAuthors() - .Select(author => _diskProvider.GetMount(author.Path)) + var mounts = _authorService.AllAuthorPaths() + .Select(path => _diskProvider.GetMount(path.Value)) .Where(m => m != null && m.MountOptions != null && m.MountOptions.IsReadOnly) .DistinctBy(m => m.RootDirectory) .ToList(); diff --git a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs index de020ae21..814cf2fc2 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs @@ -28,8 +28,8 @@ namespace NzbDrone.Core.HealthCheck.Checks public override HealthCheck Check() { - var rootFolders = _artistService.GetAllAuthors() - .Select(s => _rootFolderService.GetBestRootFolderPath(s.Path)) + var rootFolders = _authorService.AllAuthorPaths() + .Select(s => _rootFolderService.GetBestRootFolderPath(s.Value)) .Distinct(); var missingRootFolders = rootFolders.Where(s => !_diskProvider.FolderExists(s)) diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs index 577210eec..6fdf2df16 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs @@ -38,19 +38,19 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers return; } - var artists = _authorService.GetAllAuthors(); + var artists = _authorService.AllAuthorPaths(); var imageExtensions = new List { ".jpg", ".png", ".gif" }; foreach (var author in artists) { - var images = _metaFileService.GetFilesByAuthor(author.Id) + var images = _metaFileService.GetFilesByAuthor(author.Key) .Where(c => c.LastUpdated > new DateTime(2014, 12, 27) && imageExtensions.Any(x => c.RelativePath.EndsWith(x, StringComparison.InvariantCultureIgnoreCase))); foreach (var image in images) { try { - var path = Path.Combine(author.Path, image.RelativePath); + var path = Path.Combine(author.Value, image.RelativePath); if (!IsValid(path)) { _logger.Debug("Deleting invalid image file " + path); diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs index 98385730c..c8abc9a98 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs @@ -104,22 +104,22 @@ namespace NzbDrone.Core.MediaFiles if (message.DeleteFiles) { var author = message.Author; - var allArtists = _authorService.GetAllAuthors(); + var allArtists = _authorService.AllAuthorPaths(); foreach (var s in allArtists) { - if (s.Id == author.Id) + if (s.Key == author.Id) { continue; } - if (author.Path.IsParentPath(s.Path)) + if (author.Path.IsParentPath(s.Value)) { _logger.Error("Author path: '{0}' is a parent of another author, not deleting files.", author.Path); return; } - if (author.Path.PathEquals(s.Path)) + if (author.Path.PathEquals(s.Value)) { _logger.Error("Author path: '{0}' is the same as another author, not deleting files.", author.Path); return; diff --git a/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs index 72905aaf5..472f0e9bf 100644 --- a/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs @@ -22,7 +22,7 @@ namespace NzbDrone.Core.Validation.Paths return true; } - return !_authorService.GetAllAuthors().Any(s => context.PropertyValue.ToString().IsParentPath(s.Path)); + return !_authorService.AllAuthorPaths().Any(s => context.PropertyValue.ToString().IsParentPath(s.Value)); } } } diff --git a/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs index 463d0f1af..1105afecb 100644 --- a/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs @@ -1,4 +1,5 @@ -using FluentValidation.Validators; +using System.Linq; +using FluentValidation.Validators; using NzbDrone.Common.Extensions; using NzbDrone.Core.Books; @@ -24,7 +25,7 @@ namespace NzbDrone.Core.Validation.Paths dynamic instance = context.ParentContext.InstanceToValidate; var instanceId = (int)instance.Id; - return !_authorService.GetAllAuthors().Exists(s => s.Path.PathEquals(context.PropertyValue.ToString()) && s.Id != instanceId); + return !_authorService.AllAuthorPaths().Any(s => s.Value.PathEquals(context.PropertyValue.ToString()) && s.Key != instanceId); } } }