using ErrorOr; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.Extensions.Logging; using MuiCharts.Domain.Models; using MuiCharts.Domain.Repositories; namespace MuiCharts.Infrastructure.Repositories; /// /// Represents a repository for points. /// /// The data context. /// The logger. public class PointRepository( DataContext context, ILogger logger ) : IPointRepository { private readonly DataContext _context = context; private readonly ILogger _logger = logger; /// public async Task> AddOrUpdatePointAsync(Point point) { try { _logger.LogInformation("Adding or updating point {point}", point); Point result = UpsertPoint(point, out bool isNewlyCreated); await _context.SaveChangesAsync(); if (!isNewlyCreated) return (Point?)null; return result; } catch (Exception e) { _logger.LogError(e, "Error adding or updating point {point}", point); return Error.Failure(); } } /// public async Task> AddPointAsync(Point point) { try { _logger.LogInformation("Adding or updating point {point}", point); EntityEntry result = await _context.Points.AddAsync(point); await _context.SaveChangesAsync(); return result.Entity; } catch (Exception e) { _logger.LogError(e, "Error adding point {point}", point); return Error.Failure(); } } public async Task>> AddPointsRangeAsync(IEnumerable points) { try { _logger.LogInformation("Adding points rage"); List updatedPoints = []; foreach (Point point in points) updatedPoints.Add(UpsertPoint(point, out _)); await _context.SaveChangesAsync(); _logger.LogInformation("Added {Count} points", updatedPoints.Count); return updatedPoints; } catch (Exception e) { _logger.LogError(e, "Error adding points {points}", points); return Error.Failure(); } } /// public async Task> DeletePointAsync(int id) { try { _logger.LogInformation("Deleting point {id}", id); Point? point = await _context.Points.FindAsync(id); if (point == null) return Error.NotFound(); if (_context.Tracks.Any(t => t.FirstId == id || t.SecondId == id)) return Error.Conflict(description: "Point is used in a track. Delete track first"); _context.Points.Remove(point); await _context.SaveChangesAsync(); return Result.Deleted; } catch (Exception e) { _logger.LogError(e, "Error deleting point {id}", id); return Error.Failure(); } } /// public async Task> GetPointAsync(int id) { try { _logger.LogInformation("Getting point {id}", id); Point? point = await _context.Points.FindAsync(id); if (point == null) return Error.NotFound(); return point; } catch (Exception e) { _logger.LogError(e, "Error getting point {id}", id); return Error.Failure(); } } /// public Task> GetPointsRangeAsync() { return Task.FromResult(_context.Points.AsQueryable()); } private Point UpsertPoint(Point point, out bool isNewlyCreated) { bool doesExist = _context.Points.Any(p => p.Id == point.Id); isNewlyCreated = !doesExist; Point entity; if (doesExist) entity = _context.Points.Update(point).Entity; else entity = _context.Points.Add(point).Entity; return entity; } }