using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using API.Comparators; using API.DTOs; using API.Entities; using API.Extensions; using API.Interfaces; using AutoMapper; using AutoMapper.QueryableExtensions; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace API.Data { public class VolumeRepository : IVolumeRepository { private readonly DataContext _context; private readonly IMapper _mapper; private readonly ILogger _logger; public VolumeRepository(DataContext context, IMapper mapper, ILogger logger) { _context = context; _mapper = mapper; _logger = logger; } public void Update(Volume volume) { _context.Entry(volume).State = EntityState.Modified; } /// /// Returns a Chapter for an Id. Includes linked s. /// /// /// public async Task GetChapterAsync(int chapterId) { return await _context.Chapter .Include(c => c.Files) .SingleOrDefaultAsync(c => c.Id == chapterId); } /// /// Returns Chapters for a volume id. /// /// /// public async Task> GetChaptersAsync(int volumeId) { return await _context.Chapter .Where(c => c.VolumeId == volumeId) .ToListAsync(); } /// /// Returns the cover image for a chapter id. /// /// /// public async Task GetChapterCoverImageAsync(int chapterId) { return await _context.Chapter .Where(c => c.Id == chapterId) .Select(c => c.CoverImage) .AsNoTracking() .SingleOrDefaultAsync(); } public async Task GetChapterDtoAsync(int chapterId) { var chapter = await _context.Chapter .Include(c => c.Files) .ProjectTo(_mapper.ConfigurationProvider) .AsNoTracking() .SingleOrDefaultAsync(c => c.Id == chapterId); return chapter; } public async Task> GetFilesForChapter(int chapterId) { return await _context.MangaFile .Where(c => chapterId == c.Id) .AsNoTracking() .ToListAsync(); } /// /// Gets the first (ordered) volume/chapter in a series where the user has progress on it. Only completed volumes/chapters, next entity shouldn't /// have any read progress on it. /// /// /// /// /// public async Task> GetContinueReading(int userId, int libraryId, int limit) { _logger.LogInformation("Get Continue Reading"); var chapters = await _context.Chapter .Join(_context.AppUserProgresses, c => c.Id, p => p.ChapterId, (chapter, progress) => new { Chapter = chapter, Progress = progress }) .Join(_context.Series, arg => arg.Progress.SeriesId, series => series.Id, (arg, series) => new { arg.Chapter, arg.Progress, Series = series }) .AsNoTracking() .Where(arg => arg.Progress.AppUserId == userId && arg.Progress.PagesRead < arg.Chapter.Pages) .OrderByDescending(d => d.Progress.LastModified) .Take(limit) .ToListAsync(); return chapters .OrderBy(c => float.Parse(c.Chapter.Number), new ChapterSortComparer()) .DistinctBy(p => p.Series.Id) .Select(arg => new InProgressChapterDto() { Id = arg.Chapter.Id, Number = arg.Chapter.Number, Range = arg.Chapter.Range, SeriesId = arg.Progress.SeriesId, SeriesName = arg.Series.Name, LibraryId = arg.Series.LibraryId, Pages = arg.Chapter.Pages, }); } } }