Skip to content

Commit f1dda9b

Browse files
Entity Framework Support (#108)
1 parent 483eff1 commit f1dda9b

37 files changed

+595
-216
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ jobs:
2525
# Windows
2626
- build: win-x64
2727
os: windows-latest
28+
test: --filter Category!=Docker
2829

2930
# Linux
3031
- build: linux-x64
@@ -36,6 +37,7 @@ jobs:
3637
# macOS
3738
- build: macos-aarch64
3839
os: macos-latest
40+
test: --filter Category!=Docker
3941

4042
steps:
4143
- name: Checkout
@@ -63,6 +65,6 @@ jobs:
6365

6466
- name: Run tests server
6567
run: |
66-
dotnet test Tests/YDotNet.Tests.Server.Unit
68+
dotnet test Tests/YDotNet.Tests.Server.Unit ${{ matrix.test }}
6769
env:
6870
RUST_BACKTRACE: 1

Demo/Callback.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,8 @@
55

66
namespace Demo;
77

8-
public sealed class Callback : IDocumentCallback
8+
public sealed class Callback(ILogger<Callback> log) : IDocumentCallback
99
{
10-
private readonly ILogger<Callback> log;
11-
12-
public Callback(ILogger<Callback> log)
13-
{
14-
this.log = log;
15-
}
16-
1710
public ValueTask OnAwarenessUpdatedAsync(ClientAwarenessEvent @event)
1811
{
1912
log.LogInformation("Client {clientId} awareness changed.", @event.Context.ClientId);

Demo/Db/AppDbContext.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using YDotNet.Server.EntityFramework;
3+
4+
namespace Demo.Db;
5+
6+
public class AppDbContext(DbContextOptions options) : DbContext(options)
7+
{
8+
protected override void OnModelCreating(ModelBuilder modelBuilder)
9+
{
10+
modelBuilder.UseYDotNet();
11+
base.OnModelCreating(modelBuilder);
12+
}
13+
}

Demo/Db/DbInitializer.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
using Microsoft.EntityFrameworkCore;
3+
using Microsoft.EntityFrameworkCore.Infrastructure;
4+
using Microsoft.EntityFrameworkCore.Storage;
5+
6+
namespace Demo.Db;
7+
8+
public class DbInitializer(IDbContextFactory<AppDbContext> dbContextFactory) : IHostedService
9+
{
10+
public async Task StartAsync(CancellationToken cancellationToken)
11+
{
12+
await using var context = await dbContextFactory.CreateDbContextAsync(cancellationToken);
13+
14+
var creator = (RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>();
15+
await creator.EnsureCreatedAsync(cancellationToken);
16+
}
17+
18+
public Task StopAsync(CancellationToken cancellationToken)
19+
{
20+
return Task.CompletedTask;
21+
}
22+
}

Demo/Program.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
using Demo.Db;
2+
using Microsoft.EntityFrameworkCore;
13
using MongoDB.Driver;
24
using StackExchange.Redis;
35
using YDotNet.Server;
6+
using YDotNet.Server.EntityFramework;
47
using YDotNet.Server.MongoDB;
58

69
namespace Demo;
@@ -50,6 +53,20 @@ public static void Main(string[] args)
5053
builder.Configuration["Storage:Redis:ConnectionString"]!);
5154
});
5255

56+
break;
57+
}
58+
59+
case "Postgres":
60+
{
61+
builder.Services.AddHostedService<DbInitializer>();
62+
builder.Services.AddDbContext<AppDbContext>(options =>
63+
{
64+
options.UseNpgsql(
65+
builder.Configuration["Storage:Postgres:ConnectionString"]!);
66+
});
67+
68+
yDotNet.AddEntityFrameworkStorage<AppDbContext>();
69+
5370
break;
5471
}
5572
}

Demo/appsettings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
},
1616
"Redis": {
1717
"ConnectionString": "localhost:6379"
18+
},
19+
"Postgres": {
20+
"ConnectionString": "Host=localhost;Port=5432;Database=ydotnet;Username=postgres;Password=password"
1821
}
1922
}
2023
}

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<PackageReadmeFile>README.md</PackageReadmeFile>
1212
<PublishRepositoryUrl>true</PublishRepositoryUrl>
1313
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
14-
<Version>0.4.1</Version>
14+
<Version>0.4.2</Version>
1515
</PropertyGroup>
1616

