Move to using PagingSpec in BlocklistRepository

This commit is contained in:
Stevie Robinson 2024-05-04 12:21:59 +02:00
parent 6c4e259a8d
commit d0e9155076
4 changed files with 42 additions and 92 deletions

View File

@ -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;

View File

@ -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<Blocklist> BlocklistedByTorrentInfoHash(int seriesId, string torrentInfoHash);
List<Blocklist> BlocklistedBySeries(int seriesId);
void DeleteForSeriesIds(List<int> seriesIds);
PagingSpec<Blocklist> GetPaged(PagingSpec<Blocklist> pagingSpec, DownloadProtocol? protocol);
}
public class BlocklistRepository : BasicRepository<Blocklist>, IBlocklistRepository
@ -40,11 +42,37 @@ namespace NzbDrone.Core.Blocklisting
Delete(x => seriesIds.Contains(x.SeriesId));
}
protected override SqlBuilder PagedBuilder() => new SqlBuilder(_database.DatabaseType).Join<Blocklist, Series>((b, m) => b.SeriesId == m.Id);
protected override IEnumerable<Blocklist> PagedQuery(SqlBuilder sql) => _database.QueryJoined<Blocklist, Series>(sql, (bl, movie) =>
{
bl.Series = movie;
return bl;
});
public PagingSpec<Blocklist> GetPaged(PagingSpec<Blocklist> 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<Blocklist, Series>((b, m) => b.SeriesId == m.Id);
if (protocol != null)
{
builder.Where($"({BuildProtocolWhereClause(protocol)})");
}
return builder;
}
protected override IEnumerable<Blocklist> PagedQuery(SqlBuilder builder) =>
_database.QueryJoined<Blocklist, Series>(builder, (blocklist, series) =>
{
blocklist.Series = series;
return blocklist;
});
private string BuildProtocolWhereClause(DownloadProtocol? protocol) =>
$"\"{TableMapping.Mapper.TableNameMapping(typeof(Blocklist))}\".\"Protocol\" = {(int) protocol}";
}
}

View File

@ -14,10 +14,9 @@ namespace NzbDrone.Core.Blocklisting
{
public interface IBlocklistService
{
List<Blocklist> GetBlocklist();
bool Blocklisted(int seriesId, ReleaseInfo release);
bool BlocklistedTorrentHash(int seriesId, string hash);
PagingSpec<Blocklist> Paged(PagingSpec<Blocklist> pagingSpec);
PagingSpec<Blocklist> Paged(PagingSpec<Blocklist> pagingSpec, DownloadProtocol? protocol);
void Block(RemoteEpisode remoteEpisode, string message);
void Delete(int id);
void Delete(List<int> ids);
@ -35,11 +34,6 @@ namespace NzbDrone.Core.Blocklisting
_blocklistRepository = blocklistRepository;
}
public List<Blocklist> 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<Blocklist> Paged(PagingSpec<Blocklist> pagingSpec)
public PagingSpec<Blocklist> Paged(PagingSpec<Blocklist> pagingSpec, DownloadProtocol? protocol)
{
return _blocklistRepository.GetPaged(pagingSpec);
return _blocklistRepository.GetPaged(pagingSpec, protocol);
}
public void Block(RemoteEpisode remoteEpisode, string message)

View File

@ -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<BlocklistResource> GetBlocklist([FromQuery] PagingRequestResource paging, [FromQuery] int[] seriesIds = null, DownloadProtocol? protocol = null)
public PagingResource<BlocklistResource> GetBlocklist([FromQuery] PagingRequestResource paging, [FromQuery] int[] seriesIds = null, [FromQuery] DownloadProtocol? protocol = null)
{
var pagingResource = new PagingResource<BlocklistResource>(paging);
var pagingSpec = pagingResource.MapToPagingSpec<BlocklistResource, NzbDrone.Core.Blocklisting.Blocklist>("date", SortDirection.Descending);
return pagingSpec.ApplyToPage(spec => GetBlocklist(spec, seriesIds?.ToHashSet(), protocol), model => BlocklistResourceMapper.MapToResource(model, _formatCalculator));
}
private PagingSpec<NzbDrone.Core.Blocklisting.Blocklist> GetBlocklist(PagingSpec<NzbDrone.Core.Blocklisting.Blocklist> pagingSpec, HashSet<int> 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<NzbDrone.Core.Blocklisting.Blocklist> 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<NzbDrone.Core.Blocklisting.Blocklist, object> GetOrderByFunc(PagingSpec<NzbDrone.Core.Blocklisting.Blocklist> 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]