diff --git a/PIbd-23_Gutorov_I.A._IT-Company/PIbd-23_Gutorov_I.A._IT-Company.csproj b/PIbd-23_Gutorov_I.A._IT-Company/PIbd-23_Gutorov_I.A._IT-Company.csproj index 5159f6f..b1e209f 100644 --- a/PIbd-23_Gutorov_I.A._IT-Company/PIbd-23_Gutorov_I.A._IT-Company.csproj +++ b/PIbd-23_Gutorov_I.A._IT-Company/PIbd-23_Gutorov_I.A._IT-Company.csproj @@ -10,7 +10,19 @@ + + + + + + + + + + + + @@ -28,4 +40,10 @@ + + + PreserveNewest + + + \ No newline at end of file diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Program.cs b/PIbd-23_Gutorov_I.A._IT-Company/Program.cs index 3c5e10d..8114fc4 100644 --- a/PIbd-23_Gutorov_I.A._IT-Company/Program.cs +++ b/PIbd-23_Gutorov_I.A._IT-Company/Program.cs @@ -1,6 +1,10 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using PIbd_23_Gutorov_I.A._IT_Company.Repositories; using PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations; +using Serilog; using Unity; +using Unity.Microsoft.Logging; namespace PIbd_23_Gutorov_I.A._IT_Company { @@ -22,13 +26,28 @@ namespace PIbd_23_Gutorov_I.A._IT_Company { var container = new UnityContainer(); + container.AddExtension(new LoggingExtension(CreateLoggerFactory())); + container.RegisterType(); container.RegisterType(); container.RegisterType(); container.RegisterType(); container.RegisterType(); + container.RegisterType(); + return container; } + + private static LoggerFactory CreateLoggerFactory() + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddSerilog(new LoggerConfiguration() + .ReadFrom.Configuration(new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json").Build()) + .CreateLogger()); + return loggerFactory; + } } } \ No newline at end of file diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/IConnectionString.cs b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/IConnectionString.cs new file mode 100644 index 0000000..10298a0 --- /dev/null +++ b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/IConnectionString.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories; + +public interface IConnectionString +{ + public string ConnectionString { get; } +} diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ConnectionString.cs b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ConnectionString.cs new file mode 100644 index 0000000..d5afdbc --- /dev/null +++ b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ConnectionString.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations; + +public class ConnectionString : IConnectionString +{ + string IConnectionString.ConnectionString => "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=OTP"; +} diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ContractRepository.cs b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ContractRepository.cs index 1e14ec1..c6a8c40 100644 --- a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ContractRepository.cs +++ b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ContractRepository.cs @@ -1,19 +1,97 @@ -using PIbd_23_Gutorov_I.A._IT_Company.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations; public class ContractRepository : IContractRepository { - public void CreateContract(Contract contract) + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + + public ContractRepository(IConnectionString connectionString, ILogger logger) { + _connectionString = connectionString; + _logger = logger; + } + + public void CreateContract(Entities.Contract contract) + { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(contract)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + connection.Open(); + using var transaction = connection.BeginTransaction(); + + var queryInsert = @" + INSERT INTO Contracts (CustomerId, ExecutorId, Category, + ConclusionDate, Deadline, PaymentAmount) + VALUES (@CustomerId, @ExecutorId, @Category, + @ConclusionDate, @Deadline, @PaymentAmount); + SELECT MAX(Id) FROM Contracts; + "; + var contractId = connection.QueryFirst(queryInsert, contract, transaction); + + var querySubInsert = @" + INSERT INTO ServiceContract (ServiceId, ContractId) + VALUES (@ServiceId, @ContractId); + "; + foreach (var elem in contract.Services) + { + var serviceId = elem.Id; + connection.Execute(querySubInsert, new { serviceId, contractId }, transaction); + } + + transaction.Commit(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteContract(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Contracts + WHERE Id = @id + "; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } - public IEnumerable ReadContracts(DateTime? dateFrom = null, DateTime? dateTo = null, int? customerId = null, int? executorId = null) + public IEnumerable ReadContracts(DateTime? dateFrom = null, DateTime? dateTo = null, int? customerId = null, int? executorId = null) { - return []; + _logger.LogInformation("Получение всех объектов"); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @"SELECT * FROM Contracts"; + var contracts = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(contracts)); + return contracts; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } } diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerExecutorReviewRepository.cs b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerExecutorReviewRepository.cs index ebd6a67..cefc193 100644 --- a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerExecutorReviewRepository.cs +++ b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerExecutorReviewRepository.cs @@ -1,20 +1,83 @@ -using PIbd_23_Gutorov_I.A._IT_Company.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; +using PIbd_23_Gutorov_I.A._IT_Company.Entities; namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations; public class CustomerExecutorReviewRepository : ICustomerExecutorReviewRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + + public CustomerExecutorReviewRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } + public void CreateCustomerExecutorReview(CustomerExecutorReview customerContractReview) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(customerContractReview)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO CustomerExecutorReviews (CustomerId, ExecutorId, Review, Grade) + VALUES (@CustomerId, @ExecutorId, @Review, @Grade); + "; + connection.Execute(queryInsert, customerContractReview); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public CustomerExecutorReview ReadCustomerExecutorReviewById(int id) { - return CustomerExecutorReview.CreateElement(0, 0, 0, string.Empty, 0); + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM CustomerExecutorReviews WHERE Id = @Id; + "; + var customerEexcutorReview = connection.QueryFirst(querySelect, new { id }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(customerEexcutorReview)); + return customerEexcutorReview; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } } public IEnumerable ReadCustomerExecutorReviews(int? customerId = null, int? executorId = null) { - return []; + _logger.LogInformation("Получение всех объектов"); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM CustomerExecutorReviews; + "; + var customerExecutorReviews = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(customerExecutorReviews)); + return customerExecutorReviews; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } } diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerRepository.cs b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerRepository.cs index 618d76a..1f3ba11 100644 --- a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerRepository.cs +++ b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/CustomerRepository.cs @@ -1,28 +1,125 @@ -using PIbd_23_Gutorov_I.A._IT_Company.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; +using PIbd_23_Gutorov_I.A._IT_Company.Entities; namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations; public class CustomerRepository : ICustomerRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + + public CustomerRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } + public void CreateCustomer(Customer customer) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(customer)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO Customers (Name, Contact, Address) + VALUES (@Name, @Contact, @Address); + "; + connection.Execute(queryInsert, customer); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteCustomer(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Customers WHERE Id = @Id; + "; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public Customer ReadCustomerById(int id) { - return Customer.CreateEntity(0, string.Empty, string.Empty, string.Empty); + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Customers WHERE Id = @Id; + "; + var customer = connection.QueryFirst(querySelect, new { id }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(customer)); + return customer; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } } public IEnumerable ReadCustomers() { - return []; + _logger.LogInformation("Получение всех объектов"); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Customers; + "; + var customers = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(customers)); + return customers; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } public void UpdateCustomer(Customer customer) { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(customer)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryUpdate = @" + UPDATE Customers + SET Name = @Name, Contact = @Contact, Address = @Address + WHERE Id = @Id; + "; + connection.Execute(queryUpdate, customer); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } } diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ExecutorRepository.cs b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ExecutorRepository.cs index 6533fc8..d4b663b 100644 --- a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ExecutorRepository.cs +++ b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ExecutorRepository.cs @@ -1,28 +1,125 @@ -using PIbd_23_Gutorov_I.A._IT_Company.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; +using PIbd_23_Gutorov_I.A._IT_Company.Entities; namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations; public class ExecutorRepository : IExecutorRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + + public ExecutorRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } + public void CreateExecutor(Executor executor) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(executor)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO Executors (Name, Post) + VALUES (@Name, @Post); + "; + connection.Execute(queryInsert, executor); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteExecutor(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Executors WHERE Id = @Id; + "; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public Executor ReadExecutorById(int id) { - return Executor.CreateEntity(0, string.Empty, Entities.Enums.ExecutorPost.None); + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Executors WHERE Id = @Id; + "; + var executor = connection.QueryFirst(querySelect, new { id }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(executor)); + return executor; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } } public IEnumerable ReadExecutors() { - return []; + _logger.LogInformation("Получение всех объектов"); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Executors; + "; + var executors = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(executors)); + return executors; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } public void UpdateExecutor(Executor executor) { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(executor)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryUpdate = @" + UPDATE Executors + SET Name = @Name, Post = @Post + WHERE Id = @Id; + "; + connection.Execute(queryUpdate, executor); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } } diff --git a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ServiceRepository.cs b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ServiceRepository.cs index 11f9679..85718cb 100644 --- a/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ServiceRepository.cs +++ b/PIbd-23_Gutorov_I.A._IT-Company/Repositories/Implementations/ServiceRepository.cs @@ -1,28 +1,127 @@ -using PIbd_23_Gutorov_I.A._IT_Company.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; +using PIbd_23_Gutorov_I.A._IT_Company.Entities; +using System.CodeDom.Compiler; namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations; -internal class ServiceRepository : IServiceRepository +public class ServiceRepository : IServiceRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + + public ServiceRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } + + public void CreateService(Service service) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(service)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO Services (Description) + VALUES (@Description); + "; + connection.Execute(queryInsert, service); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteService(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Services WHERE Id = @Id; + "; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public Service ReadServiceById(int id) { - return Service.CreateEntity(0, string.Empty); + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Services WHERE Id = @Id; + "; + var service = connection.QueryFirst(querySelect, new { id }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(service)); + return service; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } } public IEnumerable ReadServices() { - return []; + _logger.LogInformation("Получение всех объектов"); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Services; + "; + var services = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(services)); + return services; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } public void UpdateService(Service service) { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(service)); + + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryUpdate = @" + UPDATE Services + SET Description = @Description + WHERE Id = @Id; + "; + connection.Execute(queryUpdate, service); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } } \ No newline at end of file diff --git a/PIbd-23_Gutorov_I.A._IT-Company/appsettings.json b/PIbd-23_Gutorov_I.A._IT-Company/appsettings.json new file mode 100644 index 0000000..8578938 --- /dev/null +++ b/PIbd-23_Gutorov_I.A._IT-Company/appsettings.json @@ -0,0 +1,15 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.File" ], + "MinimumLevel": "Debug", + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Logs/it-company_log.txt", + "rollingInterval": "Day" + } + } + ] + } +} \ No newline at end of file