1717
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">

Tests/YDotNet.Tests.Server.Unit/DelayedWriterTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
namespace YDotNet.Tests.Server.Unit;
2+
13
using NUnit.Framework;
24
using YDotNet.Server.Internal;
35

4-
namespace YDotNet.Tests.Server.Unit;
5-
66
public class DelayedWriterTests
77
{
88
[Test]
@@ -81,6 +81,7 @@ public async Task WriteAfterDelayOnce()
8181
{
8282
sut.Ping();
8383
}
84+
8485
await Task.Delay(300);
8586

8687
// Assert

Tests/YDotNet.Tests.Server.Unit/DocumentContainerTests.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
namespace YDotNet.Tests.Server.Unit;
2+
13
using FakeItEasy;
24
using Microsoft.Extensions.Logging;
35
using NUnit.Framework;
@@ -6,8 +8,6 @@
68
using YDotNet.Server.Internal;
79
using YDotNet.Server.Storage;
810

9-
namespace YDotNet.Tests.Server.Unit;
10-
1111
public class DocumentContainerTests
1212
{
1313
private readonly IDocumentStorage documentStorage = A.Fake<IDocumentStorage>();
@@ -31,7 +31,7 @@ await sut.ApplyUpdateReturnAsync(async doc =>
3131
map.Insert(transaction, "key", Input.Double(42));
3232
}
3333

34-
await Task.Delay(100);
34+
await Task.Delay(100).ConfigureAwait(false);
3535
return true;
3636
});
3737

@@ -43,7 +43,12 @@ private DocumentContainer CreateSut(DocumentManagerOptions? options)
4343
{
4444
options ??= new DocumentManagerOptions();
4545

46-
return new DocumentContainer(name, documentStorage, documentCallback, documentManager, options,
46+
return new DocumentContainer(
47+
name,
48+
documentStorage,
49+
documentCallback,
50+
documentManager,
51+
options,
4752
A.Fake<ILogger>());
4853
}
4954
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
namespace YDotNet.Tests.Server.Unit;
2+
3+
using NUnit.Framework;
4+
using YDotNet.Server.Storage;
5+
6+
public abstract class DocumentStorageTests
7+
{
8+
protected abstract IDocumentStorage CreateSut();
9+
10+
[Test]
11+
public async Task GetDocData()
12+
{
13+
// Arrange
14+
var sut = CreateSut();
15+
16+
// Act
17+
var received = await sut.GetDocAsync(Guid.NewGuid().ToString());
18+
19+
// Assert
20+
Assert.That(received, Is.Null);
21+
}
22+
23+
[Test]
24+
public async Task InsertDocument()
25+
{
26+
// Arrange
27+
var sut = CreateSut();
28+
29+
var docName = Guid.NewGuid().ToString();
30+
var docData = new byte[] { 1, 2, 3, 4 };
31+
32+
// Act
33+
await sut.StoreDocAsync(docName, docData);
34+
35+
// Assert
36+
var received = await sut.GetDocAsync(docName);
37+
38+
Assert.That(received, Is.EqualTo(docData));
39+
}
40+
41+
[Test]
42+
public async Task UpdateDocument()
43+
{
44+
// Arrange
45+
var sut = CreateSut();
46+
47+
var docName = Guid.NewGuid().ToString();
48+
var docData1 = new byte[] { 1, 2, 3, 4 };
49+
var docData2 = new byte[] { 5, 6, 7, 8 };
50+
51+
// Act
52+
await sut.StoreDocAsync(docName, docData1);
53+
await sut.StoreDocAsync(docName, docData2);
54+
55+
// Assert
56+
var received = await sut.GetDocAsync(docName);
57+
58+
Assert.That(received, Is.EqualTo(docData2));
59+
}
60+
}

0 commit comments

Comments
 (0)