Skip to content

Commit cc32b10

Browse files
feat: supported Guid (Uuid YDB type) (#465)
* dev: update SLO EF test * Update CHANGELOG.md * Supported Guid * Fixed flap test in topic unit tests
1 parent cfeea1f commit cc32b10

File tree

8 files changed

+97
-34
lines changed

8 files changed

+97
-34
lines changed

.github/workflows/slo.yml

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,6 @@ on:
77
pull_request:
88
branches:
99
- main
10-
workflow_dispatch:
11-
inputs:
12-
github_pull_request_number:
13-
required: true
14-
slo_workload_duration_seconds:
15-
default: '600'
16-
required: false
17-
slo_workload_read_max_rps:
18-
default: '1000'
19-
required: false
20-
slo_workload_write_max_rps:
21-
default: '1000'
22-
required: false
2310

2411
jobs:
2512
ydb-slo-action:
@@ -32,7 +19,17 @@ jobs:
3219
workload:
3320
- AdoNet
3421
- Dapper
35-
# - EF
22+
- EF
23+
include:
24+
- workload: AdoNet
25+
read_rps: 1000
26+
write_rps: 1000
27+
- workload: Dapper
28+
read_rps: 1000
29+
write_rps: 1000
30+
- workload: EF
31+
read_rps: 400
32+
write_rps: 400
3633

3734
concurrency:
3835
group: slo-${{ github.ref }}-${{ matrix.workload }}
@@ -66,9 +63,9 @@ jobs:
6663
dotnet run run "Host=localhost;Port=2135;Database=/Root/testdb" \
6764
--prom-pgw http://localhost:9091 \
6865
--report-period 250 \
69-
--time ${{inputs.slo_workload_duration_seconds || 600 }} \
70-
--read-rps ${{inputs.slo_workload_read_max_rps || 1000 }} \
71-
--write-rps ${{inputs.slo_workload_write_max_rps || 1000 }} \
66+
--time 600 \
67+
--read-rps ${{matrix.read_rps || 1000 }} \
68+
--write-rps ${{matrix.write_rps || 1000 }} \
7269
--read-timeout 1000 \
7370
--write-timeout 1000
7471

slo/src/EF/SloTableContext.cs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
using System.Data;
12
using EntityFrameworkCore.Ydb.Extensions;
23
using Internal;
34
using Microsoft.EntityFrameworkCore;
45
using Microsoft.EntityFrameworkCore.Infrastructure;
56
using Ydb.Sdk;
7+
using Ydb.Sdk.Ado;
68

79
namespace EF;
810

@@ -29,9 +31,46 @@ int operationTimeout
2931
int writeTimeout
3032
)
3133
{
32-
await using var dbContext = await client.CreateDbContextAsync();
33-
dbContext.SloEntities.Add(sloTable);
34-
await dbContext.SaveChangesAsync();
34+
await using var context = await client.CreateDbContextAsync();
35+
var executeStrategy = context.Database.CreateExecutionStrategy();
36+
await executeStrategy.ExecuteAsync(async () =>
37+
{
38+
var dbContext = await client.CreateDbContextAsync();
39+
40+
return await dbContext.Database.ExecuteSqlRawAsync(
41+
$"UPSERT INTO `{SloTable.Name}` (Guid, Id, PayloadStr, PayloadDouble, PayloadTimestamp) " +
42+
"VALUES (@Guid, @Id, @PayloadStr, @PayloadDouble, @PayloadTimestamp)",
43+
new YdbParameter
44+
{
45+
DbType = DbType.Guid,
46+
ParameterName = "Guid",
47+
Value = sloTable.Guid
48+
},
49+
new YdbParameter
50+
{
51+
DbType = DbType.Int32,
52+
ParameterName = "Id",
53+
Value = sloTable.Id
54+
},
55+
new YdbParameter
56+
{
57+
DbType = DbType.String,
58+
ParameterName = "PayloadStr",
59+
Value = sloTable.PayloadStr
60+
},
61+
new YdbParameter
62+
{
63+
DbType = DbType.Double,
64+
ParameterName = "PayloadDouble",
65+
Value = sloTable.PayloadDouble
66+
},
67+
new YdbParameter
68+
{
69+
DbType = DbType.DateTime2,
70+
ParameterName = "PayloadTimestamp",
71+
Value = sloTable.PayloadTimestamp
72+
});
73+
});
3574

3675
return (1, StatusCode.Success);
3776
}
@@ -43,15 +82,14 @@ int readTimeout
4382
)
4483
{
4584
await using var dbContext = await client.CreateDbContextAsync();
46-
await dbContext.SloEntities.FindAsync(select.Guid, select.Id);
47-
48-
return (0, StatusCode.Success, null);
85+
return (0, StatusCode.Success,
86+
await dbContext.SloEntities.FirstOrDefaultAsync(table =>
87+
table.Guid == select.Guid && table.Id == select.Id));
4988
}
5089

5190
protected override async Task<int> SelectCount(PooledDbContextFactory<TableDbContext> client)
5291
{
5392
await using var dbContext = await client.CreateDbContextAsync();
54-
5593
return await dbContext.SloEntities.CountAsync();
5694
}
5795
}

