Fixed: Size on disk calculation including multi-episode files multiple times
Closes #5296
This commit is contained in:
parent
f15f08e51a
commit
6c53bf30d5
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
@ -180,5 +181,25 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
|
|||
stats.Should().HaveCount(1);
|
||||
stats.First().SizeOnDisk.Should().Be(_episodeFile.Size);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_duplicate_size_for_multi_episode_files()
|
||||
{
|
||||
GivenEpisodeWithFile();
|
||||
GivenEpisode();
|
||||
GivenEpisodeFile();
|
||||
|
||||
var episode2 = _episode.JsonClone();
|
||||
|
||||
episode2.Id = 0;
|
||||
episode2.EpisodeNumber += 1;
|
||||
|
||||
Db.Insert(episode2);
|
||||
|
||||
var stats = Subject.SeriesStatistics();
|
||||
|
||||
stats.Should().HaveCount(1);
|
||||
stats.First().SizeOnDisk.Should().Be(_episodeFile.Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Dapper;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
@ -17,7 +16,8 @@ namespace NzbDrone.Core.SeriesStats
|
|||
|
||||
public class SeriesStatisticsRepository : ISeriesStatisticsRepository
|
||||
{
|
||||
private const string _selectTemplate = "SELECT /**select**/ FROM Episodes /**join**/ /**innerjoin**/ /**leftjoin**/ /**where**/ /**groupby**/ /**having**/ /**orderby**/";
|
||||
private const string _selectEpisodesTemplate = "SELECT /**select**/ FROM Episodes /**join**/ /**innerjoin**/ /**leftjoin**/ /**where**/ /**groupby**/ /**having**/ /**orderby**/";
|
||||
private const string _selectEpisodeFilesTemplate = "SELECT /**select**/ FROM EpisodeFiles /**join**/ /**innerjoin**/ /**leftjoin**/ /**where**/ /**groupby**/ /**having**/ /**orderby**/";
|
||||
|
||||
private readonly IMainDatabase _database;
|
||||
|
||||
|
@ -29,18 +29,34 @@ namespace NzbDrone.Core.SeriesStats
|
|||
public List<SeasonStatistics> SeriesStatistics()
|
||||
{
|
||||
var time = DateTime.UtcNow;
|
||||
return Query(Builder(time));
|
||||
return MapResults(Query(EpisodesBuilder(time), _selectEpisodesTemplate),
|
||||
Query(EpisodeFilesBuilder(), _selectEpisodeFilesTemplate));
|
||||
}
|
||||
|
||||
public List<SeasonStatistics> SeriesStatistics(int seriesId)
|
||||
{
|
||||
var time = DateTime.UtcNow;
|
||||
return Query(Builder(time).Where<Episode>(x => x.SeriesId == seriesId));
|
||||
|
||||
return MapResults(Query(EpisodesBuilder(time).Where<Episode>(x => x.SeriesId == seriesId), _selectEpisodesTemplate),
|
||||
Query(EpisodeFilesBuilder().Where<EpisodeFile>(x => x.SeriesId == seriesId), _selectEpisodeFilesTemplate));
|
||||
}
|
||||
|
||||
private List<SeasonStatistics> Query(SqlBuilder builder)
|
||||
private List<SeasonStatistics> MapResults(List<SeasonStatistics> episodesResult, List<SeasonStatistics> filesResult)
|
||||
{
|
||||
var sql = builder.AddTemplate(_selectTemplate).LogQuery();
|
||||
episodesResult.ForEach(e =>
|
||||
{
|
||||
var file = filesResult.SingleOrDefault(f => f.SeriesId == e.SeriesId & f.SeasonNumber == e.SeasonNumber);
|
||||
|
||||
e.SizeOnDisk = file?.SizeOnDisk ?? 0;
|
||||
e.ReleaseGroupsString = file?.ReleaseGroupsString;
|
||||
});
|
||||
|
||||
return episodesResult;
|
||||
}
|
||||
|
||||
private List<SeasonStatistics> Query(SqlBuilder builder, string template)
|
||||
{
|
||||
var sql = builder.AddTemplate(template).LogQuery();
|
||||
|
||||
using (var conn = _database.OpenConnection())
|
||||
{
|
||||
|
@ -48,24 +64,33 @@ namespace NzbDrone.Core.SeriesStats
|
|||
}
|
||||
}
|
||||
|
||||
private SqlBuilder Builder(DateTime currentDate)
|
||||
private SqlBuilder EpisodesBuilder(DateTime currentDate)
|
||||
{
|
||||
var parameters = new DynamicParameters();
|
||||
parameters.Add("currentDate", currentDate, null);
|
||||
|
||||
return new SqlBuilder()
|
||||
.Select(@"Episodes.SeriesId AS SeriesId,
|
||||
Episodes.SeasonNumber,
|
||||
SUM(COALESCE(EpisodeFiles.Size, 0)) AS SizeOnDisk,
|
||||
GROUP_CONCAT(EpisodeFiles.ReleaseGroup, '|') AS ReleaseGroupsString,
|
||||
COUNT(*) AS TotalEpisodeCount,
|
||||
SUM(CASE WHEN AirdateUtc <= @currentDate OR EpisodeFileId > 0 THEN 1 ELSE 0 END) AS AvailableEpisodeCount,
|
||||
SUM(CASE WHEN (Monitored = 1 AND AirdateUtc <= @currentDate) OR EpisodeFileId > 0 THEN 1 ELSE 0 END) AS EpisodeCount,
|
||||
SUM(CASE WHEN EpisodeFileId > 0 THEN 1 ELSE 0 END) AS EpisodeFileCount,
|
||||
MIN(CASE WHEN AirDateUtc < @currentDate OR EpisodeFileId > 0 OR Monitored = 0 THEN NULL ELSE AirDateUtc END) AS NextAiringString,
|
||||
MAX(CASE WHEN AirDateUtc >= @currentDate OR EpisodeFileId = 0 AND Monitored = 0 THEN NULL ELSE AirDateUtc END) AS PreviousAiringString", parameters)
|
||||
.LeftJoin<Episode, EpisodeFile>((t, f) => t.EpisodeFileId == f.Id)
|
||||
.GroupBy<Episode>(x => x.SeriesId)
|
||||
.GroupBy<Episode>(x => x.SeasonNumber);
|
||||
}
|
||||
|
||||
private SqlBuilder EpisodeFilesBuilder()
|
||||
{
|
||||
return new SqlBuilder()
|
||||
.Select(@"SeriesId,
|
||||
SeasonNumber,
|
||||
SUM(COALESCE(Size, 0)) AS SizeOnDisk,
|
||||
GROUP_CONCAT(ReleaseGroup, '|') AS ReleaseGroupsString")
|
||||
.GroupBy<EpisodeFile>(x => x.SeriesId)
|
||||
.GroupBy<EpisodeFile>(x => x.SeasonNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue