using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Core.Books; using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Qualities; namespace NzbDrone.Core.History { public interface IHistoryRepository : IBasicRepository { EntityHistory MostRecentForBook(int bookId); EntityHistory MostRecentForDownloadId(string downloadId); List FindByDownloadId(string downloadId); List GetByAuthor(int authorId, EntityHistoryEventType? eventType); List GetByBook(int bookId, EntityHistoryEventType? eventType); List FindDownloadHistory(int idAuthorId, QualityModel quality); void DeleteForAuthor(int authorId); List Since(DateTime date, EntityHistoryEventType? eventType); } public class HistoryRepository : BasicRepository, IHistoryRepository { public HistoryRepository(IMainDatabase database, IEventAggregator eventAggregator) : base(database, eventAggregator) { } public EntityHistory MostRecentForBook(int bookId) { return Query(h => h.BookId == bookId).MaxBy(h => h.Date); } public EntityHistory MostRecentForDownloadId(string downloadId) { return Query(h => h.DownloadId == downloadId).MaxBy(h => h.Date); } public List FindByDownloadId(string downloadId) { return _database.QueryJoined( Builder() .Join((h, a) => h.AuthorId == a.Id) .Join((h, a) => h.BookId == a.Id) .Where(h => h.DownloadId == downloadId), (history, author, book) => { history.Author = author; history.Book = book; return history; }).ToList(); } public List GetByAuthor(int authorId, EntityHistoryEventType? eventType) { var builder = Builder().Where(h => h.AuthorId == authorId); if (eventType.HasValue) { builder.Where(h => h.EventType == eventType); } return Query(builder).OrderByDescending(h => h.Date).ToList(); } public List GetByBook(int bookId, EntityHistoryEventType? eventType) { var builder = Builder() .Join((h, a) => h.BookId == a.Id) .Where(h => h.BookId == bookId); if (eventType.HasValue) { builder.Where(h => h.EventType == eventType); } return _database.QueryJoined( builder, (history, book) => { history.Book = book; return history; }).OrderByDescending(h => h.Date).ToList(); } public List FindDownloadHistory(int idAuthorId, QualityModel quality) { var allowed = new[] { (int)EntityHistoryEventType.Grabbed, (int)EntityHistoryEventType.DownloadFailed, (int)EntityHistoryEventType.BookFileImported }; return Query(h => h.AuthorId == idAuthorId && h.Quality == quality && allowed.Contains((int)h.EventType)); } public void DeleteForAuthor(int authorId) { Delete(c => c.AuthorId == authorId); } protected override SqlBuilder PagedBuilder() => new SqlBuilder(_database.DatabaseType) .Join((h, a) => h.AuthorId == a.Id) .Join((l, r) => l.AuthorMetadataId == r.Id) .Join((h, a) => h.BookId == a.Id); protected override IEnumerable PagedQuery(SqlBuilder builder) => _database.QueryJoined(builder, (history, author, metadata, book) => { author.Metadata = metadata; history.Author = author; history.Book = book; return history; }); public List Since(DateTime date, EntityHistoryEventType? eventType) { var builder = Builder() .Join((h, a) => h.AuthorId == a.Id) .Where(x => x.Date >= date); if (eventType.HasValue) { builder.Where(h => h.EventType == eventType); } return _database.QueryJoined(builder, (history, author) => { history.Author = author; return history; }).OrderBy(h => h.Date).ToList(); } } }