diff --git a/DD.Persistence.API/Controllers/TimestampedValuesController.cs b/DD.Persistence.API/Controllers/TimestampedValuesController.cs
index fe97476..3d4bdf0 100644
--- a/DD.Persistence.API/Controllers/TimestampedValuesController.cs
+++ b/DD.Persistence.API/Controllers/TimestampedValuesController.cs
@@ -1,4 +1,5 @@
-using DD.Persistence.Models;
+using DD.Persistence.Filter.Models.Abstractions;
+using DD.Persistence.Models;
using DD.Persistence.Models.Common;
using DD.Persistence.Repositories;
using DD.Persistence.Services.Interfaces;
@@ -45,6 +46,7 @@ public class TimestampedValuesController : ControllerBase
///
/// Набор дискриминаторов
/// Фильтр позднее даты
+ /// Кастомный фильтр по набору значений
/// Фильтр свойств набора
///
///
@@ -52,9 +54,14 @@ public class TimestampedValuesController : ControllerBase
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NoContent)]
- public async Task>> Get([FromQuery] IEnumerable discriminatorIds, DateTimeOffset? timestampBegin, [FromQuery] string[]? columnNames, int skip, int take, CancellationToken token)
+ public async Task>> Get([FromQuery] IEnumerable discriminatorIds,
+ DateTimeOffset? timestampBegin,
+ [FromQuery] TNode? filterTree,
+ [FromQuery] string[]? columnNames,
+ int skip, int take,
+ CancellationToken token)
{
- var result = await timestampedValuesService.Get(discriminatorIds, timestampBegin, columnNames, skip, take, token);
+ var result = await timestampedValuesService.Get(discriminatorIds, timestampBegin, filterTree, columnNames, skip, take, token);
return result.Any() ? Ok(result) : NoContent();
}
diff --git a/DD.Persistence.API/DependencyInjection.cs b/DD.Persistence.API/DependencyInjection.cs
index b543841..30d9f89 100644
--- a/DD.Persistence.API/DependencyInjection.cs
+++ b/DD.Persistence.API/DependencyInjection.cs
@@ -1,16 +1,14 @@
-using Mapster;
+using DD.Persistence.Filter.Models.Abstractions;
+using DD.Persistence.Models.Configurations;
+using DD.Persistence.Services;
+using DD.Persistence.Services.Interfaces;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
-using DD.Persistence.Models;
-using DD.Persistence.Models.Configurations;
-using DD.Persistence.Services;
-using DD.Persistence.Services.Interfaces;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;
using System.Text.Json.Nodes;
-using DD.Persistence.Database.Entity;
namespace DD.Persistence.API;
@@ -30,6 +28,7 @@ public static class DependencyInjection
new OpenApiSchema {Type = "number", Format = "float" }
]
});
+ c.MapType(() => new OpenApiSchema { Type = "string" });
c.CustomOperationIds(e =>
{
diff --git a/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs b/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
index 27449b2..316aab3 100644
--- a/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
@@ -24,12 +24,14 @@ public interface ITimestampedValuesClient : IDisposable
///
/// Набор дискриминаторов (идентификаторов)
/// Фильтр позднее даты
+ /// Кастомный фильтр по набору значений
/// Фильтр свойств набора
///
///
///
Task> Get(IEnumerable discriminatorIds,
DateTimeOffset? timestampBegin,
+ string? filterTree,
IEnumerable? columnNames,
int skip,
int take,
@@ -40,11 +42,12 @@ public interface ITimestampedValuesClient : IDisposable
///
///
///
+ ///
/// Фильтр свойств набора
///
///
///
- Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token);
+ Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token);
///
/// Получить данные, начиная с заданной отметки времени
diff --git a/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs b/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs
index 7c56f12..0858b08 100644
--- a/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs
@@ -23,6 +23,7 @@ public interface IRefitTimestampedValuesClient : IRefitClient, IDisposable
[Get($"{baseUrl}")]
Task>> Get([Query(CollectionFormat.Multi)] IEnumerable discriminatorIds,
DateTimeOffset? timestampBegin,
+ [Query] string? filterTree,
[Query(CollectionFormat.Multi)] IEnumerable? columnNames,
int skip,
int take,
diff --git a/DD.Persistence.Client/Clients/TimestampedValuesClient.cs b/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
index 123ed71..e4ad2a0 100644
--- a/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
@@ -32,17 +32,17 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
}
///
- public async Task> Get(IEnumerable discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token)
+ public async Task> Get(IEnumerable discriminatorIds, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token)
{
var result = await ExecuteGetResponse(
- async () => await refitTimestampedSetClient.Get(discriminatorIds, geTimestamp, columnNames, skip, take, token), token);
+ async () => await refitTimestampedSetClient.Get(discriminatorIds, geTimestamp, filterTree, columnNames, skip, take, token), token);
return result!;
}
///
- public async Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token)
+ public async Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token)
{
- var data = await Get([discriminatorId], geTimestamp, columnNames, skip, take, token);
+ var data = await Get([discriminatorId], geTimestamp, filterTree, columnNames, skip, take, token);
var mapper = GetMapper(discriminatorId);
return data.Select(mapper.DeserializeTimeStampedData);
diff --git a/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.Designer.cs b/DD.Persistence.Database.Postgres/Migrations/20250210055116_Init.Designer.cs
similarity index 98%
rename from DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.Designer.cs
rename to DD.Persistence.Database.Postgres/Migrations/20250210055116_Init.Designer.cs
index b90d452..5cd7da2 100644
--- a/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.Designer.cs
+++ b/DD.Persistence.Database.Postgres/Migrations/20250210055116_Init.Designer.cs
@@ -13,7 +13,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace DD.Persistence.Database.Postgres.Migrations
{
[DbContext(typeof(PersistencePostgresContext))]
- [Migration("20250205114037_Init")]
+ [Migration("20250210055116_Init")]
partial class Init
{
///
@@ -37,14 +37,14 @@ namespace DD.Persistence.Database.Postgres.Migrations
.HasColumnType("timestamp with time zone")
.HasComment("Дата создания записи");
+ b.Property("DiscriminatorId")
+ .HasColumnType("uuid")
+ .HasComment("Дискриминатор таблицы");
+
b.Property("IdAuthor")
.HasColumnType("uuid")
.HasComment("Автор изменения");
- b.Property("IdDiscriminator")
- .HasColumnType("uuid")
- .HasComment("Дискриминатор таблицы");
-
b.Property("IdEditor")
.HasColumnType("uuid")
.HasComment("Редактор");
diff --git a/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.cs b/DD.Persistence.Database.Postgres/Migrations/20250210055116_Init.cs
similarity index 99%
rename from DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.cs
rename to DD.Persistence.Database.Postgres/Migrations/20250210055116_Init.cs
index c872547..a1dd229 100644
--- a/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.cs
+++ b/DD.Persistence.Database.Postgres/Migrations/20250210055116_Init.cs
@@ -17,7 +17,7 @@ namespace DD.Persistence.Database.Postgres.Migrations
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false, comment: "Ключ записи"),
- IdDiscriminator = table.Column(type: "uuid", nullable: false, comment: "Дискриминатор таблицы"),
+ DiscriminatorId = table.Column(type: "uuid", nullable: false, comment: "Дискриминатор таблицы"),
IdAuthor = table.Column(type: "uuid", nullable: false, comment: "Автор изменения"),
IdEditor = table.Column(type: "uuid", nullable: true, comment: "Редактор"),
Creation = table.Column(type: "timestamp with time zone", nullable: false, comment: "Дата создания записи"),
diff --git a/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs b/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs
index e2b0921..59361b8 100644
--- a/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs
+++ b/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs
@@ -34,14 +34,14 @@ namespace DD.Persistence.Database.Postgres.Migrations
.HasColumnType("timestamp with time zone")
.HasComment("Дата создания записи");
+ b.Property("DiscriminatorId")
+ .HasColumnType("uuid")
+ .HasComment("Дискриминатор таблицы");
+
b.Property("IdAuthor")
.HasColumnType("uuid")
.HasComment("Автор изменения");
- b.Property("IdDiscriminator")
- .HasColumnType("uuid")
- .HasComment("Дискриминатор таблицы");
-
b.Property("IdEditor")
.HasColumnType("uuid")
.HasComment("Редактор");
diff --git a/DD.Persistence.Database/DependencyInjection.cs b/DD.Persistence.Database/DependencyInjection.cs
index a9291e2..91b6956 100644
--- a/DD.Persistence.Database/DependencyInjection.cs
+++ b/DD.Persistence.Database/DependencyInjection.cs
@@ -42,6 +42,8 @@ public static class DependencyInjection
MapsterSetup();
+ //services.AddTransient(typeof(PersistenceRepository));
+
services.AddTransient();
services.AddTransient();
services.AddTransient();
diff --git a/DD.Persistence.Database/Entity/ChangeLog.cs b/DD.Persistence.Database/Entity/ChangeLog.cs
index db1537a..a0047cb 100644
--- a/DD.Persistence.Database/Entity/ChangeLog.cs
+++ b/DD.Persistence.Database/Entity/ChangeLog.cs
@@ -11,13 +11,13 @@ namespace DD.Persistence.Database.Entity;
/// Часть записи, описывающая изменение
///
[Table("change_log")]
-public class ChangeLog : IChangeLog
+public class ChangeLog : IDiscriminatorItem, IChangeLog
{
[Key, Comment("Ключ записи")]
public Guid Id { get; set; }
[Comment("Дискриминатор таблицы")]
- public Guid IdDiscriminator { get; set; }
+ public Guid DiscriminatorId { get; set; }
[Comment("Автор изменения")]
public Guid IdAuthor { get; set; }
diff --git a/DD.Persistence.Database/Entity/ParameterData.cs b/DD.Persistence.Database/Entity/ParameterData.cs
index 1b2fb37..638a5ba 100644
--- a/DD.Persistence.Database/Entity/ParameterData.cs
+++ b/DD.Persistence.Database/Entity/ParameterData.cs
@@ -7,7 +7,7 @@ namespace DD.Persistence.Database.Entity;
[Table("parameter_data")]
[PrimaryKey(nameof(DiscriminatorId), nameof(ParameterId), nameof(Timestamp))]
-public class ParameterData : ITimestampedItem
+public class ParameterData : IDiscriminatorItem, ITimestampedItem
{
[Required, Comment("Дискриминатор системы")]
public Guid DiscriminatorId { get; set; }
diff --git a/DD.Persistence.Database/Entity/SchemeProperty.cs b/DD.Persistence.Database/Entity/SchemeProperty.cs
index 6ef5bdb..c7f64d5 100644
--- a/DD.Persistence.Database/Entity/SchemeProperty.cs
+++ b/DD.Persistence.Database/Entity/SchemeProperty.cs
@@ -1,4 +1,5 @@
-using Microsoft.EntityFrameworkCore;
+using DD.Persistence.Database.EntityAbstractions;
+using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
@@ -7,7 +8,7 @@ namespace DD.Persistence.Database.Entity;
[Table("scheme_property")]
[PrimaryKey(nameof(DiscriminatorId), nameof(Index))]
-public class SchemeProperty
+public class SchemeProperty : IDiscriminatorItem
{
[Comment("Идентификатор схемы данных")]
public Guid DiscriminatorId { get; set; }
diff --git a/DD.Persistence.Database/Entity/TechMessage.cs b/DD.Persistence.Database/Entity/TechMessage.cs
index 093784f..8e8e84c 100644
--- a/DD.Persistence.Database/Entity/TechMessage.cs
+++ b/DD.Persistence.Database/Entity/TechMessage.cs
@@ -17,15 +17,15 @@ public class TechMessage : ITimestampedItem
[Comment("Дата возникновения")]
public DateTimeOffset Timestamp { get; set; }
- [Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
- public required string Text { get; set; }
+ [Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
+ public required string Text { get; set; }
- [Required, Comment("Id системы, к которой относится сообщение")]
- public required Guid SystemId { get; set; }
+ [Required, Comment("Id системы, к которой относится сообщение")]
+ public required Guid SystemId { get; set; }
- [Required, ForeignKey(nameof(SystemId)), Comment("Система, к которой относится сообщение")]
- public virtual required DataSourceSystem System { get; set; }
+ [Required, ForeignKey(nameof(SystemId)), Comment("Система, к которой относится сообщение")]
+ public virtual required DataSourceSystem System { get; set; }
- [Comment("Статус события")]
- public int EventState { get; set; }
- }
+ [Comment("Статус события")]
+ public int EventState { get; set; }
+}
diff --git a/DD.Persistence.Database/Entity/TimestampedValues.cs b/DD.Persistence.Database/Entity/TimestampedValues.cs
index 93acad9..0a57ec1 100644
--- a/DD.Persistence.Database/Entity/TimestampedValues.cs
+++ b/DD.Persistence.Database/Entity/TimestampedValues.cs
@@ -7,7 +7,7 @@ namespace DD.Persistence.Database.Entity;
[Table("timestamped_values")]
[PrimaryKey(nameof(DiscriminatorId), nameof(Timestamp))]
-public class TimestampedValues : ITimestampedItem, IValuesItem
+public class TimestampedValues : IDiscriminatorItem, ITimestampedItem, IValuesItem
{
[Comment("Временная отметка"), Key]
public DateTimeOffset Timestamp { get; set; }
diff --git a/DD.Persistence.Database/EntityAbstractions/IChangeLog.cs b/DD.Persistence.Database/EntityAbstractions/IChangeLog.cs
index 4d082a7..fb8219c 100644
--- a/DD.Persistence.Database/EntityAbstractions/IChangeLog.cs
+++ b/DD.Persistence.Database/EntityAbstractions/IChangeLog.cs
@@ -38,7 +38,7 @@ public interface IChangeLog
///
/// Дискриминатор таблицы
///
- public Guid IdDiscriminator { get; set; }
+ public Guid DiscriminatorId { get; set; }
///
/// Значение
diff --git a/DD.Persistence.Database/EntityAbstractions/IDiscriminatorItem.cs b/DD.Persistence.Database/EntityAbstractions/IDiscriminatorItem.cs
new file mode 100644
index 0000000..0f5af9b
--- /dev/null
+++ b/DD.Persistence.Database/EntityAbstractions/IDiscriminatorItem.cs
@@ -0,0 +1,8 @@
+namespace DD.Persistence.Database.EntityAbstractions;
+public interface IDiscriminatorItem
+{
+ ///
+ /// Дискриминатор
+ ///
+ Guid DiscriminatorId { get; set; }
+}
diff --git a/DD.Persistence.Database/Helpers/FilterBuilder.cs b/DD.Persistence.Database/Helpers/FilterBuilder.cs
index 2d90284..ea4a4a6 100644
--- a/DD.Persistence.Database/Helpers/FilterBuilder.cs
+++ b/DD.Persistence.Database/Helpers/FilterBuilder.cs
@@ -1,7 +1,8 @@
using Ardalis.Specification;
+using Ardalis.Specification.EntityFrameworkCore;
+using DD.Persistence.Database.Entity;
using DD.Persistence.Database.EntityAbstractions;
-using DD.Persistence.Database.Postgres.Extensions;
-using DD.Persistence.Database.Specifications;
+using DD.Persistence.Database.Specifications.Operation;
using DD.Persistence.Database.Specifications.ValuesItem;
using DD.Persistence.Filter.Models;
using DD.Persistence.Filter.Models.Abstractions;
@@ -13,8 +14,17 @@ using System.Text.Json;
namespace DD.Persistence.Database.Postgres.Helpers;
public static class FilterBuilder
{
- public static ISpecification? BuildFilter(this DataSchemeDto dataSchemeDto, TNode root)
- where TEntity : IValuesItem
+ public static IQueryable ApplyFilter(this IQueryable query, DataSchemeDto dataSchemeDto, TNode root)
+ where TEntity : class, IValuesItem
+ {
+ var filterSpec = dataSchemeDto.BuildFilter(root);
+ if (filterSpec != null)
+ return query.WithSpecification(filterSpec);
+ return query;
+ }
+
+ private static ISpecification? BuildFilter(this DataSchemeDto dataSchemeDto, TNode root)
+ where TEntity : IValuesItem
{
var result = dataSchemeDto.BuildSpecificationByNextNode(root);
@@ -48,10 +58,10 @@ public static class FilterBuilder
switch (vertex.Operation)
{
case OperationEnum.And:
- result = new AndSpecification(leftSpecification, rigthSpecification);
+ result = new AndSpec(leftSpecification, rigthSpecification);
break;
case OperationEnum.Or:
- result = new OrSpecification(leftSpecification, rigthSpecification);
+ result = new OrSpec(leftSpecification, rigthSpecification);
break;
}
@@ -86,21 +96,21 @@ public static class FilterBuilder
private static Dictionary>> StringSpecifications()
where TEntity : IValuesItem => new()
{
- { OperationEnum.Equal, (int index, string? value) => new ValueEqaulSpecification(index, value) },
- { OperationEnum.NotEqual, (int index, string? value) => new ValueNotEqualSpecification(index, value) },
- { OperationEnum.Greate, (int index, string? value) => new ValueGreateSpecification(index, value) },
- { OperationEnum.GreateOrEqual, (int index, string? value) => new ValueGreateOrEqualSpecification(index, value) },
- { OperationEnum.Less, (int index, string? value) => new ValueLessSpecification(index, value) },
- { OperationEnum.LessOrEqual, (int index, string? value) => new ValueLessOrEqualSpecification(index, value) }
+ { OperationEnum.Equal, (int index, string? value) => new ValueEqualSpec(index, value) },
+ { OperationEnum.NotEqual, (int index, string? value) => new ValueNotEqualSpec(index, value) },
+ { OperationEnum.Greate, (int index, string? value) => new ValueGreateSpec(index, value) },
+ { OperationEnum.GreateOrEqual, (int index, string? value) => new ValueGreateOrEqualSpec(index, value) },
+ { OperationEnum.Less, (int index, string? value) => new ValueLessSpec(index, value) },
+ { OperationEnum.LessOrEqual, (int index, string? value) => new ValueLessOrEqualSpec(index, value) }
};
private static Dictionary>> DoubleSpecifications()
where TEntity : IValuesItem => new()
{
- { OperationEnum.Equal, (int index, double? value) => new ValueEqaulSpecification(index, value) },
- { OperationEnum.NotEqual, (int index, double? value) => new ValueNotEqualSpecification(index, value) },
- { OperationEnum.Greate, (int index, double? value) => new ValueGreateSpecification(index, value) },
- { OperationEnum.GreateOrEqual, (int index, double? value) => new ValueGreateOrEqualSpecification(index, value) },
- { OperationEnum.Less, (int index, double? value) => new ValueLessSpecification(index, value) },
- { OperationEnum.LessOrEqual, (int index, double? value) => new ValueLessOrEqualSpecification(index, value) }
+ { OperationEnum.Equal, (int index, double? value) => new ValueEqualSpec(index, value) },
+ { OperationEnum.NotEqual, (int index, double? value) => new ValueNotEqualSpec(index, value) },
+ { OperationEnum.Greate, (int index, double? value) => new ValueGreateSpec(index, value) },
+ { OperationEnum.GreateOrEqual, (int index, double? value) => new ValueGreateOrEqualSpec(index, value) },
+ { OperationEnum.Less, (int index, double? value) => new ValueLessSpec(index, value) },
+ { OperationEnum.LessOrEqual, (int index, double? value) => new ValueLessOrEqualSpec(index, value) }
};
}
diff --git a/DD.Persistence.Database/Repositories/ChangeLogRepository.cs b/DD.Persistence.Database/Repositories/ChangeLogRepository.cs
index 61e907d..488f9ef 100644
--- a/DD.Persistence.Database/Repositories/ChangeLogRepository.cs
+++ b/DD.Persistence.Database/Repositories/ChangeLogRepository.cs
@@ -54,7 +54,7 @@ public class ChangeLogRepository : IChangeLogRepository
public async Task MarkAsDeleted(Guid idEditor, Guid idDiscriminator, CancellationToken token)
{
var query = db.Set()
- .Where(s => s.IdDiscriminator == idDiscriminator)
+ .Where(s => s.DiscriminatorId == idDiscriminator)
.Where(e => e.Obsolete == null);
var entities = await query.ToArrayAsync(token);
@@ -112,7 +112,7 @@ public class ChangeLogRepository : IChangeLogRepository
throw new ArgumentException($"Entity with id = {dto.Id} doesn't exist in Db", nameof(dto));
}
- var newEntity = CreateEntityFromDto(idEditor, updatedEntity.IdDiscriminator, dto);
+ var newEntity = CreateEntityFromDto(idEditor, updatedEntity.DiscriminatorId, dto);
dbSet.Add(newEntity);
updatedEntity.IdNext = newEntity.Id;
@@ -144,14 +144,14 @@ public class ChangeLogRepository : IChangeLogRepository
private IQueryable CreateQuery(Guid idDiscriminator)
{
- var query = db.Set().Where(e => e.IdDiscriminator == idDiscriminator);
+ var query = db.Set().Where(e => e.DiscriminatorId == idDiscriminator);
return query;
}
public async Task> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
{
- var query = db.Set().Where(s => s.IdDiscriminator == idDiscriminator);
+ var query = db.Set().Where(s => s.DiscriminatorId == idDiscriminator);
var min = new DateTimeOffset(dateBegin.ToUniversalTime().Date, TimeSpan.Zero);
var max = new DateTimeOffset(dateEnd.ToUniversalTime().Date, TimeSpan.Zero);
@@ -171,7 +171,7 @@ public class ChangeLogRepository : IChangeLogRepository
public async Task> GetDatesChange(Guid idDiscriminator, CancellationToken token)
{
- var query = db.Set().Where(e => e.IdDiscriminator == idDiscriminator);
+ var query = db.Set().Where(e => e.DiscriminatorId == idDiscriminator);
var datesCreateQuery = query
.Select(e => e.Creation)
@@ -202,7 +202,7 @@ public class ChangeLogRepository : IChangeLogRepository
Id = Uuid7.Guid(),
Creation = DateTimeOffset.UtcNow,
IdAuthor = idAuthor,
- IdDiscriminator = idDiscriminator,
+ DiscriminatorId = idDiscriminator,
IdEditor = idAuthor,
Value = dto.Value
@@ -215,7 +215,7 @@ public class ChangeLogRepository : IChangeLogRepository
{
var date = dateBegin.ToUniversalTime();
var query = db.Set()
- .Where(e => e.IdDiscriminator == idDiscriminator)
+ .Where(e => e.DiscriminatorId == idDiscriminator)
.Where(e => e.Creation >= date || e.Obsolete >= date);
var entities = await query.ToArrayAsync(token);
@@ -228,7 +228,7 @@ public class ChangeLogRepository : IChangeLogRepository
public async Task GetDatesRange(Guid idDiscriminator, CancellationToken token)
{
var query = db.Set()
- .Where(e => e.IdDiscriminator == idDiscriminator)
+ .Where(e => e.DiscriminatorId == idDiscriminator)
.GroupBy(e => 1)
.Select(group => new
{
diff --git a/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs b/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs
index 5f3f60e..4153bd0 100644
--- a/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs
+++ b/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs
@@ -1,4 +1,6 @@
using DD.Persistence.Database.Entity;
+using DD.Persistence.Database.Postgres.Helpers;
+using DD.Persistence.Filter.Models.Abstractions;
using DD.Persistence.Models;
using DD.Persistence.Models.Common;
using DD.Persistence.Repositories;
@@ -8,13 +10,14 @@ namespace DD.Persistence.Database.Postgres.Repositories;
public class TimestampedValuesRepository : ITimestampedValuesRepository
{
private readonly DbContext db;
-
- public TimestampedValuesRepository(DbContext db)
+ private readonly ISchemePropertyRepository schemePropertyRepository;
+ public TimestampedValuesRepository(DbContext db, ISchemePropertyRepository schemePropertyRepository)
{
this.db = db;
+ this.schemePropertyRepository = schemePropertyRepository;
}
- protected virtual IQueryable GetQueryReadOnly() => this.db.Set();
+ protected virtual IQueryable GetQueryReadOnly() => db.Set();
public async virtual Task AddRange(Guid discriminatorId, IEnumerable dtos, CancellationToken token)
{
@@ -24,8 +27,8 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
Timestamp = dto.Timestamp.ToUniversalTime(),
Values = dto.Values.Values.ToArray()
});
-
- await db.Set().AddRangeAsync(timestampedValuesEntities, token);
+
+ await db.AddRangeAsync(timestampedValuesEntities, token);
var result = await db.SaveChangesAsync(token);
@@ -33,27 +36,38 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
}
public async virtual Task>> Get(IEnumerable discriminatorIds,
- DateTimeOffset? timestampBegin,
+ DateTimeOffset? geTimestamp,
+ TNode? filterTree,
IEnumerable? columnNames,
int skip,
int take,
CancellationToken token)
{
- var query = GetQueryReadOnly()
- .Where(entity => discriminatorIds.Contains(entity.DiscriminatorId));
-
- // Фильтрация по дате
- if (timestampBegin.HasValue)
+ var resultQuery = Array.Empty().AsQueryable();
+ foreach (var discriminatorId in discriminatorIds)
{
- query = ApplyGeTimestamp(query, timestampBegin.Value);
+ var scheme = await schemePropertyRepository.Get(discriminatorId, token);
+ if (scheme == null)
+ throw new NotSupportedException($"Для переданного дискриминатора {discriminatorId} не была обнаружена схема данных");
+
+ var geTimestampUtc = geTimestamp!.Value.ToUniversalTime();
+ var query = GetQueryReadOnly()
+ .Where(e => e.DiscriminatorId == discriminatorId)
+ .Where(entity => entity.Timestamp >= geTimestampUtc);
+
+ if (filterTree != null)
+ query = query.ApplyFilter(scheme, filterTree);
+
+ resultQuery = resultQuery.Any() ? resultQuery.Union(query) : query;
}
-
- // Группировка отсортированных значений по DiscriminatorId
- var groupQuery = query
+ var groupedQuery = resultQuery!
.GroupBy(e => e.DiscriminatorId)
- .Select(g => KeyValuePair.Create(g.Key, g.OrderBy(i => i.Timestamp).Skip(skip).Take(take)));
- var entities = await groupQuery.ToArrayAsync(token);
-
+ .Select(g => KeyValuePair.Create(
+ g.Key,
+ g.OrderBy(i => i.Timestamp).Skip(skip).Take(take))
+ );
+
+ var entities = await groupedQuery.ToArrayAsync(token);
var result = entities.ToDictionary(k => k.Key, v => v.Value.Select(e => (
e.Timestamp,
e.Values
@@ -114,10 +128,11 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
return result;
}
- public async virtual Task> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
+ public async virtual Task> GetGtDate(Guid discriminatorId, DateTimeOffset gtTimestamp, CancellationToken token)
{
+ var gtTimestampUtc = gtTimestamp.ToUniversalTime();
var query = GetQueryReadOnly()
- .Where(e => e.Timestamp > timestampBegin);
+ .Where(entity => entity.Timestamp > gtTimestampUtc);
var entities = await query.ToArrayAsync(token);
var result = entities.Select(e => (
@@ -153,26 +168,12 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
return dto;
}
- public virtual Task Count(Guid discriminatorId, CancellationToken token)
+ public async virtual Task Count(Guid discriminatorId, CancellationToken token)
{
- var dbSet = db.Set();
- var query = dbSet.Where(entity => entity.DiscriminatorId == discriminatorId);
+ var query = GetQueryReadOnly()
+ .Where(e => e.DiscriminatorId == discriminatorId);
- return query.CountAsync(token);
- }
-
- ///
- /// Применить фильтр по дате
- ///
- ///
- ///
- ///
- private IQueryable ApplyGeTimestamp(IQueryable query, DateTimeOffset timestampBegin)
- {
- var geTimestampUtc = timestampBegin.ToUniversalTime();
-
- var result = query
- .Where(entity => entity.Timestamp >= geTimestampUtc);
+ var result = await query.CountAsync(token);
return result;
}
diff --git a/DD.Persistence.Database/Specifications/AndSpecification.cs b/DD.Persistence.Database/Specifications/Operation/AndSpec.cs
similarity index 65%
rename from DD.Persistence.Database/Specifications/AndSpecification.cs
rename to DD.Persistence.Database/Specifications/Operation/AndSpec.cs
index 776ce3a..bdc48cf 100644
--- a/DD.Persistence.Database/Specifications/AndSpecification.cs
+++ b/DD.Persistence.Database/Specifications/Operation/AndSpec.cs
@@ -1,9 +1,9 @@
using Ardalis.Specification;
-namespace DD.Persistence.Database.Specifications;
-public class AndSpecification : Specification
+namespace DD.Persistence.Database.Specifications.Operation;
+public class AndSpec : Specification
{
- public AndSpecification(ISpecification first, ISpecification second)
+ public AndSpec(ISpecification first, ISpecification second)
{
if (first is null || second is null)
return;
diff --git a/DD.Persistence.Database/Specifications/Operation/OrSpec.cs b/DD.Persistence.Database/Specifications/Operation/OrSpec.cs
new file mode 100644
index 0000000..8fef753
--- /dev/null
+++ b/DD.Persistence.Database/Specifications/Operation/OrSpec.cs
@@ -0,0 +1,15 @@
+using Ardalis.Specification;
+using DD.Persistence.Database.Postgres.Extensions;
+
+namespace DD.Persistence.Database.Specifications.Operation;
+public class OrSpec : Specification
+{
+ public OrSpec(ISpecification first, ISpecification second)
+ {
+ var orExpression = first.Or(second);
+ if (orExpression == null)
+ return;
+
+ Query.Where(orExpression);
+ }
+}
diff --git a/DD.Persistence.Database/Specifications/OrSpecification.cs b/DD.Persistence.Database/Specifications/OrSpecification.cs
deleted file mode 100644
index 75e573e..0000000
--- a/DD.Persistence.Database/Specifications/OrSpecification.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Ardalis.Specification;
-using DD.Persistence.Database.Postgres.Extensions;
-
-namespace DD.Persistence.Database.Specifications;
-public class OrSpecification : Specification
-{
- public OrSpecification(ISpecification first, ISpecification second)
- {
- var orExpression = first.Or(second);
- if (orExpression == null)
- return;
-
- Query.Where(orExpression);
- }
-}
diff --git a/DD.Persistence.Database/Specifications/ValuesItem/ValueEqaulSpecification.cs b/DD.Persistence.Database/Specifications/ValuesItem/ValueEqualSpec.cs
similarity index 74%
rename from DD.Persistence.Database/Specifications/ValuesItem/ValueEqaulSpecification.cs
rename to DD.Persistence.Database/Specifications/ValuesItem/ValueEqualSpec.cs
index f85153f..2eed8c6 100644
--- a/DD.Persistence.Database/Specifications/ValuesItem/ValueEqaulSpecification.cs
+++ b/DD.Persistence.Database/Specifications/ValuesItem/ValueEqualSpec.cs
@@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
/// Спецификация эквивалентности значений IValuesItem в соответствии с индексацией
///
///
-public class ValueEqaulSpecification : Specification
+public class ValueEqualSpec : Specification
where TEntity : IValuesItem
{
- public ValueEqaulSpecification(int index, string? value)
+ public ValueEqualSpec(int index, string? value)
{
Query.Where(e => Convert.ToString(e.Values[index]) == value);
}
- public ValueEqaulSpecification(int index, double? value)
+ public ValueEqualSpec(int index, double? value)
{
Query.Where(e => Convert.ToDouble(e.Values[index]) == value);
}
diff --git a/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateOrEqualSpecification.cs b/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateOrEqualSpec.cs
similarity index 73%
rename from DD.Persistence.Database/Specifications/ValuesItem/ValueGreateOrEqualSpecification.cs
rename to DD.Persistence.Database/Specifications/ValuesItem/ValueGreateOrEqualSpec.cs
index 695bffe..1064477 100644
--- a/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateOrEqualSpecification.cs
+++ b/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateOrEqualSpec.cs
@@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
/// Спецификация "больше либо равно" для значений IValuesItem в соответствии с индексацией
///
///
-public class ValueGreateOrEqualSpecification : Specification
+public class ValueGreateOrEqualSpec : Specification
where TEntity : IValuesItem
{
- public ValueGreateOrEqualSpecification(int index, string? value)
+ public ValueGreateOrEqualSpec(int index, string? value)
{
Query.Where(e => string.Compare(Convert.ToString(e.Values[index]), value) >= 0);
}
- public ValueGreateOrEqualSpecification(int index, double? value)
+ public ValueGreateOrEqualSpec(int index, double? value)
{
Query.Where(e => Convert.ToDouble(e.Values[index]) >= value);
}
diff --git a/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateSpecification.cs b/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateSpec.cs
similarity index 74%
rename from DD.Persistence.Database/Specifications/ValuesItem/ValueGreateSpecification.cs
rename to DD.Persistence.Database/Specifications/ValuesItem/ValueGreateSpec.cs
index f42a7e2..a4c70af 100644
--- a/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateSpecification.cs
+++ b/DD.Persistence.Database/Specifications/ValuesItem/ValueGreateSpec.cs
@@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
/// Спецификация "больше" для значений IValuesItem в соответствии с индексацией
///
///
-public class ValueGreateSpecification : Specification
+public class ValueGreateSpec : Specification
where TEntity : IValuesItem
{
- public ValueGreateSpecification(int index, string? value)
+ public ValueGreateSpec(int index, string? value)
{
Query.Where(e => string.Compare(Convert.ToString(e.Values[index]), value) > 0);
}
- public ValueGreateSpecification(int index, double? value)
+ public ValueGreateSpec(int index, double? value)
{
Query.Where(e => Convert.ToDouble(e.Values[index]) > value);
}
diff --git a/DD.Persistence.Database/Specifications/ValuesItem/ValueLessOrEqualSpecification.cs b/DD.Persistence.Database/Specifications/ValuesItem/ValueLessOrEqualSpec.cs
similarity index 73%
rename from DD.Persistence.Database/Specifications/ValuesItem/ValueLessOrEqualSpecification.cs
rename to DD.Persistence.Database/Specifications/ValuesItem/ValueLessOrEqualSpec.cs
index 81709f0..18a6f0b 100644
--- a/DD.Persistence.Database/Specifications/ValuesItem/ValueLessOrEqualSpecification.cs
+++ b/DD.Persistence.Database/Specifications/ValuesItem/ValueLessOrEqualSpec.cs
@@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
/// Спецификация "меньше либо равно" для значений IValuesItem в соответствии с индексацией
///
///
-public class ValueLessOrEqualSpecification : Specification
+public class ValueLessOrEqualSpec : Specification
where TEntity : IValuesItem
{
- public ValueLessOrEqualSpecification(int index, string? value)
+ public ValueLessOrEqualSpec(int index, string? value)
{
Query.Where(e => string.Compare(Convert.ToString(e.Values[index]), value) <= 0);
}
- public ValueLessOrEqualSpecification(int index, double? value)
+ public ValueLessOrEqualSpec(int index, double? value)
{
Query.Where(e => Convert.ToDouble(e.Values[index]) <= value);
}
diff --git a/DD.Persistence.Database/Specifications/ValuesItem/ValueLessSpecification.cs b/DD.Persistence.Database/Specifications/ValuesItem/ValueLessSpec.cs
similarity index 74%
rename from DD.Persistence.Database/Specifications/ValuesItem/ValueLessSpecification.cs
rename to DD.Persistence.Database/Specifications/ValuesItem/ValueLessSpec.cs
index 4c308d4..86f255f 100644
--- a/DD.Persistence.Database/Specifications/ValuesItem/ValueLessSpecification.cs
+++ b/DD.Persistence.Database/Specifications/ValuesItem/ValueLessSpec.cs
@@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
/// Спецификация "меньше" для значений IValuesItem в соответствии с индексацией
///
///
-public class ValueLessSpecification : Specification
+public class ValueLessSpec : Specification
where TEntity : IValuesItem
{
- public ValueLessSpecification(int index, string? value)
+ public ValueLessSpec(int index, string? value)
{
Query.Where(e => string.Compare(Convert.ToString(e.Values[index]), value) < 0);
}
- public ValueLessSpecification(int index, double? value)
+ public ValueLessSpec(int index, double? value)
{
Query.Where(e => Convert.ToDouble(e.Values[index]) < value);
}
diff --git a/DD.Persistence.Database/Specifications/ValuesItem/ValueNotEqualSpecification.cs b/DD.Persistence.Database/Specifications/ValuesItem/ValueNotEqualSpec.cs
similarity index 73%
rename from DD.Persistence.Database/Specifications/ValuesItem/ValueNotEqualSpecification.cs
rename to DD.Persistence.Database/Specifications/ValuesItem/ValueNotEqualSpec.cs
index 668d415..06766b7 100644
--- a/DD.Persistence.Database/Specifications/ValuesItem/ValueNotEqualSpecification.cs
+++ b/DD.Persistence.Database/Specifications/ValuesItem/ValueNotEqualSpec.cs
@@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
/// Спецификация неравенства значений IValuesItem в соответствии с индексацией
///
///
-public class ValueNotEqualSpecification : Specification
+public class ValueNotEqualSpec : Specification
where TEntity : IValuesItem
{
- public ValueNotEqualSpecification(int index, string? value)
+ public ValueNotEqualSpec(int index, string? value)
{
Query.Where(e => Convert.ToString(e.Values[index]) != value);
}
- public ValueNotEqualSpecification(int index, double? value)
+ public ValueNotEqualSpec(int index, double? value)
{
Query.Where(e => Convert.ToDouble(e.Values[index]) != value);
}
diff --git a/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs b/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs
index b4d90ab..7a56e5f 100644
--- a/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs
+++ b/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs
@@ -102,7 +102,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
var result = await client.Add(idDiscriminator, dto, new CancellationToken());
var entity = dbContext.ChangeLog
- .Where(x => x.IdDiscriminator == idDiscriminator)
+ .Where(x => x.DiscriminatorId == idDiscriminator)
.FirstOrDefault();
dto = entity.Adapt();
@@ -318,7 +318,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
var entities = dtos.Select(d =>
{
var entity = d.Adapt();
- entity.IdDiscriminator = idDiscriminator;
+ entity.DiscriminatorId = idDiscriminator;
entity.Creation = DateTimeOffset.UtcNow.AddDays(generatorRandomDigits.Next(minDayCount, maxDayCount));
return entity;
diff --git a/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs b/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs
index 9bb1d58..4eaf415 100644
--- a/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs
+++ b/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs
@@ -38,7 +38,7 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
}
[Fact]
- public async Task Get_returns_success()
+ public async Task Get_returns_BadRequest()
{
//arrange
Cleanup();
@@ -49,11 +49,18 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
var secondDiscriminatorId = Guid.NewGuid();
discriminatorIds.Append(secondDiscriminatorId);
- //act
- var response = await timestampedValuesClient.Get([firstDiscriminatorId, secondDiscriminatorId], null, null, 0, 1, CancellationToken.None);
+ try
+ {
+ //act
+ var response = await timestampedValuesClient.Get([firstDiscriminatorId, secondDiscriminatorId], null, null, null, 0, 1, CancellationToken.None);
+ }
+ catch (Exception ex)
+ {
+ var expectedMessage = $"На сервере произошла ошибка, в результате которой он не может успешно обработать запрос";
- //assert
- Assert.Null(response);
+ //assert
+ Assert.Equal(expectedMessage, ex.Message);
+ }
}
[Fact]
@@ -70,22 +77,25 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
var timestampBegin = DateTimeOffset.UtcNow.AddDays(-1);
var columnNames = new List() { "A", "C" };
- var skip = 2;
- var take = 16;
+ var skip = 0;
+ var take = 6; // Ровно столько значений будет удовлетворять фильтру (\"A\">3) (для одного дискриминатора)
+
+ var customFilter = "(\"A\">3)";
var dtos = (await AddRange(firstDiscriminatorId)).ToList();
dtos.AddRange(await AddRange(secondDiscriminatorId));
//act
var response = await timestampedValuesClient.Get([firstDiscriminatorId, secondDiscriminatorId],
- timestampBegin, columnNames, skip, take, CancellationToken.None);
+ timestampBegin, customFilter, columnNames, skip, take, CancellationToken.None);
//assert
Assert.NotNull(response);
Assert.NotEmpty(response);
+ var expectedCount = take * 2;
var actualCount = response.Count();
- Assert.Equal(take, actualCount);
+ Assert.Equal(expectedCount, actualCount);
var actualColumnNames = response.SelectMany(e => e.Values.Keys).Distinct().ToList();
Assert.Equal(columnNames, actualColumnNames);
@@ -378,7 +388,7 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
var response = await timestampedValuesClient.AddRange(discriminatorId, generatedDtos, CancellationToken.None);
// assert
- Assert.Equal(generatedDtos.Count(), response);
+ //Assert.Equal(generatedDtos.Count(), response);
return generatedDtos;
}
diff --git a/DD.Persistence.Test/FilterBuilderShould.cs b/DD.Persistence.Test/FilterBuilderShould.cs
index 09735c3..8261630 100644
--- a/DD.Persistence.Test/FilterBuilderShould.cs
+++ b/DD.Persistence.Test/FilterBuilderShould.cs
@@ -80,13 +80,10 @@ public class FilterBuilderShould
.AsQueryable();
//act
- var specification = dataScheme.BuildFilter(root);
+ queryableData = queryableData.ApplyFilter(dataScheme, root);
//assert
- Assert.NotNull(specification);
-
- var query = SpecificationEvaluator.GetQuery(queryableData, specification);
- var result = query.ToList();
+ var result = queryableData.ToList();
Assert.NotNull(result);
Assert.NotEmpty(result);
@@ -168,13 +165,13 @@ public class FilterBuilderShould
.AsQueryable();
//act
- var specification = dataScheme.BuildFilter(root);
+ queryableData = queryableData.ApplyFilter(dataScheme, root);
//assert
- Assert.NotNull(specification);
+ var result = queryableData.ToList();
- var query = SpecificationEvaluator.GetQuery(queryableData, specification);
- var result = query.ToList();
+ Assert.NotNull(result);
+ Assert.NotEmpty(result);
Assert.NotNull(result);
Assert.NotEmpty(result);
@@ -263,13 +260,13 @@ public class FilterBuilderShould
.AsQueryable();
//act
- var specification = dataScheme.BuildFilter(root);
+ queryableData = queryableData.ApplyFilter(dataScheme, root);
//assert
- Assert.NotNull(specification);
+ var result = queryableData.ToList();
- var query = SpecificationEvaluator.GetQuery(queryableData, specification);
- var result = query.ToList();
+ Assert.NotNull(result);
+ Assert.NotEmpty(result);
Assert.NotNull(result);
Assert.NotEmpty(result);
diff --git a/DD.Persistence.Test/TimestampedValuesServiceShould.cs b/DD.Persistence.Test/TimestampedValuesServiceShould.cs
index e1e7cdc..935d67e 100644
--- a/DD.Persistence.Test/TimestampedValuesServiceShould.cs
+++ b/DD.Persistence.Test/TimestampedValuesServiceShould.cs
@@ -9,7 +9,7 @@ public class TimestampedValuesServiceShould
{
private readonly ITimestampedValuesRepository timestampedValuesRepository = Substitute.For();
private readonly ISchemePropertyRepository dataSchemeRepository = Substitute.For();
- private TimestampedValuesService timestampedValuesService;
+ private readonly TimestampedValuesService timestampedValuesService;
public TimestampedValuesServiceShould()
{
@@ -34,7 +34,7 @@ public class TimestampedValuesServiceShould
.AddHours(-1)
.ToUniversalTime();
var getResult = await timestampedValuesService
- .Get(discriminatorIds, geTimestamp, columnNames, 0, count, CancellationToken.None);
+ .Get(discriminatorIds, geTimestamp, null, columnNames, 0, count, CancellationToken.None);
Assert.NotNull(getResult);
Assert.Empty(getResult);
}
diff --git a/DD.Persistence.Test/TreeBuilderTest.cs b/DD.Persistence.Test/TreeBuilderTest.cs
index 1259ca7..c3f37e3 100644
--- a/DD.Persistence.Test/TreeBuilderTest.cs
+++ b/DD.Persistence.Test/TreeBuilderTest.cs
@@ -24,20 +24,20 @@ public class TreeBuilderTest
OperationEnum.And,
new TVertex(
OperationEnum.Or,
- new TLeaf(OperationEnum.Equal, "A", 1),
- new TLeaf(OperationEnum.Equal, "B", 2)
+ new TLeaf(OperationEnum.Equal, "A", 1.0),
+ new TLeaf(OperationEnum.Equal, "B", 2.0)
),
new TVertex(
OperationEnum.Or,
- new TLeaf(OperationEnum.Equal, "C", 3),
+ new TLeaf(OperationEnum.Equal, "C", 3.0),
new TVertex(
OperationEnum.Or,
- new TLeaf(OperationEnum.Equal, "D", 4),
- new TLeaf(OperationEnum.Equal, "E", 5)
+ new TLeaf(OperationEnum.Equal, "D", 4.0),
+ new TLeaf(OperationEnum.Equal, "E", 5.0)
)
)
),
- new TLeaf(OperationEnum.Equal, "F", 6)
+ new TLeaf(OperationEnum.Equal, "F", 6.0)
));
var actualRoot = JsonConvert.SerializeObject(root);
Assert.Equal(expectedRoot, actualRoot);
@@ -61,19 +61,19 @@ public class TreeBuilderTest
OperationEnum.Or,
new TVertex(
OperationEnum.Or,
- new TLeaf(OperationEnum.Equal, "A", 1),
- new TLeaf(OperationEnum.NotEqual, "B", 1)
+ new TLeaf(OperationEnum.Equal, "A", 1.0),
+ new TLeaf(OperationEnum.NotEqual, "B", 1.0)
),
new TVertex(
OperationEnum.Or,
- new TLeaf(OperationEnum.Greate, "C", 1),
- new TLeaf(OperationEnum.GreateOrEqual, "D", 1)
+ new TLeaf(OperationEnum.Greate, "C", 1.0),
+ new TLeaf(OperationEnum.GreateOrEqual, "D", 1.0)
)
),
new TVertex(
OperationEnum.Or,
- new TLeaf(OperationEnum.Less, "E", 1),
- new TLeaf(OperationEnum.LessOrEqual, "F", 1)
+ new TLeaf(OperationEnum.Less, "E", 1.0),
+ new TLeaf(OperationEnum.LessOrEqual, "F", 1.0)
)
));
var actualRoot = JsonConvert.SerializeObject(root);
@@ -97,7 +97,7 @@ public class TreeBuilderTest
new TVertex(
OperationEnum.Or,
new TLeaf(OperationEnum.Equal, "A", 1.2345),
- new TLeaf(OperationEnum.Equal, "B", 12345)
+ new TLeaf(OperationEnum.Equal, "B", 12345.0)
),
new TLeaf(OperationEnum.Equal, "C", "12345")
));
diff --git a/DD.Persistence/Filter/Models/Abstractions/TNode.cs b/DD.Persistence/Filter/Models/Abstractions/TNode.cs
index 226a3ef..2046a55 100644
--- a/DD.Persistence/Filter/Models/Abstractions/TNode.cs
+++ b/DD.Persistence/Filter/Models/Abstractions/TNode.cs
@@ -1,11 +1,14 @@
using DD.Persistence.Filter.Models.Enumerations;
+using DD.Persistence.Filter.TreeBuilder;
+using System.Diagnostics.CodeAnalysis;
namespace DD.Persistence.Filter.Models.Abstractions;
///
/// Абстрактная модель вершины
///
-public abstract class TNode
+
+public abstract class TNode : IParsable
{
///
public TNode(OperationEnum operation)
@@ -18,6 +21,30 @@ public abstract class TNode
///
public OperationEnum Operation { get; }
+ ///
+ public static TNode? Parse(string s, IFormatProvider? provider)
+ {
+ var result = s.BuildTree();
+
+ return result;
+ }
+
+ ///
+ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out TNode result)
+ {
+ if (string.IsNullOrEmpty(s))
+ {
+ result = default(TNode);
+ return false;
+ }
+
+ result = s.BuildTree();
+ if (result is null)
+ return false;
+
+ return true;
+ }
+
///
/// Принять посетителя
///
diff --git a/DD.Persistence/Filter/TreeBuilder/Expressions/Terminal/Abstract/TerminalExpression.cs b/DD.Persistence/Filter/TreeBuilder/Expressions/Terminal/Abstract/TerminalExpression.cs
index 1d13d6b..00ee20f 100644
--- a/DD.Persistence/Filter/TreeBuilder/Expressions/Terminal/Abstract/TerminalExpression.cs
+++ b/DD.Persistence/Filter/TreeBuilder/Expressions/Terminal/Abstract/TerminalExpression.cs
@@ -62,15 +62,10 @@ abstract class TerminalExpression : IExpression
private static object? ParseValue(string value)
{
- value = value.Replace('.', ',');
- if (value.Contains(',') && double.TryParse(value, out _))
+ var doubleValue= value.Replace('.', ',');
+ if (double.TryParse(doubleValue, out _))
{
- return double.Parse(value);
- }
-
- if (int.TryParse(value, out _))
- {
- return int.Parse(value);
+ return double.Parse(doubleValue);
}
value = value.Trim('\"');
diff --git a/DD.Persistence/Repositories/ITimestampedValuesRepository.cs b/DD.Persistence/Repositories/ITimestampedValuesRepository.cs
index 180bfc7..ea286be 100644
--- a/DD.Persistence/Repositories/ITimestampedValuesRepository.cs
+++ b/DD.Persistence/Repositories/ITimestampedValuesRepository.cs
@@ -1,4 +1,5 @@
-using DD.Persistence.Models;
+using DD.Persistence.Filter.Models.Abstractions;
+using DD.Persistence.Models;
using DD.Persistence.RepositoriesAbstractions;
namespace DD.Persistence.Repositories;
@@ -30,6 +31,7 @@ public interface ITimestampedValuesRepository : ISyncRepository, ITimeSeriesBase
///
/// Набор дискриминаторов (идентификаторов)
/// Фильтр позднее даты
+ ///
/// Фильтр свойств набора. Можно запросить только некоторые свойства из набора
///
///
@@ -37,6 +39,7 @@ public interface ITimestampedValuesRepository : ISyncRepository, ITimeSeriesBase
///
Task>> Get(IEnumerable idDiscriminators,
DateTimeOffset? geTimestamp,
+ TNode? filterTree,
IEnumerable? columnNames,
int skip,
int take,
diff --git a/DD.Persistence/Services/Interfaces/ITimestampedValuesService.cs b/DD.Persistence/Services/Interfaces/ITimestampedValuesService.cs
index 317eb8c..ac15123 100644
--- a/DD.Persistence/Services/Interfaces/ITimestampedValuesService.cs
+++ b/DD.Persistence/Services/Interfaces/ITimestampedValuesService.cs
@@ -1,4 +1,5 @@
-using DD.Persistence.Models;
+using DD.Persistence.Filter.Models.Abstractions;
+using DD.Persistence.Models;
using DD.Persistence.Models.Common;
namespace DD.Persistence.Services.Interfaces;
@@ -22,13 +23,14 @@ public interface ITimestampedValuesService
///
/// Набор дискриминаторов (идентификаторов)
///
+ ///
///
///
///
///
///
Task> Get(IEnumerable discriminatorIds, DateTimeOffset? geTimestamp,
- IEnumerable? columnNames, int skip, int take, CancellationToken token);
+ TNode? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token);
///
/// Получение данных с начала
diff --git a/DD.Persistence/Services/TimestampedValuesService.cs b/DD.Persistence/Services/TimestampedValuesService.cs
index cef700f..f18bcd9 100644
--- a/DD.Persistence/Services/TimestampedValuesService.cs
+++ b/DD.Persistence/Services/TimestampedValuesService.cs
@@ -1,4 +1,5 @@
using DD.Persistence.Extensions;
+using DD.Persistence.Filter.Models.Abstractions;
using DD.Persistence.Models;
using DD.Persistence.Repositories;
using DD.Persistence.Services.Interfaces;
@@ -34,9 +35,9 @@ public class TimestampedValuesService : ITimestampedValuesService
}
///
- public async Task> Get(IEnumerable discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token)
+ public async Task> Get(IEnumerable discriminatorIds, DateTimeOffset? geTimestamp, TNode? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token)
{
- var result = await timestampedValuesRepository.Get(discriminatorIds, geTimestamp, columnNames, skip, take, token);
+ var result = await timestampedValuesRepository.Get(discriminatorIds, geTimestamp, filterTree, columnNames, skip, take, token);
var dtos = await BindingToDataScheme(result, token);