Compare commits
17 Commits
feature/sp
...
master
Author | SHA1 | Date | |
---|---|---|---|
a5037b8967 | |||
27b9728912 | |||
93472f7933 | |||
0d9c61c905 | |||
36274b3a5e | |||
b30d28dbeb | |||
233850483c | |||
ca0b1f0031 | |||
3cf7cbcc7c | |||
a49a0f567a | |||
c904c117d8 | |||
0aca5d2d43 | |||
4b9a4b4db7 | |||
e1f84f3091 | |||
2fe369d49e | |||
8e2c3a3a55 | |||
83c744939b |
@ -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
|
||||
/// </summary>
|
||||
/// <param name="discriminatorIds">Набор дискриминаторов</param>
|
||||
/// <param name="timestampBegin">Фильтр позднее даты</param>
|
||||
/// <param name="filterTree">Кастомный фильтр по набору значений</param>
|
||||
/// <param name="columnNames">Фильтр свойств набора</param>
|
||||
/// <param name="skip"></param>
|
||||
/// <param name="take"></param>
|
||||
@ -52,9 +54,14 @@ public class TimestampedValuesController : ControllerBase
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<TimestampedValuesDto>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||
public async Task<ActionResult<IEnumerable<TimestampedValuesDto>>> Get([FromQuery] IEnumerable<Guid> discriminatorIds, DateTimeOffset? timestampBegin, [FromQuery] string[]? columnNames, int skip, int take, CancellationToken token)
|
||||
public async Task<ActionResult<IEnumerable<TimestampedValuesDto>>> Get([FromQuery] IEnumerable<Guid> 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();
|
||||
}
|
||||
|
@ -28,4 +28,8 @@
|
||||
<ProjectReference Include="..\DD.Persistence\DD.Persistence.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Docs\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -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<TNode>(() => new OpenApiSchema { Type = "string" });
|
||||
|
||||
c.CustomOperationIds(e =>
|
||||
{
|
||||
|
359
DD.Persistence.API/Docs/ChangeLog_actions.drawio.xml
Normal file
359
DD.Persistence.API/Docs/ChangeLog_actions.drawio.xml
Normal file
@ -0,0 +1,359 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" version="24.8.3">
|
||||
<diagram name="Страница — 1" id="7k5Wemfp-yc9piGHxsiE">
|
||||
<mxGraphModel dx="2049" dy="1054" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1300" pageHeight="1050" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-1" value="" style="endArrow=none;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="355" y="930" as="sourcePoint" />
|
||||
<mxPoint x="355" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-2" value="" style="endArrow=none;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="555" y="930" as="sourcePoint" />
|
||||
<mxPoint x="555" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-4" value="<b>FRONT</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#76608a;strokeColor=#432D57;fontColor=#ffffff;" vertex="1" parent="1">
|
||||
<mxGeometry x="325" y="180" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-5" value="<b>BACK</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#76608a;fontColor=#ffffff;strokeColor=#432D57;" vertex="1" parent="1">
|
||||
<mxGeometry x="525" y="180" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-7" value="<b>CACHE</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#76608a;fontColor=#ffffff;strokeColor=#432D57;" vertex="1" parent="1">
|
||||
<mxGeometry x="725" y="180" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-8" value="" style="endArrow=none;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="955" y="930" as="sourcePoint" />
|
||||
<mxPoint x="955" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-9" value="<b>COMMIT REPOSITORY</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#76608a;fontColor=#ffffff;strokeColor=#432D57;" vertex="1" parent="1">
|
||||
<mxGeometry x="880" y="180" width="155" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-32" value="" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;align=center;" edge="1" parent="1" target="_dnhcZFeje3u91oS2JwL-7">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="755" y="930" as="sourcePoint" />
|
||||
<mxPoint x="756.5000000000002" y="300" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-52" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="300" as="sourcePoint" />
|
||||
<mxPoint x="755" y="300" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-53" value="<span style="font-size: 12px; text-wrap-mode: wrap;">GetOrCreate(userId, message)</span>" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;labelBackgroundColor=none;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-52">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-67" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="755" y="310" as="sourcePoint" />
|
||||
<mxPoint x="955" y="310.83" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-68" value="CreateCommit(userId, message)" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;labelBackgroundColor=none;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-67">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-69" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="955" y="330" as="sourcePoint" />
|
||||
<mxPoint x="755" y="330" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-70" value="CommitId" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-69">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-88" value="" style="endArrow=none;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1155" y="930" as="sourcePoint" />
|
||||
<mxPoint x="1155" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-89" value="<b>CHANGE LOG REPOSITORY</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#76608a;fontColor=#ffffff;strokeColor=#432D57;" vertex="1" parent="1">
|
||||
<mxGeometry x="1060" y="180" width="185" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-90" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="755" y="340" as="sourcePoint" />
|
||||
<mxPoint x="555" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-91" value="CommitId" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-90">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-93" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="380" as="sourcePoint" />
|
||||
<mxPoint x="1155" y="380" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-94" value="AddRange(items, commitId)" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;labelBackgroundColor=none;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-93">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-96" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="1155" y="410" as="sourcePoint" />
|
||||
<mxPoint x="555" y="410" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-97" value="CREATED" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-96">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-100" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="420" as="sourcePoint" />
|
||||
<mxPoint x="355" y="420" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-101" value="CREATED" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-100">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-102" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=9;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="555" y="420" as="sourcePoint" />
|
||||
<mxPoint x="555" y="290" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-104" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="355" y="290" as="sourcePoint" />
|
||||
<mxPoint x="555" y="290" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-105" value="Insert(items, message) [POST]" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;labelBackgroundColor=none;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-104">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-107" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=9;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="354.13" y="420" as="sourcePoint" />
|
||||
<mxPoint x="354.13" y="290" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-108" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="355" y="520" as="sourcePoint" />
|
||||
<mxPoint x="555" y="520" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-109" value="Update(items, message) [PUT]" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-108">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-110" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="530" as="sourcePoint" />
|
||||
<mxPoint x="755" y="530" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-111" value="<span style="font-size: 12px; text-wrap-mode: wrap;">GetOrCreate(userId, message)</span>" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;labelBackgroundColor=none;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-110">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-112" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="755" y="560" as="sourcePoint" />
|
||||
<mxPoint x="555" y="560" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-113" value="CommitId" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-112">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-114" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=9;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="554.5699999999999" y="650" as="sourcePoint" />
|
||||
<mxPoint x="554.5699999999999" y="520" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-115" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="610" as="sourcePoint" />
|
||||
<mxPoint x="1155" y="610" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-116" value="UpdateRange(items, commitId)" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-115">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-117" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="1155" y="640" as="sourcePoint" />
|
||||
<mxPoint x="555" y="640" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-118" value="OK" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-117">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-119" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="650" as="sourcePoint" />
|
||||
<mxPoint x="355" y="650" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-120" value="OK" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-119">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-121" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="755" y="530" as="sourcePoint" />
|
||||
<mxPoint x="755" y="560" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="775" y="550" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-122" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="355" y="760" as="sourcePoint" />
|
||||
<mxPoint x="555" y="760" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-123" value="Delete(items, message) [DELETE]" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-122">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-124" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="770" as="sourcePoint" />
|
||||
<mxPoint x="755" y="770" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-125" value="<span style="font-size: 12px; text-wrap-mode: wrap;">GetOrCreate(userId, message)</span>" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;labelBackgroundColor=none;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-124">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-126" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="755" y="800" as="sourcePoint" />
|
||||
<mxPoint x="555" y="800" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-127" value="CommitId" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-126">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-128" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=9;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="554.5699999999999" y="890" as="sourcePoint" />
|
||||
<mxPoint x="554.5699999999999" y="760" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-129" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="850" as="sourcePoint" />
|
||||
<mxPoint x="1155" y="850" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-130" value="UpdateRange(items, commitId)" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-129">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-131" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="1155" y="880" as="sourcePoint" />
|
||||
<mxPoint x="555" y="880" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-132" value="OK" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-131">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-133" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="555" y="890" as="sourcePoint" />
|
||||
<mxPoint x="355" y="890" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-134" value="OK" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-133">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-135" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="755" y="770" as="sourcePoint" />
|
||||
<mxPoint x="755" y="800" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="775" y="790" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-136" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=9;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="354.57" y="650" as="sourcePoint" />
|
||||
<mxPoint x="354.57" y="520" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-137" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=9;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="354.57" y="890" as="sourcePoint" />
|
||||
<mxPoint x="354.57" y="760" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-138" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=10;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1155" y="411" as="sourcePoint" />
|
||||
<mxPoint x="1155" y="381" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-139" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=10;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1155" y="641" as="sourcePoint" />
|
||||
<mxPoint x="1155" y="611" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-140" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=10;curved=1;targetPerimeterSpacing=3;fillColor=#f8cecc;gradientColor=#ea6b66;strokeColor=#b85450;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1154.75" y="881" as="sourcePoint" />
|
||||
<mxPoint x="1154.75" y="851" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-141" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=10;curved=1;targetPerimeterSpacing=3;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;opacity=50;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="755" y="830" as="sourcePoint" />
|
||||
<mxPoint x="754.93" y="312" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-142" value="" style="endArrow=none;html=1;rounded=0;fillColor=#dae8fc;strokeColor=#6c8ebf;strokeWidth=10;opacity=50;gradientColor=#7ea6e0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="165" y="882" as="sourcePoint" />
|
||||
<mxPoint x="165.22" y="292" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-143" value="<font color="#330066">User</font>" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;fillColor=#76608a;strokeColor=#432D57;fontColor=#ffffff;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="155" y="180" width="21.5" height="43" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-146" value="" style="endArrow=classic;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="170" y="280" as="sourcePoint" />
|
||||
<mxPoint x="360" y="280" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-147" value="SAVE" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;labelBackgroundColor=none;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-146">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-148" value="" style="endArrow=none;html=1;rounded=0;align=center;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="165.22" y="930" as="sourcePoint" />
|
||||
<mxPoint x="165.22" y="210" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-149" value="" style="endArrow=classic;html=1;rounded=0;dashed=1;align=center;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="355" y="892" as="sourcePoint" />
|
||||
<mxPoint x="165" y="892" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="265" y="892" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-150" value="OK" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="_dnhcZFeje3u91oS2JwL-149">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-152" value="<h1 style="margin-top: 0px;">UML-диаграмма процесса пакетного редактирования</h1><p>.</p>" style="text;html=1;whiteSpace=wrap;overflow=hidden;rounded=0;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="75" y="50" width="1150" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-154" value="frame" style="shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="250" width="1120" height="680" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="_dnhcZFeje3u91oS2JwL-156" value="<p style="line-height: 120%;">Время жизни кеша задается внутри проекта</p>" style="shape=note;size=20;whiteSpace=wrap;html=1;labelBackgroundColor=none;fillColor=#d0cee2;strokeColor=#56517e;opacity=50;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="660" width="120" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
@ -48,4 +48,7 @@ Password: 12345
|
||||
}
|
||||
```
|
||||
|
||||
## Пакетное редактирование (на примере ChangeLog)
|
||||
UML-диаграмма процесса редактирования находится по [ссылке](https://git.ddrilling.ru/on.nemtina/persistence/src/branch/master/DD.Persistence.API/Docs/ChangeLog_actions.drawio.xml)
|
||||
|
||||
|
||||
|
@ -28,7 +28,6 @@ COPY ["DD.Persistence/DD.Persistence.csproj", "DD.Persistence/"]
|
||||
COPY ["DD.Persistence.Database/DD.Persistence.Database.csproj", "DD.Persistence.Database/"]
|
||||
COPY ["DD.Persistence.Database.Postgres/DD.Persistence.Database.Postgres.csproj", "DD.Persistence.Database.Postgres/"]
|
||||
COPY ["DD.Persistence.Models/DD.Persistence.Models.csproj", "DD.Persistence.Models/"]
|
||||
COPY ["DD.Persistence.Repository/DD.Persistence.Repository.csproj", "DD.Persistence.Repository/"]
|
||||
|
||||
RUN dotnet restore "./DD.Persistence.App/DD.Persistence.App.csproj"
|
||||
|
||||
|
@ -24,12 +24,14 @@ public interface ITimestampedValuesClient : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="discriminatorIds">Набор дискриминаторов (идентификаторов)</param>
|
||||
/// <param name="timestampBegin">Фильтр позднее даты</param>
|
||||
/// <param name="filterTree">Кастомный фильтр по набору значений</param>
|
||||
/// <param name="columnNames">Фильтр свойств набора</param>
|
||||
/// <param name="skip"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds,
|
||||
DateTimeOffset? timestampBegin,
|
||||
string? filterTree,
|
||||
IEnumerable<string>? columnNames,
|
||||
int skip,
|
||||
int take,
|
||||
@ -40,11 +42,12 @@ public interface ITimestampedValuesClient : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="geTimestamp"></param>
|
||||
/// <param name="filterTree"></param>
|
||||
/// <param name="columnNames">Фильтр свойств набора</param>
|
||||
/// <param name="skip"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
Task<IEnumerable<T>> Get<T>(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
||||
Task<IEnumerable<T>> Get<T>(Guid discriminatorId, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить данные, начиная с заданной отметки времени
|
||||
|
@ -23,6 +23,7 @@ public interface IRefitTimestampedValuesClient : IRefitClient, IDisposable
|
||||
[Get($"{baseUrl}")]
|
||||
Task<IApiResponse<IEnumerable<TimestampedValuesDto>>> Get([Query(CollectionFormat.Multi)] IEnumerable<Guid> discriminatorIds,
|
||||
DateTimeOffset? timestampBegin,
|
||||
[Query] string? filterTree,
|
||||
[Query(CollectionFormat.Multi)] IEnumerable<string>? columnNames,
|
||||
int skip,
|
||||
int take,
|
||||
|
@ -32,17 +32,17 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable<string>? 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!;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<T>> Get<T>(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||
public async Task<IEnumerable<T>> Get<T>(Guid discriminatorId, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable<string>? 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<T>(discriminatorId);
|
||||
|
||||
return data.Select(mapper.DeserializeTimeStampedData);
|
||||
|
@ -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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
@ -37,14 +37,14 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания записи");
|
||||
|
||||
b.Property<Guid>("DiscriminatorId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid>("IdAuthor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Автор изменения");
|
||||
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid?>("IdEditor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Редактор");
|
@ -17,7 +17,7 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ записи"),
|
||||
IdDiscriminator = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор таблицы"),
|
||||
DiscriminatorId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор таблицы"),
|
||||
IdAuthor = table.Column<Guid>(type: "uuid", nullable: false, comment: "Автор изменения"),
|
||||
IdEditor = table.Column<Guid>(type: "uuid", nullable: true, comment: "Редактор"),
|
||||
Creation = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата создания записи"),
|
@ -34,14 +34,14 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания записи");
|
||||
|
||||
b.Property<Guid>("DiscriminatorId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid>("IdAuthor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Автор изменения");
|
||||
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid?>("IdEditor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Редактор");
|
||||
|
@ -42,6 +42,8 @@ public static class DependencyInjection
|
||||
|
||||
MapsterSetup();
|
||||
|
||||
//services.AddTransient(typeof(PersistenceRepository<TimestampedValues>));
|
||||
|
||||
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
||||
services.AddTransient<IChangeLogRepository, ChangeLogRepository>();
|
||||
services.AddTransient<ITimestampedValuesRepository, TimestampedValuesRepository>();
|
||||
|
@ -11,13 +11,13 @@ namespace DD.Persistence.Database.Entity;
|
||||
/// Часть записи, описывающая изменение
|
||||
/// </summary>
|
||||
[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; }
|
||||
|
@ -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; }
|
||||
|
@ -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; }
|
||||
|
@ -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; }
|
||||
|
@ -38,7 +38,7 @@ public interface IChangeLog
|
||||
/// <summary>
|
||||
/// Дискриминатор таблицы
|
||||
/// </summary>
|
||||
public Guid IdDiscriminator { get; set; }
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Значение
|
||||
|
@ -0,0 +1,8 @@
|
||||
namespace DD.Persistence.Database.EntityAbstractions;
|
||||
public interface IDiscriminatorItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Дискриминатор
|
||||
/// </summary>
|
||||
Guid DiscriminatorId { get; set; }
|
||||
}
|
@ -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,7 +14,16 @@ using System.Text.Json;
|
||||
namespace DD.Persistence.Database.Postgres.Helpers;
|
||||
public static class FilterBuilder
|
||||
{
|
||||
public static ISpecification<TEntity>? BuildFilter<TEntity>(this DataSchemeDto dataSchemeDto, TNode root)
|
||||
public static IQueryable<TEntity> ApplyFilter<TEntity>(this IQueryable<TEntity> query, DataSchemeDto dataSchemeDto, TNode root)
|
||||
where TEntity : class, IValuesItem
|
||||
{
|
||||
var filterSpec = dataSchemeDto.BuildFilter<TEntity>(root);
|
||||
if (filterSpec != null)
|
||||
return query.WithSpecification(filterSpec);
|
||||
return query;
|
||||
}
|
||||
|
||||
private static ISpecification<TEntity>? BuildFilter<TEntity>(this DataSchemeDto dataSchemeDto, TNode root)
|
||||
where TEntity : IValuesItem
|
||||
{
|
||||
var result = dataSchemeDto.BuildSpecificationByNextNode<TEntity>(root);
|
||||
@ -48,10 +58,10 @@ public static class FilterBuilder
|
||||
switch (vertex.Operation)
|
||||
{
|
||||
case OperationEnum.And:
|
||||
result = new AndSpecification<TEntity>(leftSpecification, rigthSpecification);
|
||||
result = new AndSpec<TEntity>(leftSpecification, rigthSpecification);
|
||||
break;
|
||||
case OperationEnum.Or:
|
||||
result = new OrSpecification<TEntity>(leftSpecification, rigthSpecification);
|
||||
result = new OrSpec<TEntity>(leftSpecification, rigthSpecification);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -86,21 +96,21 @@ public static class FilterBuilder
|
||||
private static Dictionary<OperationEnum, Func<int, string?, ISpecification<TEntity>>> StringSpecifications<TEntity>()
|
||||
where TEntity : IValuesItem => new()
|
||||
{
|
||||
{ OperationEnum.Equal, (int index, string? value) => new ValueEqaulSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.NotEqual, (int index, string? value) => new ValueNotEqualSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.Greate, (int index, string? value) => new ValueGreateSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.GreateOrEqual, (int index, string? value) => new ValueGreateOrEqualSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.Less, (int index, string? value) => new ValueLessSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.LessOrEqual, (int index, string? value) => new ValueLessOrEqualSpecification<TEntity>(index, value) }
|
||||
{ OperationEnum.Equal, (int index, string? value) => new ValueEqualSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.NotEqual, (int index, string? value) => new ValueNotEqualSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.Greate, (int index, string? value) => new ValueGreateSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.GreateOrEqual, (int index, string? value) => new ValueGreateOrEqualSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.Less, (int index, string? value) => new ValueLessSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.LessOrEqual, (int index, string? value) => new ValueLessOrEqualSpec<TEntity>(index, value) }
|
||||
};
|
||||
private static Dictionary<OperationEnum, Func<int, double?, ISpecification<TEntity>>> DoubleSpecifications<TEntity>()
|
||||
where TEntity : IValuesItem => new()
|
||||
{
|
||||
{ OperationEnum.Equal, (int index, double? value) => new ValueEqaulSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.NotEqual, (int index, double? value) => new ValueNotEqualSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.Greate, (int index, double? value) => new ValueGreateSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.GreateOrEqual, (int index, double? value) => new ValueGreateOrEqualSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.Less, (int index, double? value) => new ValueLessSpecification<TEntity>(index, value) },
|
||||
{ OperationEnum.LessOrEqual, (int index, double? value) => new ValueLessOrEqualSpecification<TEntity>(index, value) }
|
||||
{ OperationEnum.Equal, (int index, double? value) => new ValueEqualSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.NotEqual, (int index, double? value) => new ValueNotEqualSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.Greate, (int index, double? value) => new ValueGreateSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.GreateOrEqual, (int index, double? value) => new ValueGreateOrEqualSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.Less, (int index, double? value) => new ValueLessSpec<TEntity>(index, value) },
|
||||
{ OperationEnum.LessOrEqual, (int index, double? value) => new ValueLessOrEqualSpec<TEntity>(index, value) }
|
||||
};
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
public async Task<int> MarkAsDeleted(Guid idEditor, Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var query = db.Set<ChangeLog>()
|
||||
.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<ChangeLog> CreateQuery(Guid idDiscriminator)
|
||||
{
|
||||
var query = db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator);
|
||||
var query = db.Set<ChangeLog>().Where(e => e.DiscriminatorId == idDiscriminator);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ChangeLogDto>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
||||
{
|
||||
var query = db.Set<ChangeLog>().Where(s => s.IdDiscriminator == idDiscriminator);
|
||||
var query = db.Set<ChangeLog>().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<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var query = db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator);
|
||||
var query = db.Set<ChangeLog>().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<ChangeLog>()
|
||||
.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<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var query = db.Set<ChangeLog>()
|
||||
.Where(e => e.IdDiscriminator == idDiscriminator)
|
||||
.Where(e => e.DiscriminatorId == idDiscriminator)
|
||||
.GroupBy(e => 1)
|
||||
.Select(group => new
|
||||
{
|
||||
|
@ -12,7 +12,7 @@ public class DataSourceSystemRepository : IDataSourceSystemRepository
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
protected virtual IQueryable<DataSourceSystem> GetQueryReadOnly() => db.Set<DataSourceSystem>();
|
||||
protected IQueryable<DataSourceSystem> GetQueryReadOnly() => db.Set<DataSourceSystem>();
|
||||
|
||||
public virtual async Task Add(DataSourceSystemDto dataSourceSystemDto, CancellationToken token)
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ public class ParameterRepository : IParameterRepository
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<ParameterData> GetQueryReadOnly() => db.Set<ParameterData>();
|
||||
protected IQueryable<ParameterData> GetQueryReadOnly() => db.Set<ParameterData>();
|
||||
|
||||
public async Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
|
@ -12,7 +12,7 @@ public class SchemePropertyRepository : ISchemePropertyRepository
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
protected virtual IQueryable<SchemeProperty> GetQueryReadOnly() => db.Set<SchemeProperty>();
|
||||
protected IQueryable<SchemeProperty> GetQueryReadOnly() => db.Set<SchemeProperty>();
|
||||
|
||||
public virtual async Task AddRange(DataSchemeDto dataSchemeDto, CancellationToken token)
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ namespace DD.Persistence.Database.Postgres.Repositories
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<Setpoint> GetQueryReadOnly() => db.Set<Setpoint>();
|
||||
protected IQueryable<Setpoint> GetQueryReadOnly() => db.Set<Setpoint>();
|
||||
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetCurrent(
|
||||
IEnumerable<Guid> setpointKeys,
|
||||
|
@ -20,7 +20,7 @@ namespace DD.Persistence.Database.Postgres.Repositories
|
||||
this.sourceSystemRepository = sourceSystemRepository;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<TechMessage> GetQueryReadOnly() => db.Set<TechMessage>()
|
||||
protected IQueryable<TechMessage> GetQueryReadOnly() => db.Set<TechMessage>()
|
||||
.Include(e => e.System);
|
||||
|
||||
public async Task<PaginationContainer<TechMessageDto>> GetPage(PaginationRequest request, CancellationToken token)
|
||||
|
@ -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,15 +10,16 @@ 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<TimestampedValues> GetQueryReadOnly() => this.db.Set<TimestampedValues>();
|
||||
protected IQueryable<TimestampedValues> GetQueryReadOnly() => db.Set<TimestampedValues>();
|
||||
|
||||
public async virtual Task<int> AddRange(Guid discriminatorId, IEnumerable<TimestampedValuesDto> dtos, CancellationToken token)
|
||||
public async Task<int> AddRange(Guid discriminatorId, IEnumerable<TimestampedValuesDto> dtos, CancellationToken token)
|
||||
{
|
||||
var timestampedValuesEntities = dtos.Select(dto => new TimestampedValues()
|
||||
{
|
||||
@ -25,35 +28,46 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||
Values = dto.Values.Values.ToArray()
|
||||
});
|
||||
|
||||
await db.Set<TimestampedValues>().AddRangeAsync(timestampedValuesEntities, token);
|
||||
await db.AddRangeAsync(timestampedValuesEntities, token);
|
||||
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async virtual Task<IDictionary<Guid, IEnumerable<(DateTimeOffset Timestamp, object[] Values)>>> Get(IEnumerable<Guid> discriminatorIds,
|
||||
DateTimeOffset? timestampBegin,
|
||||
public async Task<IDictionary<Guid, IEnumerable<(DateTimeOffset Timestamp, object[] Values)>>> Get(IEnumerable<Guid> discriminatorIds,
|
||||
DateTimeOffset? geTimestamp,
|
||||
TNode? filterTree,
|
||||
IEnumerable<string>? columnNames,
|
||||
int skip,
|
||||
int take,
|
||||
CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.Where(entity => discriminatorIds.Contains(entity.DiscriminatorId));
|
||||
|
||||
// Фильтрация по дате
|
||||
if (timestampBegin.HasValue)
|
||||
var resultQuery = Array.Empty<TimestampedValues>().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
|
||||
@ -62,7 +76,7 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||
return result;
|
||||
}
|
||||
|
||||
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetFirst(Guid discriminatorId, int takeCount, CancellationToken token)
|
||||
public async Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetFirst(Guid discriminatorId, int takeCount, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.OrderBy(e => e.Timestamp)
|
||||
@ -77,7 +91,7 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||
return result;
|
||||
}
|
||||
|
||||
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetLast(Guid discriminatorId, int takeCount, CancellationToken token)
|
||||
public async Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetLast(Guid discriminatorId, int takeCount, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.OrderByDescending(e => e.Timestamp)
|
||||
@ -93,7 +107,7 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||
}
|
||||
|
||||
// ToDo: прореживание должно осуществляться до материализации
|
||||
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetResampledData(
|
||||
public async Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetResampledData(
|
||||
Guid discriminatorId,
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
@ -114,10 +128,11 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||
return result;
|
||||
}
|
||||
|
||||
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
|
||||
public async Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> 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 => (
|
||||
@ -128,7 +143,7 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||
return result;
|
||||
}
|
||||
|
||||
public async virtual Task<DatesRangeDto?> GetDatesRange(Guid discriminatorId, CancellationToken token)
|
||||
public async Task<DatesRangeDto?> GetDatesRange(Guid discriminatorId, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.GroupBy(entity => entity.DiscriminatorId)
|
||||
@ -153,26 +168,12 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||
return dto;
|
||||
}
|
||||
|
||||
public virtual Task<int> Count(Guid discriminatorId, CancellationToken token)
|
||||
public async Task<int> Count(Guid discriminatorId, CancellationToken token)
|
||||
{
|
||||
var dbSet = db.Set<TimestampedValues>();
|
||||
var query = dbSet.Where(entity => entity.DiscriminatorId == discriminatorId);
|
||||
var query = GetQueryReadOnly()
|
||||
.Where(e => e.DiscriminatorId == discriminatorId);
|
||||
|
||||
return query.CountAsync(token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Применить фильтр по дате
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="timestampBegin"></param>
|
||||
/// <returns></returns>
|
||||
private IQueryable<TimestampedValues> ApplyGeTimestamp(IQueryable<TimestampedValues> query, DateTimeOffset timestampBegin)
|
||||
{
|
||||
var geTimestampUtc = timestampBegin.ToUniversalTime();
|
||||
|
||||
var result = query
|
||||
.Where(entity => entity.Timestamp >= geTimestampUtc);
|
||||
var result = await query.CountAsync(token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
using Ardalis.Specification;
|
||||
|
||||
namespace DD.Persistence.Database.Specifications;
|
||||
public class AndSpecification<TEntity> : Specification<TEntity>
|
||||
namespace DD.Persistence.Database.Specifications.Operation;
|
||||
public class AndSpec<TEntity> : Specification<TEntity>
|
||||
{
|
||||
public AndSpecification(ISpecification<TEntity> first, ISpecification<TEntity> second)
|
||||
public AndSpec(ISpecification<TEntity> first, ISpecification<TEntity> second)
|
||||
{
|
||||
if (first is null || second is null)
|
||||
return;
|
15
DD.Persistence.Database/Specifications/Operation/OrSpec.cs
Normal file
15
DD.Persistence.Database/Specifications/Operation/OrSpec.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using Ardalis.Specification;
|
||||
using DD.Persistence.Database.Postgres.Extensions;
|
||||
|
||||
namespace DD.Persistence.Database.Specifications.Operation;
|
||||
public class OrSpec<TEntity> : Specification<TEntity>
|
||||
{
|
||||
public OrSpec(ISpecification<TEntity> first, ISpecification<TEntity> second)
|
||||
{
|
||||
var orExpression = first.Or(second);
|
||||
if (orExpression == null)
|
||||
return;
|
||||
|
||||
Query.Where(orExpression);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
using Ardalis.Specification;
|
||||
using DD.Persistence.Database.Postgres.Extensions;
|
||||
|
||||
namespace DD.Persistence.Database.Specifications;
|
||||
public class OrSpecification<TEntity> : Specification<TEntity>
|
||||
{
|
||||
public OrSpecification(ISpecification<TEntity> first, ISpecification<TEntity> second)
|
||||
{
|
||||
var orExpression = first.Or(second);
|
||||
if (orExpression == null)
|
||||
return;
|
||||
|
||||
Query.Where(orExpression);
|
||||
}
|
||||
}
|
@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
|
||||
/// Спецификация эквивалентности значений IValuesItem в соответствии с индексацией
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class ValueEqaulSpecification<TEntity> : Specification<TEntity>
|
||||
public class ValueEqualSpec<TEntity> : Specification<TEntity>
|
||||
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);
|
||||
}
|
@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
|
||||
/// Спецификация "больше либо равно" для значений IValuesItem в соответствии с индексацией
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class ValueGreateOrEqualSpecification<TEntity> : Specification<TEntity>
|
||||
public class ValueGreateOrEqualSpec<TEntity> : Specification<TEntity>
|
||||
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);
|
||||
}
|
@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
|
||||
/// Спецификация "больше" для значений IValuesItem в соответствии с индексацией
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class ValueGreateSpecification<TEntity> : Specification<TEntity>
|
||||
public class ValueGreateSpec<TEntity> : Specification<TEntity>
|
||||
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);
|
||||
}
|
@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
|
||||
/// Спецификация "меньше либо равно" для значений IValuesItem в соответствии с индексацией
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class ValueLessOrEqualSpecification<TEntity> : Specification<TEntity>
|
||||
public class ValueLessOrEqualSpec<TEntity> : Specification<TEntity>
|
||||
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);
|
||||
}
|
@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
|
||||
/// Спецификация "меньше" для значений IValuesItem в соответствии с индексацией
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class ValueLessSpecification<TEntity> : Specification<TEntity>
|
||||
public class ValueLessSpec<TEntity> : Specification<TEntity>
|
||||
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);
|
||||
}
|
@ -7,15 +7,15 @@ namespace DD.Persistence.Database.Specifications.ValuesItem;
|
||||
/// Спецификация неравенства значений IValuesItem в соответствии с индексацией
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class ValueNotEqualSpecification<TEntity> : Specification<TEntity>
|
||||
public class ValueNotEqualSpec<TEntity> : Specification<TEntity>
|
||||
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);
|
||||
}
|
@ -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<ChangeLogValuesDto>();
|
||||
|
||||
@ -318,7 +318,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
var entities = dtos.Select(d =>
|
||||
{
|
||||
var entity = d.Adapt<ChangeLog>();
|
||||
entity.IdDiscriminator = idDiscriminator;
|
||||
entity.DiscriminatorId = idDiscriminator;
|
||||
entity.Creation = DateTimeOffset.UtcNow.AddDays(generatorRandomDigits.Next(minDayCount, maxDayCount));
|
||||
|
||||
return entity;
|
||||
|
@ -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);
|
||||
|
||||
try
|
||||
{
|
||||
//act
|
||||
var response = await timestampedValuesClient.Get([firstDiscriminatorId, secondDiscriminatorId], null, null, 0, 1, CancellationToken.None);
|
||||
var response = await timestampedValuesClient.Get([firstDiscriminatorId, secondDiscriminatorId], null, null, null, 0, 1, CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var expectedMessage = $"На сервере произошла ошибка, в результате которой он не может успешно обработать запрос";
|
||||
|
||||
//assert
|
||||
Assert.Null(response);
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -70,22 +77,25 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
|
||||
|
||||
var timestampBegin = DateTimeOffset.UtcNow.AddDays(-1);
|
||||
var columnNames = new List<string>() { "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;
|
||||
}
|
||||
|
@ -80,13 +80,10 @@ public class FilterBuilderShould
|
||||
.AsQueryable();
|
||||
|
||||
//act
|
||||
var specification = dataScheme.BuildFilter<TimestampedValues>(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<TimestampedValues>(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<TimestampedValues>(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);
|
||||
|
@ -9,7 +9,7 @@ public class TimestampedValuesServiceShould
|
||||
{
|
||||
private readonly ITimestampedValuesRepository timestampedValuesRepository = Substitute.For<ITimestampedValuesRepository>();
|
||||
private readonly ISchemePropertyRepository dataSchemeRepository = Substitute.For<ISchemePropertyRepository>();
|
||||
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);
|
||||
}
|
||||
|
@ -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")
|
||||
));
|
||||
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Абстрактная модель вершины
|
||||
/// </summary>
|
||||
public abstract class TNode
|
||||
|
||||
public abstract class TNode : IParsable<TNode?>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public TNode(OperationEnum operation)
|
||||
@ -18,6 +21,30 @@ public abstract class TNode
|
||||
/// </summary>
|
||||
public OperationEnum Operation { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static TNode? Parse(string s, IFormatProvider? provider)
|
||||
{
|
||||
var result = s.BuildTree();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Принять посетителя
|
||||
/// </summary>
|
||||
|
@ -62,15 +62,16 @@ abstract class TerminalExpression : IExpression
|
||||
|
||||
private static object? ParseValue(string value)
|
||||
{
|
||||
value = value.Replace('.', ',');
|
||||
if (value.Contains(',') && double.TryParse(value, out _))
|
||||
if (double.TryParse(value, out _))
|
||||
{
|
||||
return double.Parse(value);
|
||||
}
|
||||
|
||||
if (int.TryParse(value, out _))
|
||||
// ToDo: избавиться
|
||||
var doubleValue= value.Replace('.', ',');
|
||||
if (double.TryParse(doubleValue, out _))
|
||||
{
|
||||
return int.Parse(value);
|
||||
return double.Parse(doubleValue);
|
||||
}
|
||||
|
||||
value = value.Trim('\"');
|
||||
|
@ -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
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminators">Набор дискриминаторов (идентификаторов)</param>
|
||||
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
||||
/// <param name="filterTree"></param>
|
||||
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||
/// <param name="skip"></param>
|
||||
/// <param name="take"></param>
|
||||
@ -37,6 +39,7 @@ public interface ITimestampedValuesRepository : ISyncRepository, ITimeSeriesBase
|
||||
/// <returns></returns>
|
||||
Task<IDictionary<Guid, IEnumerable<(DateTimeOffset Timestamp, object[] Values)>>> Get(IEnumerable<Guid> idDiscriminators,
|
||||
DateTimeOffset? geTimestamp,
|
||||
TNode? filterTree,
|
||||
IEnumerable<string>? columnNames,
|
||||
int skip,
|
||||
int take,
|
||||
|
@ -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
|
||||
/// </summary>
|
||||
/// <param name="discriminatorIds">Набор дискриминаторов (идентификаторов)</param>
|
||||
/// <param name="geTimestamp"></param>
|
||||
/// <param name="filterTree"></param>
|
||||
/// <param name="columnNames"></param>
|
||||
/// <param name="skip"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp,
|
||||
IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
||||
TNode? filterTree, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение данных с начала
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, TNode? filterTree, IEnumerable<string>? 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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user