using System; using System.Collections.Generic; using System.Linq; using Dapper; using NzbDrone.Core.Books; using NzbDrone.Core.Datastore; using NzbDrone.Core.MediaFiles; namespace NzbDrone.Core.AuthorStats { public interface IAuthorStatisticsRepository { List AuthorStatistics(); List AuthorStatistics(int authorId); } public class AuthorStatisticsRepository : IAuthorStatisticsRepository { private const string _selectTemplate = "SELECT /**select**/ FROM \"Editions\" /**join**/ /**innerjoin**/ /**leftjoin**/ /**where**/ /**groupby**/ /**having**/ /**orderby**/"; private readonly IMainDatabase _database; public AuthorStatisticsRepository(IMainDatabase database) { _database = database; } public List AuthorStatistics() { return Query(Builder()); } public List AuthorStatistics(int authorId) { return Query(Builder().Where(x => x.Id == authorId)); } private List Query(SqlBuilder builder) { var sql = builder.AddTemplate(_selectTemplate).LogQuery(); using (var conn = _database.OpenConnection()) { return conn.Query(sql.RawSql, sql.Parameters).ToList(); } } private SqlBuilder Builder() => new SqlBuilder(_database.DatabaseType) .Select(@"""Authors"".""Id"" AS ""AuthorId"", ""Books"".""Id"" AS ""BookId"", SUM(COALESCE(""BookFiles"".""Size"", 0)) AS ""SizeOnDisk"", 1 AS ""TotalBookCount"", CASE WHEN MIN(""BookFiles"".""Id"") IS NULL THEN 0 ELSE 1 END AS ""AvailableBookCount"", CASE WHEN (""Books"".""Monitored"" = true AND (""Books"".""ReleaseDate"" < @currentDate) OR ""Books"".""ReleaseDate"" IS NULL) OR MIN(""BookFiles"".""Id"") IS NOT NULL THEN 1 ELSE 0 END AS ""BookCount"", CASE WHEN MIN(""BookFiles"".""Id"") IS NULL THEN 0 ELSE COUNT(""BookFiles"".""Id"") END AS ""BookFileCount""") .Join((e, b) => e.BookId == b.Id) .Join((book, author) => book.AuthorMetadataId == author.AuthorMetadataId) .LeftJoin((t, f) => t.Id == f.EditionId) .Where(x => x.Monitored == true) .GroupBy(x => x.Id) .GroupBy(x => x.Id) .AddParameters(new Dictionary { { "currentDate", DateTime.UtcNow } }); } }