-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGameDocumentStore.cs
More file actions
133 lines (119 loc) · 5.03 KB
/
GameDocumentStore.cs
File metadata and controls
133 lines (119 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using EntglDb.Core;
using EntglDb.Core.Network;
using EntglDb.Core.Storage;
using EntglDb.Core.Sync;
using EntglDb.Persistence.BLite;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace EntglDb.Demo.Game;
public class GameDocumentStore : BLiteDocumentStore<GameDbContext>
{
private const string HeroesCollection = "Heroes";
private const string BattleLogsCollection = "BattleLogs";
public GameDocumentStore(
GameDbContext context,
EntglDbMetaContext metaContext,
IPeerNodeConfigurationProvider configProvider,
IVectorClockService vectorClockService,
IPendingChangesService pendingChangesService,
ILogger<GameDocumentStore>? logger = null)
: base(context, metaContext, configProvider, vectorClockService, pendingChangesService, new LastWriteWinsConflictResolver(), logger)
{
WatchCollection(HeroesCollection, context.Heroes, h => h.Id);
WatchCollection(BattleLogsCollection, context.BattleLogs, b => b.Id);
}
protected override async Task ApplyContentToEntityAsync(
string collection, string key, JsonElement content, CancellationToken cancellationToken)
{
await UpsertEntityAsync(collection, key, content);
await _context.SaveChangesAsync(cancellationToken);
}
protected override async Task ApplyContentToEntitiesBatchAsync(
IEnumerable<(string Collection, string Key, JsonElement Content)> documents, CancellationToken cancellationToken)
{
foreach (var (collection, key, content) in documents)
await UpsertEntityAsync(collection, key, content);
await _context.SaveChangesAsync(cancellationToken);
}
private async Task UpsertEntityAsync(string collection, string key, JsonElement content)
{
switch (collection)
{
case HeroesCollection:
var hero = content.Deserialize<Hero>()!;
hero.Id = key;
if (await _context.Heroes.FindByIdAsync(key) != null)
await _context.Heroes.UpdateAsync(hero);
else
await _context.Heroes.InsertAsync(hero);
break;
case BattleLogsCollection:
var log = content.Deserialize<BattleLog>()!;
log.Id = key;
if (await _context.BattleLogs.FindByIdAsync(key) != null)
await _context.BattleLogs.UpdateAsync(log);
else
await _context.BattleLogs.InsertAsync(log);
break;
default:
throw new NotSupportedException($"Collection '{collection}' is not supported.");
}
}
protected override async Task<JsonElement?> GetEntityAsJsonAsync(
string collection, string key, CancellationToken cancellationToken)
{
return collection switch
{
HeroesCollection => SerializeEntity(await _context.Heroes.FindByIdAsync(key)),
BattleLogsCollection => SerializeEntity(await _context.BattleLogs.FindByIdAsync(key)),
_ => null
};
}
protected override async Task RemoveEntityAsync(
string collection, string key, CancellationToken cancellationToken)
{
await DeleteEntityAsync(collection, key);
await _context.SaveChangesAsync(cancellationToken);
}
protected override async Task RemoveEntitiesBatchAsync(
IEnumerable<(string Collection, string Key)> documents, CancellationToken cancellationToken)
{
foreach (var (collection, key) in documents)
await DeleteEntityAsync(collection, key);
await _context.SaveChangesAsync(cancellationToken);
}
private async Task DeleteEntityAsync(string collection, string key)
{
switch (collection)
{
case HeroesCollection:
await _context.Heroes.DeleteAsync(key);
break;
case BattleLogsCollection:
await _context.BattleLogs.DeleteAsync(key);
break;
}
}
protected override async Task<IEnumerable<(string Key, JsonElement Content)>> GetAllEntitiesAsJsonAsync(
string collection, CancellationToken cancellationToken)
{
var results = new List<(string Key, JsonElement Content)>();
switch (collection)
{
case HeroesCollection:
await foreach (var h in _context.Heroes.FindAllAsync())
results.Add((h.Id, SerializeEntity(h)!.Value));
break;
case BattleLogsCollection:
await foreach (var b in _context.BattleLogs.FindAllAsync())
results.Add((b.Id, SerializeEntity(b)!.Value));
break;
}
return results;
}
private static JsonElement? SerializeEntity<T>(T? entity) where T : class
{
if (entity == null) return null;
return JsonSerializer.SerializeToElement(entity);
}
}