using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading.Tasks; using Dapper; 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 LibraryRepository : ILibraryRepository { private readonly IDbConnection _dbConnection; private readonly IDbContextFactory _dbContextFactory; public LibraryRepository(IDbContextFactory dbContextFactory, IDbConnection dbConnection) { _dbContextFactory = dbContextFactory; _dbConnection = dbConnection; } public async Task Add(LibraryPath libraryPath) { await using TvContext context = _dbContextFactory.CreateDbContext(); await context.LibraryPaths.AddAsync(libraryPath); await context.SaveChangesAsync(); return libraryPath; } public Task> Get(int libraryId) { using TvContext context = _dbContextFactory.CreateDbContext(); return context.Libraries .Include(l => l.Paths) .OrderBy(l => l.Id) .SingleOrDefaultAsync(l => l.Id == libraryId) .Map(Optional); } public Task> GetLocal(int libraryId) { using TvContext context = _dbContextFactory.CreateDbContext(); return context.LocalLibraries .OrderBy(l => l.Id) .SingleOrDefaultAsync(l => l.Id == libraryId) .Map(Optional); } public Task> GetAll() { using TvContext context = _dbContextFactory.CreateDbContext(); return context.Libraries .AsNoTracking() .Include(l => l.MediaSource) .ToListAsync(); } public Task UpdateLastScan(Library library) => _dbConnection.ExecuteAsync( "UPDATE Library SET LastScan = @LastScan WHERE Id = @Id", new { library.LastScan, library.Id }).ToUnit(); public Task> GetLocalPaths(int libraryId) { using TvContext context = _dbContextFactory.CreateDbContext(); return context.LocalLibraries .Include(l => l.Paths) .OrderBy(l => l.Id) .SingleOrDefaultAsync(l => l.Id == libraryId) .Map(Optional) .Match(l => l.Paths, () => new List()); } public Task> GetPath(int libraryPathId) { using TvContext context = _dbContextFactory.CreateDbContext(); return context.LibraryPaths .OrderBy(lp => lp.Id) .SingleOrDefaultAsync(lp => lp.Id == libraryPathId) .Map(Optional); } public Task CountMediaItemsByPath(int libraryPathId) => _dbConnection.QuerySingleAsync( @"SELECT COUNT(*) FROM MediaItem WHERE LibraryPathId = @LibraryPathId", new { LibraryPathId = libraryPathId }); public Task> GetMediaIdsByLocalPath(int libraryPathId) => _dbConnection.QueryAsync( @"SELECT Id FROM MediaItem WHERE LibraryPathId = @LibraryPathId", new { LibraryPathId = libraryPathId }) .Map(result => result.ToList()); public async Task DeleteLocalPath(int libraryPathId) { await using TvContext context = _dbContextFactory.CreateDbContext(); LibraryPath libraryPath = await context.LibraryPaths.FindAsync(libraryPathId); context.LibraryPaths.Remove(libraryPath); await context.SaveChangesAsync(); } } }