src/EFCore.Ydb/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
- Supported Guid (Uuid YDB type).
12
- PrivateAssets="none" is set to flow the EF Core analyzer to users referencing this package [issue](https://github.com/aspnet/EntityFrameworkCore/pull/11350).
23

34
## v0.0.2

src/EFCore.Ydb/src/Storage/Internal/Mapping/YdbDecimalTypeMapping.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using Microsoft.EntityFrameworkCore.Storage;
32

43
namespace EntityFrameworkCore.Ydb.Storage.Internal.Mapping;
@@ -8,9 +7,11 @@ public class YdbDecimalTypeMapping : DecimalTypeMapping
87
private const byte DefaultPrecision = 22;
98
private const byte DefaultScale = 9;
109

11-
public YdbDecimalTypeMapping(Type? type) : this(
10+
public new static YdbDecimalTypeMapping Default => new();
11+
12+
public YdbDecimalTypeMapping() : this(
1213
new RelationalTypeMappingParameters(
13-
new CoreTypeMappingParameters(type ?? typeof(decimal)),
14+
new CoreTypeMappingParameters(typeof(decimal)),
1415
storeType: "Decimal",
1516
dbType: System.Data.DbType.Decimal
1617
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Microsoft.EntityFrameworkCore.Storage;
2+
3+
namespace EntityFrameworkCore.Ydb.Storage.Internal.Mapping;
4+
5+
public class YdbGuidTypeMapping : GuidTypeMapping
6+
{
7+
public new static YdbGuidTypeMapping Default => new();
8+
9+
private YdbGuidTypeMapping() : base("Uuid", System.Data.DbType.Guid)
10+
{
11+
}
12+
13+
protected YdbGuidTypeMapping(RelationalTypeMappingParameters parameters) : base(parameters)
14+
{
15+
}
16+
17+
protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters) =>
18+
new YdbGuidTypeMapping(parameters);
19+
20+
protected override string SqlLiteralFormatString => "Uuid('{0}')";
21+
}

src/EFCore.Ydb/src/Storage/Internal/YdbTypeMappingSource.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ RelationalTypeMappingSourceDependencies relationalDependencies
3030
private static readonly FloatTypeMapping Float = new("Float", DbType.Single);
3131
private static readonly DoubleTypeMapping Double = new("Double", DbType.Double);
3232

33-
private static readonly YdbDecimalTypeMapping Decimal = new(typeof(decimal));
33+
private static readonly YdbDecimalTypeMapping Decimal = YdbDecimalTypeMapping.Default;
34+
35+
private static readonly GuidTypeMapping Guid = YdbGuidTypeMapping.Default;
3436

3537
private static readonly YdbTextTypeMapping Text = YdbTextTypeMapping.Default;
3638
private static readonly YdbBytesTypeMapping Bytes = YdbBytesTypeMapping.Default;
@@ -64,6 +66,10 @@ RelationalTypeMappingSourceDependencies relationalDependencies
6466
{ "Float", [Float] },
6567
{ "Double", [Double] },
6668

69+
{ "Decimal", [Decimal] },
70+
71+
{ "Guid", [Guid] },
72+
6773
{ "Date", [Date] },
6874
{ "DateTime", [DateTime] },
6975
{ "Timestamp", [Timestamp] },
@@ -72,8 +78,6 @@ RelationalTypeMappingSourceDependencies relationalDependencies
7278
{ "Text", [Text] },
7379
{ "Bytes", [Bytes] },
7480

75-
{ "Decimal", [Decimal] },
76-
7781
{ "Json", [Json] }
7882
};
7983

@@ -95,6 +99,8 @@ RelationalTypeMappingSourceDependencies relationalDependencies
9599
{ typeof(double), Double },
96100
{ typeof(decimal), Decimal },
97101

102+
{ typeof(Guid), Guid },
103+
98104
{ typeof(string), Text },
99105
{ typeof(byte[]), Bytes },
100106
{ typeof(JsonElement), Json },

src/Ydb.Sdk/tests/Topic/ReaderUnitTests.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,14 +1086,13 @@ public async Task
10861086
Assert.Equal("Hello", batch.Batch[0].Data);
10871087
Assert.Equal("World!", batch.Batch[1].Data);
10881088

1089-
_mockStream.Verify(stream => stream.Write(It.IsAny<FromClient>()), Times.Between(11, 12, Range.Inclusive));
1089+
_mockStream.Verify(stream => stream.Write(It.IsAny<FromClient>()), Times.AtLeast(11));
10901090
_mockStream.Verify(stream => stream.MoveNextAsync(), Times.Between(8, 9, Range.Inclusive));
10911091
_mockStream.Verify(stream => stream.Current, Times.Exactly(7));
10921092

10931093
_mockStream.Verify(stream => stream.Write(It.Is<FromClient>(msg =>
1094-
msg.InitRequest != null &&
1095-
msg.InitRequest.Consumer == "Consumer" &&
1096-
msg.InitRequest.TopicsReadSettings[0].Path == "/topic")), Times.Exactly(2));
1094+
msg.InitRequest != null && msg.InitRequest.Consumer == "Consumer" &&
1095+
msg.InitRequest.TopicsReadSettings[0].Path == "/topic")), Times.Between(2, 3, Range.Inclusive));
10971096
_mockStream.Verify(stream => stream.Write(It.Is<FromClient>(msg =>
10981097
msg.ReadRequest != null && msg.ReadRequest.BytesSize == 100)), Times.Exactly(2));
10991098
_mockStream.Verify(stream => stream.Write(It.Is<FromClient>(msg =>

0 commit comments

Comments
 (0)