diff --git a/Persistence.API/Controllers/TimeSeriesController.cs b/Persistence.API/Controllers/TimeSeriesController.cs index e6c74ef..a4a860a 100644 --- a/Persistence.API/Controllers/TimeSeriesController.cs +++ b/Persistence.API/Controllers/TimeSeriesController.cs @@ -19,24 +19,32 @@ public class TimeSeriesController : ControllerBase, ITimeSeriesDataApi GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) + public async Task Get(DateTimeOffset dateBegin, CancellationToken token) { - var result = await this.timeSeriesDataRepository.GetAsync(dateBegin, dateEnd, token); + var result = await this.timeSeriesDataRepository.GetGtDate(dateBegin, token); return Ok(result); - } [HttpGet("datesRange")] - public async Task GetDatesRangeAsync(CancellationToken token) + public async Task GetDatesRange(CancellationToken token) { - var result = await this.timeSeriesDataRepository.GetDatesRangeAsync(token); + var result = await this.timeSeriesDataRepository.GetDatesRange(token); + return Ok(result); + } + + [HttpGet("resampled")] + public async Task GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default) + { + var result = await this.timeSeriesDataRepository.GetResampledData(dateBegin, intervalSec, approxPointsCount, token); return Ok(result); } [HttpPost] - public async Task InsertRangeAsync(IEnumerable dtos, CancellationToken token) + public async Task InsertRange(IEnumerable dtos, CancellationToken token) { var result = await this.timeSeriesDataRepository.InsertRange(dtos, token); return Ok(result); } + + } diff --git a/Persistence.API/Program.cs b/Persistence.API/Program.cs index 93e62a1..bc54d92 100644 --- a/Persistence.API/Program.cs +++ b/Persistence.API/Program.cs @@ -1,10 +1,13 @@ +using Persistence.Models; + namespace Persistence.API; public class Program { public static void Main(string[] args) { + var host = CreateHostBuilder(args).Build(); Startup.BeforeRunHandler(host); host.Run(); diff --git a/Persistence.API/Startup.cs b/Persistence.API/Startup.cs index 32466c8..e074845 100644 --- a/Persistence.API/Startup.cs +++ b/Persistence.API/Startup.cs @@ -33,6 +33,11 @@ public class Startup app.UseRouting(); + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + app.UseAuthentication(); app.UseAuthorization(); diff --git a/Persistence.Client/Clients/ITimeSeriesClient.cs b/Persistence.Client/Clients/ITimeSeriesClient.cs index 8456fa2..8f7ef0e 100644 --- a/Persistence.Client/Clients/ITimeSeriesClient.cs +++ b/Persistence.Client/Clients/ITimeSeriesClient.cs @@ -1,13 +1,22 @@ using Microsoft.AspNetCore.Mvc; +using Persistence.Models; using Refit; namespace Persistence.Client.Clients; public interface ITimeSeriesClient where TDto : class, new() { - [Post("/api/dataSaub")] - Task> InsertRangeAsync(IEnumerable dtos); + private const string BaseRoute = "/api/dataSaub"; - [Get("/api/dataSaub")] - Task>> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd); + [Post($"{BaseRoute}")] + Task> InsertRange(IEnumerable dtos); + + [Get($"{BaseRoute}")] + Task>> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd); + + [Get($"{BaseRoute}/resampled")] + Task>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024); + + [Get($"{BaseRoute}/datesRange")] + Task> GetDatesRange(); } diff --git a/Persistence.Database.Postgres/Migrations/20241118091712_InitialCreate.Designer.cs b/Persistence.Database.Postgres/Migrations/20241122074646_InitialCreate.Designer.cs similarity index 92% rename from Persistence.Database.Postgres/Migrations/20241118091712_InitialCreate.Designer.cs rename to Persistence.Database.Postgres/Migrations/20241122074646_InitialCreate.Designer.cs index b340413..17ec6e1 100644 --- a/Persistence.Database.Postgres/Migrations/20241118091712_InitialCreate.Designer.cs +++ b/Persistence.Database.Postgres/Migrations/20241122074646_InitialCreate.Designer.cs @@ -12,7 +12,7 @@ using Persistence.Database.Model; namespace Persistence.Database.Postgres.Migrations { [DbContext(typeof(PersistenceDbContext))] - [Migration("20241118091712_InitialCreate")] + [Migration("20241122074646_InitialCreate")] partial class InitialCreate { /// @@ -29,12 +29,9 @@ namespace Persistence.Database.Postgres.Migrations modelBuilder.Entity("Persistence.Database.Model.DataSaub", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); b.Property("AxialLoad") .HasColumnType("double precision") @@ -52,10 +49,6 @@ namespace Persistence.Database.Postgres.Migrations .HasColumnType("double precision") .HasColumnName("blockSpeed"); - b.Property("Date") - .HasColumnType("timestamp with time zone") - .HasColumnName("date"); - b.Property("Flow") .HasColumnType("double precision") .HasColumnName("flow"); @@ -112,7 +105,7 @@ namespace Persistence.Database.Postgres.Migrations .HasColumnType("double precision") .HasColumnName("wellDepth"); - b.HasKey("Id"); + b.HasKey("Date"); b.ToTable("DataSaub"); }); diff --git a/Persistence.Database.Postgres/Migrations/20241118091712_InitialCreate.cs b/Persistence.Database.Postgres/Migrations/20241122074646_InitialCreate.cs similarity index 89% rename from Persistence.Database.Postgres/Migrations/20241118091712_InitialCreate.cs rename to Persistence.Database.Postgres/Migrations/20241122074646_InitialCreate.cs index 61ea137..dfa9396 100644 --- a/Persistence.Database.Postgres/Migrations/20241118091712_InitialCreate.cs +++ b/Persistence.Database.Postgres/Migrations/20241122074646_InitialCreate.cs @@ -1,6 +1,5 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; #nullable disable @@ -19,8 +18,6 @@ namespace Persistence.Database.Postgres.Migrations name: "DataSaub", columns: table => new { - id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), date = table.Column(type: "timestamp with time zone", nullable: false), mode = table.Column(type: "integer", nullable: true), user = table.Column(type: "text", nullable: true), @@ -43,7 +40,7 @@ namespace Persistence.Database.Postgres.Migrations }, constraints: table => { - table.PrimaryKey("PK_DataSaub", x => x.id); + table.PrimaryKey("PK_DataSaub", x => x.date); }); } diff --git a/Persistence.Database.Postgres/Migrations/PersistenceDbContextModelSnapshot.cs b/Persistence.Database.Postgres/Migrations/PersistenceDbContextModelSnapshot.cs index 59686f7..f41f669 100644 --- a/Persistence.Database.Postgres/Migrations/PersistenceDbContextModelSnapshot.cs +++ b/Persistence.Database.Postgres/Migrations/PersistenceDbContextModelSnapshot.cs @@ -26,12 +26,9 @@ namespace Persistence.Database.Postgres.Migrations modelBuilder.Entity("Persistence.Database.Model.DataSaub", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); b.Property("AxialLoad") .HasColumnType("double precision") @@ -49,10 +46,6 @@ namespace Persistence.Database.Postgres.Migrations .HasColumnType("double precision") .HasColumnName("blockSpeed"); - b.Property("Date") - .HasColumnType("timestamp with time zone") - .HasColumnName("date"); - b.Property("Flow") .HasColumnType("double precision") .HasColumnName("flow"); @@ -109,7 +102,7 @@ namespace Persistence.Database.Postgres.Migrations .HasColumnType("double precision") .HasColumnName("wellDepth"); - b.HasKey("Id"); + b.HasKey("Date"); b.ToTable("DataSaub"); }); diff --git a/Persistence.Database/Entity/DataSaub.cs b/Persistence.Database/Entity/DataSaub.cs index 39b56cb..fecda5a 100644 --- a/Persistence.Database/Entity/DataSaub.cs +++ b/Persistence.Database/Entity/DataSaub.cs @@ -1,12 +1,11 @@ -using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; namespace Persistence.Database.Model; public class DataSaub : ITimestampedData { - [Column("id")] - public int Id { get; set; } - - [Column("date")] + [Key, Column("date")] public DateTimeOffset Date { get; set; } [Column("mode")] diff --git a/Persistence.IntegrationTests/Controllers/DataSaubControllerTest.cs b/Persistence.IntegrationTests/Controllers/DataSaubControllerTest.cs index 38d7ccd..9febbb5 100644 --- a/Persistence.IntegrationTests/Controllers/DataSaubControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/DataSaubControllerTest.cs @@ -15,7 +15,6 @@ public class DataSaubControllerTest : TimeSeriesBaseControllerTest : BaseIntegrationTest - where TEntity : class + where TEntity : class, ITimestampedData, new() where TDto : class, new() { private ITimeSeriesClient timeSeriesClient; @@ -29,7 +30,7 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat var expected = dto.Adapt(); //act - var response = await timeSeriesClient.InsertRangeAsync(new TDto[] { expected }); + var response = await timeSeriesClient.InsertRange(new TDto[] { expected }); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -45,11 +46,80 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat dbContext.SaveChanges(); - var response = await timeSeriesClient.GetAsync(beginDate, endDate); + var response = await timeSeriesClient.Get(beginDate, endDate); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.Single(response.Content); } + + public async Task GetDatesRangeSuccess(TEntity entity) + { + //arrange + var datesRangeExpected = 30; + + var entity2 = entity.Adapt(); + entity2.Date = entity.Date.AddDays(datesRangeExpected); + + var dbset = dbContext.Set(); + dbset.Add(entity); + dbset.Add(entity2); + + dbContext.SaveChanges(); + + var response = await timeSeriesClient.GetDatesRange(); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + + var datesRangeActual = (response.Content.To - response.Content.From).Days; + Assert.Equal(datesRangeExpected, datesRangeActual); + } + + public async Task GetResampledDataSuccess(TEntity entity) + { + //arrange + var approxPointsCount = 10; + var differenceBetweenStartAndEndDays = 50; + + var entities = new List(); + for (var i = 1; i <= differenceBetweenStartAndEndDays; i++) + { + var entity2 = entity.Adapt(); + entity2.Date = entity.Date.AddDays(i - 1); + + entities.Add(entity2); + } + + var dbset = dbContext.Set(); + dbset.AddRange(entities); + + dbContext.SaveChanges(); + + var response = await timeSeriesClient.GetResampledData(entity.Date.AddMinutes(-1), differenceBetweenStartAndEndDays * 24 * 60 * 60 + 60, approxPointsCount); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + + var ratio = entities.Count() / approxPointsCount; + if (ratio > 1) + { + var expectedResampledCount = entities + .Where((_, index) => index % ratio == 0) + .Count(); + + Assert.Equal(expectedResampledCount, response.Content.Count()); + } + else + { + Assert.Equal(entities.Count(), response.Content.Count()); + } + + + } + + } diff --git a/Persistence.Repository/Data/DataSaubDto.cs b/Persistence.Repository/Data/DataSaubDto.cs index bb9f74f..518380b 100644 --- a/Persistence.Repository/Data/DataSaubDto.cs +++ b/Persistence.Repository/Data/DataSaubDto.cs @@ -4,8 +4,6 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Persistence.Repository.Data; public class DataSaubDto : ITimeSeriesAbstractDto { - public int Id { get; set; } - public DateTimeOffset Date { get; set; } = DateTimeOffset.UtcNow; public int? Mode { get; set; } diff --git a/Persistence.Repository/Repositories/SetpointRepository.cs b/Persistence.Repository/Repositories/SetpointRepository.cs index 2c08e71..7f81c29 100644 --- a/Persistence.Repository/Repositories/SetpointRepository.cs +++ b/Persistence.Repository/Repositories/SetpointRepository.cs @@ -35,6 +35,7 @@ namespace Persistence.Repository.Repositories .ToArrayAsync(token); var filteredEntities = entities .GroupBy(e => e.Key) + .Select(e => e.OrderBy(o => o.Created)) .Select(e => e.Where(e => e.Created <= historyMoment).Last()); var dtos = filteredEntities .Select(e => e.Adapt()); diff --git a/Persistence.Repository/Repositories/TimeSeriesDataCachedRepository.cs b/Persistence.Repository/Repositories/TimeSeriesDataCachedRepository.cs index 4a553ac..20dbe00 100644 --- a/Persistence.Repository/Repositories/TimeSeriesDataCachedRepository.cs +++ b/Persistence.Repository/Repositories/TimeSeriesDataCachedRepository.cs @@ -10,8 +10,8 @@ public class TimeSeriesDataCachedRepository : TimeSeriesDataRepos where TEntity : class, ITimestampedData, new() where TDto : class, ITimeSeriesAbstractDto, new() { - public static TDto FirstByDate { get; set; } = default!; - public static CyclicArray LastData { get; set; } = null!; + public static TDto? FirstByDate { get; private set; } + public static CyclicArray LastData { get; } = new CyclicArray(CacheItemsCount); private const int CacheItemsCount = 3600; @@ -19,8 +19,6 @@ public class TimeSeriesDataCachedRepository : TimeSeriesDataRepos { Task.Run(async () => { - LastData = new CyclicArray(CacheItemsCount); - var firstDateItem = await base.GetFirstAsync(CancellationToken.None); if (firstDateItem == null) { @@ -35,17 +33,17 @@ public class TimeSeriesDataCachedRepository : TimeSeriesDataRepos }).Wait(); } - public override async Task> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) + public override async Task> GetGtDate(DateTimeOffset dateBegin, CancellationToken token) { if (LastData.Count() == 0 || LastData[0].Date > dateBegin) { - var dtos = await base.GetAsync(dateBegin, dateEnd, token); + var dtos = await base.GetGtDate(dateBegin, token); return dtos; } var items = LastData - .Where(i => i.Date >= dateBegin && i.Date <= dateEnd); + .Where(i => i.Date >= dateBegin); return items; } @@ -64,5 +62,44 @@ public class TimeSeriesDataCachedRepository : TimeSeriesDataRepos return result; } + + public override async Task GetDatesRange(CancellationToken token) + { + if (FirstByDate == null) + return null; + + return await Task.Run(() => + { + return new DatesRangeDto + { + From = FirstByDate.Date, + To = LastData[^1].Date + }; + }); + } + + public override async Task> GetResampledData( + DateTimeOffset dateBegin, + double intervalSec = 600d, + int approxPointsCount = 1024, + CancellationToken token = default) + { + var dtos = LastData.Where(i => i.Date >= dateBegin); + if (LastData.Count == 0 || LastData[0].Date > dateBegin) + { + dtos = await base.GetGtDate(dateBegin, token); + } + + var dateEnd = dateBegin.AddSeconds(intervalSec); + dtos = dtos + .Where(i => i.Date <= dateEnd); + + var ratio = dtos.Count() / approxPointsCount; + if (ratio > 1) + dtos = dtos + .Where((_, index) => index % ratio == 0); + + return dtos; + } } diff --git a/Persistence.Repository/Repositories/TimeSeriesDataRepository.cs b/Persistence.Repository/Repositories/TimeSeriesDataRepository.cs index 9b339a5..d73caf7 100644 --- a/Persistence.Repository/Repositories/TimeSeriesDataRepository.cs +++ b/Persistence.Repository/Repositories/TimeSeriesDataRepository.cs @@ -18,16 +18,7 @@ public class TimeSeriesDataRepository : ITimeSeriesDataRepository protected virtual IQueryable GetQueryReadOnly() => this.db.Set(); - public virtual async Task> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) - { - var query = GetQueryReadOnly(); - var entities = await query.ToArrayAsync(token); - var dtos = entities.Select(e => e.Adapt()); - - return dtos; - } - - public virtual async Task GetDatesRangeAsync(CancellationToken token) + public virtual async Task GetDatesRange(CancellationToken token) { var query = GetQueryReadOnly(); var minDate = await query.MinAsync(o => o.Date, token); @@ -60,7 +51,7 @@ public class TimeSeriesDataRepository : ITimeSeriesDataRepository return result; } - public async Task> GetLastAsync(int takeCount, CancellationToken token) + protected async Task> GetLastAsync(int takeCount, CancellationToken token) { var query = GetQueryReadOnly() .OrderByDescending(e => e.Date) @@ -72,17 +63,37 @@ public class TimeSeriesDataRepository : ITimeSeriesDataRepository return dtos; } - public async Task GetFirstAsync(CancellationToken token) + protected async Task GetFirstAsync(CancellationToken token) { var query = GetQueryReadOnly() .OrderBy(e => e.Date); var entity = await query.FirstOrDefaultAsync(token); - if(entity == null) + if (entity == null) return null; var dto = entity.Adapt(); return dto; } + + public async virtual Task> GetResampledData( + DateTimeOffset dateBegin, + double intervalSec = 600d, + int approxPointsCount = 1024, + CancellationToken token = default) + { + var dtos = await GetGtDate(dateBegin, token); + + var dateEnd = dateBegin.AddSeconds(intervalSec); + dtos = dtos + .Where(i => i.Date <= dateEnd); + + var ratio = dtos.Count() / approxPointsCount; + if (ratio > 1) + dtos = dtos + .Where((_, index) => index % ratio == 0); + + return dtos; + } } diff --git a/Persistence/API/IChangeLogApi.cs b/Persistence/API/IChangeLogApi.cs index 716944e..bb4a3c3 100644 --- a/Persistence/API/IChangeLogApi.cs +++ b/Persistence/API/IChangeLogApi.cs @@ -31,7 +31,7 @@ public interface IChangeLogApi /// /// /// - Task> AddAsync(TDto dto, CancellationToken token); + Task> Add(TDto dto, CancellationToken token); /// /// Добавить несколько записей @@ -39,7 +39,7 @@ public interface IChangeLogApi /// /// /// - Task> AddRangeAsync(IEnumerable dtos, CancellationToken token); + Task> AddRange(IEnumerable dtos, CancellationToken token); /// /// Обновить одну запись @@ -47,7 +47,7 @@ public interface IChangeLogApi /// /// /// - Task> UpdateAsync(TDto dto, CancellationToken token); + Task> Update(TDto dto, CancellationToken token); /// /// Обновить несколько записей @@ -55,7 +55,7 @@ public interface IChangeLogApi /// /// /// - Task> UpdateRangeAsync(IEnumerable dtos, CancellationToken token); + Task> UpdateRange(IEnumerable dtos, CancellationToken token); /// /// Удалить одну запись @@ -63,7 +63,7 @@ public interface IChangeLogApi /// /// /// - Task> DeleteAsync(int id, CancellationToken token); + Task> Delete(int id, CancellationToken token); /// /// Удалить несколько записей @@ -71,5 +71,5 @@ public interface IChangeLogApi /// /// /// - Task> DeleteRangeAsync(IEnumerable ids, CancellationToken token); + Task> DeleteRange(IEnumerable ids, CancellationToken token); } diff --git a/Persistence/API/IDictionaryElementApi.cs b/Persistence/API/IDictionaryElementApi.cs index 540d454..fac7870 100644 --- a/Persistence/API/IDictionaryElementApi.cs +++ b/Persistence/API/IDictionaryElementApi.cs @@ -13,7 +13,7 @@ public interface IDictionaryElementApi where TDto : class, new() /// ключ справочника /// /// - Task>> GetAsync(Guid dictionaryKey, CancellationToken token); + Task>> Get(Guid dictionaryKey, CancellationToken token); /// /// Добавить элемент в справочник @@ -22,7 +22,7 @@ public interface IDictionaryElementApi where TDto : class, new() /// /// /// - Task> AddAsync(Guid dictionaryKey, TDto dto, CancellationToken token); + Task> Add(Guid dictionaryKey, TDto dto, CancellationToken token); /// /// Изменить одну запись @@ -32,7 +32,7 @@ public interface IDictionaryElementApi where TDto : class, new() /// /// /// - Task> UpdateAsync(Guid dictionaryKey, Guid dictionaryElementKey, TDto dto, CancellationToken token); + Task> Update(Guid dictionaryKey, Guid dictionaryElementKey, TDto dto, CancellationToken token); /// /// Удалить одну запись @@ -41,5 +41,5 @@ public interface IDictionaryElementApi where TDto : class, new() /// ключ элемента в справочнике /// /// - Task> DeleteAsync(Guid dictionaryKey, Guid dictionaryElementKey, CancellationToken token); + Task> Delete(Guid dictionaryKey, Guid dictionaryElementKey, CancellationToken token); } diff --git a/Persistence/API/ISyncApi.cs b/Persistence/API/ISyncApi.cs index 9df4301..7f72812 100644 --- a/Persistence/API/ISyncApi.cs +++ b/Persistence/API/ISyncApi.cs @@ -15,7 +15,7 @@ public interface ISyncApi where TDto : class, new() /// количество записей /// /// - Task>> GetPartAsync(DateTimeOffset dateBegin, int take = 24 * 60 * 60, CancellationToken token = default); + Task>> GetPart(DateTimeOffset dateBegin, int take = 24 * 60 * 60, CancellationToken token = default); /// /// Получить диапазон дат, для которых есть данные в репозитории diff --git a/Persistence/API/ITableDataApi.cs b/Persistence/API/ITableDataApi.cs index ae7099c..a310799 100644 --- a/Persistence/API/ITableDataApi.cs +++ b/Persistence/API/ITableDataApi.cs @@ -19,5 +19,5 @@ public interface ITableDataApi /// параметры фильтрации /// /// - Task>> GetPageAsync(TRequest request, CancellationToken token); + Task>> GetPage(TRequest request, CancellationToken token); } diff --git a/Persistence/API/IGraphDataApi.cs b/Persistence/API/ITimeSeriesBaseDataApi.cs similarity index 57% rename from Persistence/API/IGraphDataApi.cs rename to Persistence/API/ITimeSeriesBaseDataApi.cs index b609f2f..480f145 100644 --- a/Persistence/API/IGraphDataApi.cs +++ b/Persistence/API/ITimeSeriesBaseDataApi.cs @@ -4,23 +4,27 @@ using Persistence.Models; namespace Persistence.API; /// -/// Интерфейс для работы с API графиков +/// Базовый интерфейс для работы с временными рядами /// -public interface IGraphDataApi +public interface ITimeSeriesBaseDataApi { /// - /// Получить список объектов с прореживанием, удовлетворящий диапазону дат + /// Получить список объектов с прореживанием, удовлетворяющий диапазону дат /// /// дата начала /// дата окончания /// /// - Task>> GetThinnedDataAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, int approxPointsCount = 1024); + Task GetResampledData( + DateTimeOffset dateBegin, + double intervalSec = 600d, + int approxPointsCount = 1024, + CancellationToken token = default); /// /// Получить диапазон дат, для которых есть данные в репозитории /// /// /// - Task> GetDatesRangeAsync(CancellationToken token); + Task GetDatesRange(CancellationToken token); } diff --git a/Persistence/API/ITimeSeriesDataApi.cs b/Persistence/API/ITimeSeriesDataApi.cs index a6a0363..a2406aa 100644 --- a/Persistence/API/ITimeSeriesDataApi.cs +++ b/Persistence/API/ITimeSeriesDataApi.cs @@ -11,24 +11,16 @@ namespace Persistence.API; /// /// Интерфейс для работы с API временных данных /// -public interface ITimeSeriesDataApi +public interface ITimeSeriesDataApi : ITimeSeriesBaseDataApi where TDto : class, ITimeSeriesAbstractDto, new() { /// /// Получить список объектов, удовлетворяющий диапазон дат /// /// дата начала - /// дата окончания /// /// - Task GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); - - /// - /// Получить диапазон дат, для которых есть данные в репозитории - /// - /// - /// - Task GetDatesRangeAsync(CancellationToken token); + Task Get(DateTimeOffset dateBegin, CancellationToken token); /// /// Добавление записей @@ -36,7 +28,7 @@ public interface ITimeSeriesDataApi /// /// /// - Task InsertRangeAsync(IEnumerable dtos, CancellationToken token); + Task InsertRange(IEnumerable dtos, CancellationToken token); } diff --git a/Persistence/Models/ChangeLogDto.cs b/Persistence/Models/ChangeLogDto.cs index 5d5e7f5..6b2a090 100644 --- a/Persistence/Models/ChangeLogDto.cs +++ b/Persistence/Models/ChangeLogDto.cs @@ -26,7 +26,7 @@ public class ChangeLogDto where T: class public DateTimeOffset Creation { get; set; } /// - /// Дата устаревания (например при удалении) + /// Дата устаревания (например, при удалении) /// public DateTimeOffset? Obsolete { get; set; } diff --git a/Persistence/Repositories/ITableDataRepository.cs b/Persistence/Repositories/ITableDataRepository.cs index 22ec55c..73d332d 100644 --- a/Persistence/Repositories/ITableDataRepository.cs +++ b/Persistence/Repositories/ITableDataRepository.cs @@ -15,5 +15,5 @@ public interface ITableDataRepository /// параметры фильтрации /// /// - Task> GetAsync(TRequest request, CancellationToken token); + Task> Get(TRequest request, CancellationToken token); } diff --git a/Persistence/Repositories/IGraphDataRepository.cs b/Persistence/Repositories/ITimeSeriesBaseRepository.cs similarity index 69% rename from Persistence/Repositories/IGraphDataRepository.cs rename to Persistence/Repositories/ITimeSeriesBaseRepository.cs index d110ffa..7102d97 100644 --- a/Persistence/Repositories/IGraphDataRepository.cs +++ b/Persistence/Repositories/ITimeSeriesBaseRepository.cs @@ -5,22 +5,25 @@ namespace Persistence.Repositories; /// /// Интерфейс по работе с прореженными данными /// -public interface IGraphDataRepository +public interface ITimeSeriesBaseRepository where TDto : class, new() { /// /// Получить список объектов с прореживанием /// /// дата начала - /// дата окончания /// /// - Task> GetThinnedDataAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, int approxPointsCount = 1024); + Task> GetResampledData( + DateTimeOffset dateBegin, + double intervalSec = 600d, + int approxPointsCount = 1024, + CancellationToken token = default); /// /// Получить диапазон дат, для которых есть данные в репозитории /// /// /// - Task GetDatesRangeAsync(CancellationToken token); + Task GetDatesRange(CancellationToken token); } diff --git a/Persistence/Repositories/ITimeSeriesDataRepository.cs b/Persistence/Repositories/ITimeSeriesDataRepository.cs index f3e49eb..9de7fc7 100644 --- a/Persistence/Repositories/ITimeSeriesDataRepository.cs +++ b/Persistence/Repositories/ITimeSeriesDataRepository.cs @@ -6,24 +6,9 @@ namespace Persistence.Repositories; /// Интерфейс по работе с временными данными /// /// -public interface ITimeSeriesDataRepository : ISyncRepository +public interface ITimeSeriesDataRepository : ISyncRepository, ITimeSeriesBaseRepository where TDto : class, ITimeSeriesAbstractDto, new() { - /// - /// Получить страницу списка объектов - /// - /// дата начала - /// дата окончания - /// - /// - Task> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); - - /// - /// Получить диапазон дат, для которых есть данные в репозитории - /// - /// - /// - Task GetDatesRangeAsync(CancellationToken token); /// /// Добавление записей /// @@ -31,19 +16,4 @@ public interface ITimeSeriesDataRepository : ISyncRepository /// /// Task InsertRange(IEnumerable dtos, CancellationToken token); - - /// - /// Получение списка последних записей - /// - /// количество записей - /// - /// - Task> GetLastAsync(int takeCount, CancellationToken token); - - /// - /// Получение первой записи - /// - /// - /// - Task GetFirstAsync(CancellationToken token); }