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 progress = await _context.Chapter .Join(_context.AppUserProgresses, chapter => chapter.Id, progress => progress.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 progress .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, }); // var chapters = await _context.Chapter // .Join(_context.AppUserProgresses, chapter => chapter.Id, progress => progress.ChapterId, (chapter, progress) => // new // { // Chapter = chapter, // Progress = progress // }) // .Where(arg => arg.Progress.AppUserId == userId && arg.Progress.PagesRead < arg.Chapter.Pages) // .Join(_context.Series, arg => arg.Progress.SeriesId, series => series.Id, (arg, series) => // new // { // arg.Chapter, // arg.Progress, // Series = series // }) // .AsNoTracking() // //.OrderBy(s => s.Chapter.Number) // .GroupBy(p => p.Series.Id) // .Select(g => g.FirstOrDefault()) // .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, // }) // // //.OrderBy(c => float.Parse(c.Number)) //can't convert to SQL // // .ToListAsync(); // // // return chapters; // return chapters // .OrderBy(c => float.Parse(c.Number), new ChapterSortComparer()) // .DistinctBy(c => c.SeriesName); } } }