From d0e91550769848cc9f40cf428935b6f3a2c4047c Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Sat, 4 May 2024 12:21:59 +0200 Subject: [PATCH] Move to using PagingSpec in BlocklistRepository --- frontend/src/Activity/Blocklist/Blocklist.js | 7 +- .../Blocklisting/BlocklistRepository.cs | 40 ++++++++-- .../Blocklisting/BlocklistService.cs | 12 +-- .../Blocklist/BlocklistController.cs | 75 +------------------ 4 files changed, 42 insertions(+), 92 deletions(-) diff --git a/frontend/src/Activity/Blocklist/Blocklist.js b/frontend/src/Activity/Blocklist/Blocklist.js index 40af88d6e..19026beb5 100644 --- a/frontend/src/Activity/Blocklist/Blocklist.js +++ b/frontend/src/Activity/Blocklist/Blocklist.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import BlocklistFilterModal from 'Activity/Blocklist/BlocklistFilterModal'; import Alert from 'Components/Alert'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import FilterMenu from 'Components/Menu/FilterMenu'; @@ -22,6 +21,7 @@ import getSelectedIds from 'Utilities/Table/getSelectedIds'; import removeOldSelectedState from 'Utilities/Table/removeOldSelectedState'; import selectAll from 'Utilities/Table/selectAll'; import toggleSelected from 'Utilities/Table/toggleSelected'; +import BlocklistFilterModal from './BlocklistFilterModal'; import BlocklistRowConnector from './BlocklistRowConnector'; class Blocklist extends Component { @@ -116,7 +116,6 @@ class Blocklist extends Component { error, items, columns, - count, selectedFilterKey, filters, customFilters, @@ -274,7 +273,6 @@ Blocklist.propTypes = { selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, filters: PropTypes.arrayOf(PropTypes.object).isRequired, customFilters: PropTypes.arrayOf(PropTypes.object).isRequired, - count: PropTypes.number.isRequired, totalRecords: PropTypes.number, isRemoving: PropTypes.bool.isRequired, isClearingBlocklistExecuting: PropTypes.bool.isRequired, @@ -283,7 +281,4 @@ Blocklist.propTypes = { onFilterSelect: PropTypes.func.isRequired }; -Blocklist.defaultProps = { - count: 0 -}; export default Blocklist; diff --git a/src/NzbDrone.Core/Blocklisting/BlocklistRepository.cs b/src/NzbDrone.Core/Blocklisting/BlocklistRepository.cs index 43348430b..8e2fff954 100644 --- a/src/NzbDrone.Core/Blocklisting/BlocklistRepository.cs +++ b/src/NzbDrone.Core/Blocklisting/BlocklistRepository.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using NzbDrone.Core.Datastore; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; @@ -11,6 +12,7 @@ namespace NzbDrone.Core.Blocklisting List BlocklistedByTorrentInfoHash(int seriesId, string torrentInfoHash); List BlocklistedBySeries(int seriesId); void DeleteForSeriesIds(List seriesIds); + PagingSpec GetPaged(PagingSpec pagingSpec, DownloadProtocol? protocol); } public class BlocklistRepository : BasicRepository, IBlocklistRepository @@ -40,11 +42,37 @@ namespace NzbDrone.Core.Blocklisting Delete(x => seriesIds.Contains(x.SeriesId)); } - protected override SqlBuilder PagedBuilder() => new SqlBuilder(_database.DatabaseType).Join((b, m) => b.SeriesId == m.Id); - protected override IEnumerable PagedQuery(SqlBuilder sql) => _database.QueryJoined(sql, (bl, movie) => - { - bl.Series = movie; - return bl; - }); + public PagingSpec GetPaged(PagingSpec pagingSpec, DownloadProtocol? protocol) + { + pagingSpec.Records = GetPagedRecords(PagedBuilder(protocol), pagingSpec, PagedQuery); + + var countTemplate = $"SELECT COUNT(*) FROM (SELECT /**select**/ FROM \"{TableMapping.Mapper.TableNameMapping(typeof(Blocklist))}\" /**join**/ /**innerjoin**/ /**leftjoin**/ /**where**/ /**groupby**/ /**having**/) AS \"Inner\""; + pagingSpec.TotalRecords = GetPagedRecordCount(PagedBuilder(protocol).Select(typeof(Blocklist)), pagingSpec, countTemplate); + + return pagingSpec; + } + + private SqlBuilder PagedBuilder(DownloadProtocol? protocol) + { + var builder = Builder() + .Join((b, m) => b.SeriesId == m.Id); + + if (protocol != null) + { + builder.Where($"({BuildProtocolWhereClause(protocol)})"); + } + + return builder; + } + + protected override IEnumerable PagedQuery(SqlBuilder builder) => + _database.QueryJoined(builder, (blocklist, series) => + { + blocklist.Series = series; + return blocklist; + }); + + private string BuildProtocolWhereClause(DownloadProtocol? protocol) => + $"\"{TableMapping.Mapper.TableNameMapping(typeof(Blocklist))}\".\"Protocol\" = {(int) protocol}"; } } diff --git a/src/NzbDrone.Core/Blocklisting/BlocklistService.cs b/src/NzbDrone.Core/Blocklisting/BlocklistService.cs index 16c02be35..74f20c0fa 100644 --- a/src/NzbDrone.Core/Blocklisting/BlocklistService.cs +++ b/src/NzbDrone.Core/Blocklisting/BlocklistService.cs @@ -14,10 +14,9 @@ namespace NzbDrone.Core.Blocklisting { public interface IBlocklistService { - List GetBlocklist(); bool Blocklisted(int seriesId, ReleaseInfo release); bool BlocklistedTorrentHash(int seriesId, string hash); - PagingSpec Paged(PagingSpec pagingSpec); + PagingSpec Paged(PagingSpec pagingSpec, DownloadProtocol? protocol); void Block(RemoteEpisode remoteEpisode, string message); void Delete(int id); void Delete(List ids); @@ -35,11 +34,6 @@ namespace NzbDrone.Core.Blocklisting _blocklistRepository = blocklistRepository; } - public List GetBlocklist() - { - return _blocklistRepository.All().ToList(); - } - public bool Blocklisted(int seriesId, ReleaseInfo release) { if (release.DownloadProtocol == DownloadProtocol.Torrent) @@ -72,9 +66,9 @@ namespace NzbDrone.Core.Blocklisting b.TorrentInfoHash.Equals(hash, StringComparison.InvariantCultureIgnoreCase)); } - public PagingSpec Paged(PagingSpec pagingSpec) + public PagingSpec Paged(PagingSpec pagingSpec, DownloadProtocol? protocol) { - return _blocklistRepository.GetPaged(pagingSpec); + return _blocklistRepository.GetPaged(pagingSpec, protocol); } public void Block(RemoteEpisode remoteEpisode, string message) diff --git a/src/Sonarr.Api.V3/Blocklist/BlocklistController.cs b/src/Sonarr.Api.V3/Blocklist/BlocklistController.cs index 898069911..ef885ce95 100644 --- a/src/Sonarr.Api.V3/Blocklist/BlocklistController.cs +++ b/src/Sonarr.Api.V3/Blocklist/BlocklistController.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; -using NzbDrone.Common.Extensions; using NzbDrone.Core.Blocklisting; using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Datastore; @@ -28,81 +25,17 @@ namespace Sonarr.Api.V3.Blocklist [HttpGet] [Produces("application/json")] - public PagingResource GetBlocklist([FromQuery] PagingRequestResource paging, [FromQuery] int[] seriesIds = null, DownloadProtocol? protocol = null) + public PagingResource GetBlocklist([FromQuery] PagingRequestResource paging, [FromQuery] int[] seriesIds = null, [FromQuery] DownloadProtocol? protocol = null) { var pagingResource = new PagingResource(paging); var pagingSpec = pagingResource.MapToPagingSpec("date", SortDirection.Descending); - return pagingSpec.ApplyToPage(spec => GetBlocklist(spec, seriesIds?.ToHashSet(), protocol), model => BlocklistResourceMapper.MapToResource(model, _formatCalculator)); - } - - private PagingSpec GetBlocklist(PagingSpec pagingSpec, HashSet seriesIds, DownloadProtocol? protocol) - { - var ascending = pagingSpec.SortDirection == SortDirection.Ascending; - var orderByFunc = GetOrderByFunc(pagingSpec); - - var blocklist = _blocklistService.GetBlocklist(); - - var hasSeriesIdFilter = seriesIds.Any(); - var fullBlocklist = blocklist.Where(b => + if (seriesIds != null && seriesIds.Any()) { - var include = true; - - if (hasSeriesIdFilter) - { - include &= seriesIds.Contains(b.SeriesId); - } - - if (include && protocol.HasValue) - { - include &= b.Protocol == protocol.Value; - } - - return include; - }).ToList(); - - IOrderedEnumerable ordered; - - if (pagingSpec.SortKey == "date") - { - ordered = ascending - ? fullBlocklist.OrderBy(b => b.Date) - : fullBlocklist.OrderByDescending(b => b.Date); - } - else if (pagingSpec.SortKey == "indexer") - { - ordered = ascending - ? fullBlocklist.OrderBy(b => b.Indexer, StringComparer.InvariantCultureIgnoreCase) - : fullBlocklist.OrderByDescending(b => b.Indexer, StringComparer.InvariantCultureIgnoreCase); - } - else - { - ordered = ascending ? fullBlocklist.OrderBy(orderByFunc) : fullBlocklist.OrderByDescending(orderByFunc); + pagingSpec.FilterExpressions.Add(b => seriesIds.Contains(b.SeriesId)); } - pagingSpec.Records = ordered.Skip((pagingSpec.Page - 1) * pagingSpec.PageSize).Take(pagingSpec.PageSize).ToList(); - pagingSpec.TotalRecords = fullBlocklist.Count; - - if (pagingSpec.Records.Empty() && pagingSpec.Page > 1) - { - pagingSpec.Page = (int)Math.Max(Math.Ceiling((decimal)(pagingSpec.TotalRecords / pagingSpec.PageSize)), 1); - pagingSpec.Records = ordered.Skip((pagingSpec.Page - 1) * pagingSpec.PageSize).Take(pagingSpec.PageSize).ToList(); - } - - return pagingSpec; - } - - private Func GetOrderByFunc(PagingSpec pagingSpec) - { - switch (pagingSpec.SortKey) - { - case "series.sortTitle": - return q => q.Series?.SortTitle ?? q.Series?.Title; - case "sourceTitle": - return q => q.SourceTitle; - default: - return q => q.Date; - } + return pagingSpec.ApplyToPage(b => _blocklistService.Paged(pagingSpec, protocol), b => BlocklistResourceMapper.MapToResource(b, _formatCalculator)); } [RestDeleteById]