diff --git a/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj b/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj index accbdf0..20f5176 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj +++ b/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj @@ -9,7 +9,18 @@ + + + + + + + + + + + @@ -27,4 +38,10 @@ + + + PreserveNewest + + + \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Program.cs b/CarpentryWorkshop/CarpentryWorkshop/Program.cs index 0d4eaf5..c962f01 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Program.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Program.cs @@ -1,4 +1,8 @@ using Unity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Serilog; +using Unity.Microsoft.Logging; using CarpentryWorkshop.Repositories; using CarpentryWorkshop.Repositories.Implementations; @@ -20,12 +24,26 @@ namespace CarpentryWorkshop private static IUnityContainer CreateContainer() { var container = new UnityContainer(); + + container.AddExtension(new LoggingExtension(CreateLoggerFactory())); + 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/CarpentryWorkshop/CarpentryWorkshop/Repositories/IConnectionString.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IConnectionString.cs new file mode 100644 index 0000000..b95132a --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IConnectionString.cs @@ -0,0 +1,6 @@ +namespace CarpentryWorkshop.Repositories; + +public interface IConnectionString +{ + public string ConnectionString { get; } +} diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs index a1b56f3..7e478ef 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs @@ -5,7 +5,6 @@ namespace CarpentryWorkshop.Repositories; public interface IOrderRepository { IEnumerable ReadOrders(DateTime? dateForm = null, DateTime? dateTo = null, int? orderStatus = null, int? orderId = null); - Order ReadOrderById(int orderId); void CreateOrder(Order order); void DeleteOrder(int id); } diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ConnectionString.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ConnectionString.cs new file mode 100644 index 0000000..f09cd9a --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ConnectionString.cs @@ -0,0 +1,6 @@ +namespace CarpentryWorkshop.Repositories.Implementations; + +public class ConnectionString : IConnectionString +{ + string IConnectionString.ConnectionString => "Server=localhost;Port=5432;Database=postgres;"; +} \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs index d86e94c..aa26fcb 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs @@ -1,24 +1,100 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class MaterialReplenishmentRepository : IMaterialReplenishmentRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public MaterialReplenishmentRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } public void CreateMaterialSpent(MaterialReplenishment material) { - } - - public MaterialReplenishment ReadMaterialSpentById(int id) - { - return MaterialReplenishment.CreateOperation(0, string.Empty, 0); - } - - public IEnumerable ReadMaterialsSpent() - { - return []; + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO MaterialReplenishment (Name, Count) + VALUES (@Name, @Count)"; + connection.Execute(queryInsert, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void UpdateMaterialSpent(MaterialReplenishment material) { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryUpdate = @" + UPDATE MaterialReplenishment + SET + Name=@Name, + Count=@Count + WHERE Id=@Id"; + connection.Execute(queryUpdate, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } -} + + public MaterialReplenishment ReadMaterialSpentById(int id) + { + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM MaterialReplenishment + WHERE Id=@id"; + var material = connection.QueryFirst(querySelect, new + { + id + }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(material)); + return material; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } + } + + public IEnumerable ReadMaterialsSpent() + { + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = "SELECT * FROM MaterialReplenishment"; + var materials = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(materials)); + return materials; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } + } +} \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs index fa8864a..0903bdb 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs @@ -1,28 +1,120 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class MaterialRepository : IMaterialRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public MaterialRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } + public void CreateMaterial(Material material) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO Materials (Name, Count, ReservInWarehouse) + VALUES (@Name, @Count, @ReservInWarehouse)"; + connection.Execute(queryInsert, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } + } + public void UpdateMaterial(Material material) + { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryUpdate = @" + UPDATE Materials + SET + Name=@Name, + Count=@Count, + ReservInWarehouse=@ReservInWarehouse + WHERE Id=@Id"; + connection.Execute(queryUpdate, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } public void DeleteMaterial(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Materials + WHERE Id=@id"; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public IEnumerable ReadMaterials() { - return []; + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = "SELECT * FROM Materials"; + var materials = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(materials)); + return materials; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } public Material ReadMaterialById(int id) { - return Material.CreateEntity(id, string.Empty, 0, 0); - } - - public void UpdateMaterial(Material material) - { + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Materials + WHERE Id=@id"; + var material = connection.QueryFirst(querySelect, new + { + id + }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(material)); + return material; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } } } diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs index b3cfeae..62a3663 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs @@ -1,23 +1,90 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class OrderRepository : IOrderRepository { - public void CreateOrder(Order feedReplenishment) + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public OrderRepository(IConnectionString connectionString, ILogger logger) { + _connectionString = connectionString; + _logger = logger; + } + public void CreateOrder(Order order) + { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(order)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + connection.Open(); + using var transaction = connection.BeginTransaction(); + var queryInsert = @" + INSERT INTO Orders (Status, Description) + VALUES (@Status, @Description); + SELECT MAX(Id) FROM Orders"; + var orderId = connection.QueryFirst(queryInsert, order, transaction); + var querySubInsert = @" + INSERT INTO Orders_Products (OrderId, ProductId, Count) + VALUES (@OrderId, @ProductId, @Count)"; + foreach (var elem in order.OrderProduct) + { + connection.Execute(querySubInsert, new + { + orderId, + elem.ProductId, + elem.Count + }, transaction); + } + transaction.Commit(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteOrder(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Orders + WHERE Id=@id"; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public IEnumerable ReadOrders(DateTime? dateForm = null, DateTime? dateTo = null, int? orderStatus = null, int? orderId = null) { - return []; - } - public Order ReadOrderById(int id) - { - return Order.CreateOperation(id, 0, string.Empty, []); + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @"SELECT * FROM Orders"; + var order = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(order)); + return order; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } } + diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs index 2a50786..6146b9d 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs @@ -1,28 +1,150 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class ProductRepository : IProductRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public ProductRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } public void CreateProduct(Product product) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(product)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + connection.Open(); + using var transaction = connection.BeginTransaction(); + var queryInsert = @" + INSERT INTO Products (Name, Type, CountInWarehouse) + VALUES (@Name, @Type, @CountInWarehouse); + SELECT MAX(Id) FROM Products"; + var productId = connection.QueryFirst(queryInsert, product, transaction); + var querySubInsert = @" + INSERT INTO Products_Materials (ProductId, MaterialId, Count) + VALUES (@ProductId, @MaterialId, @Count)"; + foreach (var elem in product.ProductMaterial) + { + connection.Execute(querySubInsert, new + { + productId, + elem.MaterialId, + elem.Count + }, transaction); + } + transaction.Commit(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteProduct(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Products + WHERE Id=@id"; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public IEnumerable ReadProducts() { - return []; + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @"SELECT * FROM Products"; + var product = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(product)); + return product; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } public Product ReadProductById(int id) { - return Product.CreateEntity(id, string.Empty, 0, 0, []); + _logger.LogInformation("Получение объекта по ID: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" SELECT * FROM Products WHERE Id = @Id"; + var product = connection.QueryFirstOrDefault(querySelect, new { Id = id }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(product)); + return product; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объекта по ID: {id}", id); + throw; + } } public void UpdateProduct(Product product) { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(product)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + connection.Open(); + using var transaction = connection.BeginTransaction(); + + var queryUpdate = @" + UPDATE Products + SET Name = @Name, Type = @Type, CountInWarehouse = @CountInWarehouse + WHERE Id = @Id"; + connection.Execute(queryUpdate, product, transaction); + + var queryDelete = @" + DELETE FROM Products_Materials + WHERE ProductId = @ProductId"; + connection.Execute(queryDelete, new { ProductId = product.Id }, transaction); + + var querySubInsert = @" + INSERT INTO Products_Materials (ProductId, MaterialId, Count) + VALUES (@ProductId, @MaterialId, @Count)"; + foreach (var elem in product.ProductMaterial) + { + connection.Execute(querySubInsert, new + { + ProductId = product.Id, + elem.MaterialId, + elem.Count + }, transaction); + } + + transaction.Commit(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } } diff --git a/CarpentryWorkshop/CarpentryWorkshop/appsettings.json b/CarpentryWorkshop/CarpentryWorkshop/appsettings.json new file mode 100644 index 0000000..540cd04 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/appsettings.json @@ -0,0 +1,15 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.File" ], + "MinimumLevel": "Debug", + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Logs.txt", + "rollingInterval": "Day" + } + } + ] + } +} \ No newline at end of file