LiteDbOfflineSyncHeadStore.cs
1 using GUNRPG.Application.Backend; 2 using LiteDB; 3 4 namespace GUNRPG.Infrastructure.Persistence; 5 6 public sealed class LiteDbOfflineSyncHeadStore : IOfflineSyncHeadStore 7 { 8 private readonly ILiteCollection<OfflineSyncHeadDocument> _heads; 9 private readonly object _syncLock = new(); 10 11 public LiteDbOfflineSyncHeadStore(LiteDatabase database) 12 { 13 _heads = database.GetCollection<OfflineSyncHeadDocument>("offline_sync_heads"); 14 _heads.EnsureIndex(x => x.OperatorId, true); 15 } 16 17 public Task<OfflineSyncHead?> GetAsync(Guid operatorId) 18 { 19 lock (_syncLock) 20 { 21 var doc = _heads.FindById(operatorId.ToString()); 22 if (doc == null) 23 { 24 return Task.FromResult<OfflineSyncHead?>(null); 25 } 26 27 return Task.FromResult<OfflineSyncHead?>(new OfflineSyncHead 28 { 29 OperatorId = doc.OperatorId, 30 SequenceNumber = doc.SequenceNumber, 31 ResultOperatorStateHash = doc.ResultOperatorStateHash 32 }); 33 } 34 } 35 36 public Task UpsertAsync(OfflineSyncHead head) 37 { 38 lock (_syncLock) 39 { 40 _heads.Upsert(new OfflineSyncHeadDocument 41 { 42 Id = head.OperatorId.ToString(), 43 OperatorId = head.OperatorId, 44 SequenceNumber = head.SequenceNumber, 45 ResultOperatorStateHash = head.ResultOperatorStateHash 46 }); 47 } 48 49 return Task.CompletedTask; 50 } 51 52 private sealed class OfflineSyncHeadDocument 53 { 54 public string Id { get; init; } = string.Empty; 55 public Guid OperatorId { get; init; } 56 public long SequenceNumber { get; init; } 57 public string ResultOperatorStateHash { get; init; } = string.Empty; 58 } 59 }