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.Linq; using System.Text; using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; internal class ClientStorageContarct : IClientStorageContract { private readonly MagicCarpetDbContext _dbContext; private readonly Mapper _mapper; public ClientStorageContarct(MagicCarpetDbContext magicCarpetDbContext) { _dbContext = magicCarpetDbContext; var config = new MapperConfiguration(cfg => { cfg.AddMaps(typeof(MagicCarpetDbContext).Assembly); }); _mapper = new Mapper(config); } public List GetList() { try { return [.. _dbContext.Clients.Select(x => _mapper.Map(x))]; } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public ClientDataModel? GetElementById(string id) { try { return _mapper.Map(GetClientById(id)); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public ClientDataModel? GetElementByFIO(string fio) { try { return _mapper.Map(_dbContext.Clients.FirstOrDefault(x => x.FIO == fio)); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public ClientDataModel? GetElementByPhoneNumber(string phoneNumber) { try { return _mapper.Map(_dbContext.Clients.FirstOrDefault(x => x.PhoneNumber == phoneNumber)); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void AddElement(ClientDataModel clientDataModel) { try { _dbContext.Clients.Add(_mapper.Map(clientDataModel)); _dbContext.SaveChanges(); } catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("Id", clientDataModel.Id); } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_PhoneNumber" }) { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void UpdElement(ClientDataModel clientDataModel) { try { var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id); _dbContext.Clients.Update(_mapper.Map(clientDataModel, element)); _dbContext.SaveChanges(); } catch (ElementNotFoundException) { _dbContext.ChangeTracker.Clear(); throw; } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_PhoneNumber" }) { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void DelElement(string id) { try { var element = GetClientById(id) ?? throw new ElementNotFoundException(id); _dbContext.Clients.Remove(element); _dbContext.SaveChanges(); } catch (ElementNotFoundException) { _dbContext.ChangeTracker.Clear(); throw; } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } private Client? GetClientById(string id) => _dbContext.Clients.FirstOrDefault(x => x.Id == id); }