using System; using System.Collections.Generic; using System.Linq; using Dapper; using NzbDrone.Core.Datastore; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Music; namespace NzbDrone.Core.ArtistStats { public interface IArtistStatisticsRepository { List ArtistStatistics(); List ArtistStatistics(int artistId); } public class ArtistStatisticsRepository : IArtistStatisticsRepository { private const string _selectTemplate = "SELECT /**select**/ FROM \"Tracks\" /**join**/ /**innerjoin**/ /**leftjoin**/ /**where**/ /**groupby**/ /**having**/ /**orderby**/"; private readonly IMainDatabase _database; public ArtistStatisticsRepository(IMainDatabase database) { _database = database; } public List ArtistStatistics() { var time = DateTime.UtcNow; if (_database.DatabaseType == DatabaseType.PostgreSQL) { return Query(Builder().WherePostgres(x => x.ReleaseDate < time)); } return Query(Builder().Where(x => x.ReleaseDate < time)); } public List ArtistStatistics(int artistId) { var time = DateTime.UtcNow; if (_database.DatabaseType == DatabaseType.PostgreSQL) { return Query(Builder().WherePostgres(x => x.ReleaseDate < time) .WherePostgres(x => x.Id == artistId)); } return Query(Builder().Where(x => x.ReleaseDate < time) .Where(x => x.Id == artistId)); } 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() { return new SqlBuilder(_database.DatabaseType) .Select(@"""Artists"".""Id"" AS ""ArtistId"", ""Albums"".""Id"" AS ""AlbumId"", SUM(COALESCE(""TrackFiles"".""Size"", 0)) AS ""SizeOnDisk"", COUNT(""Tracks"".""Id"") AS ""TotalTrackCount"", SUM(CASE WHEN ""Tracks"".""TrackFileId"" > 0 THEN 1 ELSE 0 END) AS ""AvailableTrackCount"", SUM(CASE WHEN ""Albums"".""Monitored"" = true OR ""Tracks"".""TrackFileId"" > 0 THEN 1 ELSE 0 END) AS ""TrackCount"", SUM(CASE WHEN ""TrackFiles"".""Id"" IS NULL THEN 0 ELSE 1 END) AS ""TrackFileCount""") .Join((t, r) => t.AlbumReleaseId == r.Id) .Join((r, a) => r.AlbumId == a.Id) .Join((album, artist) => album.ArtistMetadataId == artist.ArtistMetadataId) .LeftJoin((t, f) => t.TrackFileId == f.Id) .Where(x => x.Monitored == true) .GroupBy(x => x.Id) .GroupBy(x => x.Id); } } }