using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.AggregateModels; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using Microsoft.EntityFrameworkCore; using static LanguageExt.Prelude; namespace ErsatzTV.Infrastructure.Data.Repositories { public class MediaItemRepository : IMediaItemRepository { private readonly TvContext _dbContext; public MediaItemRepository(TvContext dbContext) => _dbContext = dbContext; public async Task Add(MediaItem mediaItem) { await _dbContext.MediaItems.AddAsync(mediaItem); await _dbContext.SaveChangesAsync(); return mediaItem.Id; } public Task> Get(int id) => _dbContext.MediaItems .Include(i => i.Source) .SingleOrDefaultAsync(i => i.Id == id) .Map(Optional); public Task> GetAll() => _dbContext.MediaItems.ToListAsync(); public Task> Search(string searchString) { IQueryable data = from c in _dbContext.MediaItems.Include(c => c.Source) select c; if (!string.IsNullOrEmpty(searchString)) { data = data.Where(c => EF.Functions.Like(c.Metadata.Title, $"%{searchString}%")); } return data.ToListAsync(); } public Task> GetPageByType(MediaType mediaType, int pageNumber, int pageSize) => mediaType switch { MediaType.Movie => _dbContext.MediaItemSummaries.FromSqlRaw( @"SELECT Id AS MediaItemId, Metadata_Title AS Title, Metadata_SortTitle AS SortTitle, substr(Metadata_Aired, 1, 4) AS Subtitle, Poster FROM MediaItems WHERE Metadata_MediaType=2 ORDER BY Metadata_SortTitle LIMIT {0} OFFSET {1}", pageSize, (pageNumber - 1) * pageSize) .AsNoTracking() .ToListAsync(), MediaType.TvShow => _dbContext.MediaItemSummaries.FromSqlRaw( @"SELECT min(Id) AS MediaItemId, Metadata_Title AS Title, Metadata_SortTitle AS SortTitle, count(*) || ' Episodes' AS Subtitle, max(Poster) AS Poster FROM MediaItems WHERE Metadata_MediaType=1 GROUP BY Metadata_Title, Metadata_SortTitle ORDER BY Metadata_SortTitle LIMIT {0} OFFSET {1}", pageSize, (pageNumber - 1) * pageSize) .AsNoTracking() .ToListAsync(), _ => Task.FromResult(new List()) }; public Task GetCountByType(MediaType mediaType) => mediaType switch { MediaType.Movie => _dbContext.MediaItems .Filter(i => i.Metadata.MediaType == mediaType) .CountAsync(), MediaType.TvShow => _dbContext.MediaItems .Filter(i => i.Metadata.MediaType == mediaType) .GroupBy(i => new { i.Metadata.Title, i.Metadata.SortTitle }) .CountAsync(), _ => Task.FromResult(0) }; public Task> GetAllByMediaSourceId(int mediaSourceId) => _dbContext.MediaItems .Filter(i => i.MediaSourceId == mediaSourceId) .ToListAsync(); public async Task Update(MediaItem mediaItem) { _dbContext.MediaItems.Update(mediaItem); await _dbContext.SaveChangesAsync(); } public async Task Delete(int mediaItemId) { MediaItem mediaItem = await _dbContext.MediaItems.FindAsync(mediaItemId); _dbContext.MediaItems.Remove(mediaItem); await _dbContext.SaveChangesAsync(); } } }