using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; using Microsoft.EntityFrameworkCore; using Npgsql; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; internal class TourStorageContract : ITourStorageContract { private readonly MagicCarpetDbContext _dbContext; private readonly Mapper _mapper; public TourStorageContract(MagicCarpetDbContext dbContext) { _dbContext = dbContext; var config = new MapperConfiguration(cfg => { cfg.AddMaps(typeof(Tour)); }); _mapper = new Mapper(config); } public List GetList() { try { return [.. _dbContext.Tours.Select(x => _mapper.Map(x))]; } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public List GetHistoryByTourId(string tourId) { try { return [.. _dbContext.TourHistories.Where(x => x.TourId == tourId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map(x))]; } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public TourDataModel? GetElementById(string id) { try { return _mapper.Map(GetTourById(id)); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public TourDataModel? GetElementByName(string name) { try { return _mapper.Map(_dbContext.Tours.FirstOrDefault(x => x.TourName == name)); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void AddElement(TourDataModel tourDataModel) { try { _dbContext.Tours.Add(_mapper.Map(tourDataModel)); _dbContext.SaveChanges(); } catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("Id", tourDataModel.Id); } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Tours_TourName" }) { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("TourName", tourDataModel.TourName); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void UpdElement(TourDataModel tourDataModel) { try { var element = GetTourById(tourDataModel.Id) ?? throw new ElementNotFoundException(tourDataModel.Id); _dbContext.Tours.Update(_mapper.Map(tourDataModel, element)); _dbContext.SaveChanges(); } catch (ElementNotFoundException) { _dbContext.ChangeTracker.Clear(); throw; } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Tours_TourName" }) { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("TourName", tourDataModel.TourName); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void DelElement(string id) { try { var element = GetTourById(id) ?? throw new ElementNotFoundException(id); _dbContext.Tours.Remove(element); _dbContext.SaveChanges(); } catch (ElementNotFoundException) { _dbContext.ChangeTracker.Clear(); throw; } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void ResElement(string id) { try { var element = GetTourById(id) ?? throw new ElementNotFoundException(id); _dbContext.SaveChanges(); } catch { _dbContext.ChangeTracker.Clear(); throw; } } private Tour? GetTourById(string id) => _dbContext.Tours.FirstOrDefault(x => x.Id == id); }