diff --git a/Persistence.API/Controllers/SetpointController.cs b/Persistence.API/Controllers/SetpointController.cs new file mode 100644 index 0000000..3e8e94c --- /dev/null +++ b/Persistence.API/Controllers/SetpointController.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Mvc; +using Persistence.Models; +using Persistence.Repositories; + +namespace Persistence.API.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class SetpointController : ControllerBase, ISetpointApi + { + private readonly ISetpointRepository setpointRepository; + + public SetpointController(ISetpointRepository setpointRepository) + { + this.setpointRepository = setpointRepository; + } + + [HttpPost("current")] + public Task>> GetCurrentAsync(IEnumerable setpointKeys, CancellationToken token) + { + throw new NotImplementedException(); + } + + [HttpPost("history")] + public async Task>> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + { + var result = await setpointRepository.GetHistoryAsync(setpointKeys, historyMoment, token); + + return Ok(result); + } + + [HttpPost("log")] + public async Task>>> GetLogAsync([FromBody] IEnumerable setpointKeys, CancellationToken token) + { + var result = await setpointRepository.GetLogAsync(setpointKeys, token); + + return Ok(result); + } + + [HttpPost("save")] + public async Task> SaveAsync(Guid setpointKey, object newValue, CancellationToken token) + { + var result = await setpointRepository.SaveAsync(setpointKey, newValue, token); + + return Ok(result); + } + } +} diff --git a/Persistence.Database/Model/IPersistenceDbContext.cs b/Persistence.Database/Model/IPersistenceDbContext.cs index af837d6..2c1aebb 100644 --- a/Persistence.Database/Model/IPersistenceDbContext.cs +++ b/Persistence.Database/Model/IPersistenceDbContext.cs @@ -11,6 +11,7 @@ namespace Persistence.Database.Model; public interface IPersistenceDbContext : IDisposable { DbSet DataSaub { get; } - DatabaseFacade Database { get; } + DbSet Setpoint { get; } + DatabaseFacade Database { get; } Task SaveChangesAsync(CancellationToken cancellationToken); } diff --git a/Persistence.Database/Model/ISetpointData.cs b/Persistence.Database/Model/ISetpointData.cs new file mode 100644 index 0000000..630af70 --- /dev/null +++ b/Persistence.Database/Model/ISetpointData.cs @@ -0,0 +1,10 @@ +namespace Persistence.Database.Model +{ + public interface ISetpointData + { + public Guid Key { get; set; } + public object Value { get; set; } + public DateTimeOffset Created { get; set; } + public int IdUser { get; set; } + } +} diff --git a/Persistence.Database/Model/PersistenceDbContext.cs b/Persistence.Database/Model/PersistenceDbContext.cs index 3baf334..5f4b965 100644 --- a/Persistence.Database/Model/PersistenceDbContext.cs +++ b/Persistence.Database/Model/PersistenceDbContext.cs @@ -1,17 +1,16 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Diagnostics.Metrics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; +using Microsoft.EntityFrameworkCore; namespace Persistence.Database.Model; public partial class PersistenceDbContext : DbContext, IPersistenceDbContext { public DbSet DataSaub => Set(); + public DbSet Setpoint => Set(); + + public PersistenceDbContext() + { + } + public PersistenceDbContext(DbContextOptions options) { } diff --git a/Persistence.Database/Model/Setpoint.cs b/Persistence.Database/Model/Setpoint.cs new file mode 100644 index 0000000..50d7f24 --- /dev/null +++ b/Persistence.Database/Model/Setpoint.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Persistence.Database.Model +{ + [PrimaryKey(nameof(Key), nameof(Created))] + public class Setpoint : ISetpointData + { + [Comment("Ключ")] + public Guid Key { get; set; } + + [Column(TypeName = "jsonb"), Comment("Значение уставки")] + public required object Value { get; set; } + + [Comment("Дата изменения уставки")] + public DateTimeOffset Created { get; set; } + + [Comment("Id автора последнего изменения")] + public int IdUser { get; set; } + } +} diff --git a/Persistence.Database/Model/SetpointDictionary.cs b/Persistence.Database/Model/SetpointDictionary.cs new file mode 100644 index 0000000..cd20624 --- /dev/null +++ b/Persistence.Database/Model/SetpointDictionary.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Persistence.Database.Model +{ + public class SetpointDictionary + { + [Key, Comment("Ключ")] + public Guid Key { get; set; } + + [Comment("Наименование")] + public required string Name { get; set; } + + [Comment("Описание")] + public string? Description { get; set; } + } +} diff --git a/Persistence.Repository/Data/SetpointDto.cs b/Persistence.Repository/Data/SetpointDto.cs new file mode 100644 index 0000000..261b1bc --- /dev/null +++ b/Persistence.Repository/Data/SetpointDto.cs @@ -0,0 +1,10 @@ +namespace Persistence.Repository.Data +{ + public class SetpointDto + { + public int Id { get; set; } + public required object Value { get; set; } + public DateTimeOffset Edit { get; set; } + public int IdUser { get; set; } + } +} diff --git a/Persistence.Repository/DependencyInjection.cs b/Persistence.Repository/DependencyInjection.cs index 17904c8..e77edd0 100644 --- a/Persistence.Repository/DependencyInjection.cs +++ b/Persistence.Repository/DependencyInjection.cs @@ -21,9 +21,10 @@ public static class DependencyInjection services.AddDbContext(options => options.UseNpgsql(configuration.GetConnectionString(connectionStringName))); - services.AddScoped(provider => provider.GetRequiredService()); + services.AddScoped(provider => provider.GetRequiredService()); services.AddTransient, TimeSeriesDataRepository>(); + services.AddTransient(); return services; } diff --git a/Persistence.Repository/Repositories/SetpointRepository.cs b/Persistence.Repository/Repositories/SetpointRepository.cs new file mode 100644 index 0000000..04304ce --- /dev/null +++ b/Persistence.Repository/Repositories/SetpointRepository.cs @@ -0,0 +1,70 @@ +using Mapster; +using Microsoft.EntityFrameworkCore; +using Persistence.Database.Model; +using Persistence.Models; +using Persistence.Repositories; + +namespace Persistence.Repository.Repositories +{ + public class SetpointRepository : ISetpointRepository + { + private DbContext db; + public SetpointRepository(DbContext db) + { + this.db = db; + } + + protected virtual IQueryable GetQueryReadOnly() => db.Set(); + + public async Task> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + { + var query = GetQueryReadOnly(); + var entities = await query + .Where(e => setpointKeys.Contains(e.Key) && e.Created.Date == historyMoment.Date) + .ToArrayAsync(token); + var dtos = entities.Select(e => e.Adapt()); + + return dtos; + } + + public async Task>> GetLogAsync(IEnumerable setpointKeys, CancellationToken token) + { + var query = GetQueryReadOnly(); + var entities = await query + .Where(e => setpointKeys.Contains(e.Key)) + .ToArrayAsync(token); + var dtos = entities + .GroupBy(e => e.Key) + .Select(e => new KeyValuePair>( + e.Key, + e.Select(s => s.Adapt()) + )).ToDictionary(); + + return dtos; + } + + public async Task SaveAsync(Guid setpointKey, object newValue, CancellationToken token) + { + try + { + var entity = new Setpoint() + { + Key = setpointKey, + Value = newValue, + IdUser = 0, // ToDo: откуда тянуть? + Created = DateTimeOffset.Now.ToUniversalTime() + }; + + await db.Set().AddAsync(entity, token); + var result = await db.SaveChangesAsync(token); + + return result; + } + catch(Exception ex) + { + var t = ex.Message; + return 0; + } + } + } +} diff --git a/Persistence/Models/SetpointLogDto.cs b/Persistence/Models/SetpointLogDto.cs index 8c259ca..f825aae 100644 --- a/Persistence/Models/SetpointLogDto.cs +++ b/Persistence/Models/SetpointLogDto.cs @@ -7,6 +7,6 @@ using System.Threading.Tasks; namespace Persistence.Models; public class SetpointLogDto : SetpointValueDto { - public DateTimeOffset Edit { get; set; } + public DateTimeOffset Created { get; set; } public int IdUser { get; set; } } diff --git a/Persistence/Models/SetpointValueDto.cs b/Persistence/Models/SetpointValueDto.cs index 7b49143..ca43330 100644 --- a/Persistence/Models/SetpointValueDto.cs +++ b/Persistence/Models/SetpointValueDto.cs @@ -8,7 +8,7 @@ namespace Persistence.Models; public class SetpointValueDto { - public int Id { get; set; } - public object Value { get; set; } + public Guid Key { get; set; } + public required object Value { get; set; } } diff --git a/Persistence/Repositories/ISetpointRepository.cs b/Persistence/Repositories/ISetpointRepository.cs index 38bbbf4..d315725 100644 --- a/Persistence/Repositories/ISetpointRepository.cs +++ b/Persistence/Repositories/ISetpointRepository.cs @@ -1,10 +1,4 @@ -using Microsoft.AspNetCore.Mvc; -using Persistence.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Persistence.Models; namespace Persistence.Repositories; @@ -17,19 +11,19 @@ public interface ISetpointRepository /// /// Получить значения уставок за определенный момент времени /// - /// + /// /// дата, на которую получаем данные /// /// - Task> GetHistoryAsync(IEnumerable setpoitKeys, DateTimeOffset historyMoment, CancellationToken token); + Task> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token); /// /// Получить историю изменений значений уставок /// - /// + /// /// /// - Task>> GetLogAsync(IEnumerable setpoitKeys, CancellationToken token); + Task>> GetLogAsync(IEnumerable setpointKeys, CancellationToken token); /// /// Метод сохранения уставки @@ -41,5 +35,5 @@ public interface ISetpointRepository /// /// to do /// id User учесть в соответствующем методе репозитория - Task SaveAsync(Guid setpointKey, int idUser, object newValue, CancellationToken token); + Task SaveAsync(Guid setpointKey, object newValue, CancellationToken token); }