using Data.Data.Repositories; using Data.Errors; using DeepDrftData.Data; using DeepDrftModels.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace DeepDrftData.Repositories; public class TrackRepository : Repository { private readonly DeepDrftContext _context; public TrackRepository( DeepDrftContext context, ILogger> logger, IDbExceptionClassifier? classifier = null) : base(context, logger, classifier: classifier) { _context = context; } // Lookup by vault entry key. The base Repository<> only exposes id-based queries, so this // queries the DbSet directly. Returns null on miss (service wraps in ResultContainer). public async Task GetByEntryKeyAsync(string entryKey) => await _context.Tracks.FirstOrDefaultAsync(t => t.EntryKey == entryKey); // Picks one track uniformly at random. Two round-trips (count, then a single offset row) // rather than ORDER BY random() so the database never sorts the whole table — the catalogue // is small today but this keeps the cost flat as it grows. Returns null when empty so the // service surfaces a valid empty-library state, not an error. Queries the DbSet directly, // mirroring GetByEntryKeyAsync, since the base Repository<> exposes only id-based reads. public async Task GetRandomAsync(CancellationToken cancellationToken = default) { var count = await _context.Tracks.CountAsync(cancellationToken); if (count == 0) return null; var index = Random.Shared.Next(count); return await _context.Tracks .OrderBy(t => t.Id) .Skip(index) .Take(1) .FirstOrDefaultAsync(cancellationToken); } protected override void UpdateEntity(TrackEntity target, TrackEntity source) { base.UpdateEntity(target, source); // copies CreatedAt, UpdatedAt, IsDeleted target.EntryKey = source.EntryKey; target.TrackName = source.TrackName; target.Artist = source.Artist; target.Album = source.Album; target.Genre = source.Genre; target.ReleaseDate = source.ReleaseDate; target.ImagePath = source.ImagePath; target.CreatedByUserId = source.CreatedByUserId; } }