Created
July 6, 2023 10:19
-
-
Save robie2011/1d2ae29b716b15ec9e1b7e720afcb879 to your computer and use it in GitHub Desktop.
RxDb Sync Poco
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Immutable; | |
namespace RxDbSyncTests; | |
public static class Models | |
{ | |
public record Entry( | |
int Id, | |
int Value, | |
DateTime CreatedAt, | |
DateTime? UpdatedAt); | |
public record QueryResult(IReadOnlyList<Entry> Entries) | |
{ | |
public int Count => Entries.Count; | |
public DateTime MaxChangeStamp | |
=> Entries | |
.Select(x => x.CreatedAt) | |
.Concat( | |
Entries | |
.Select(x => x.UpdatedAt) | |
.Where(x => x is { }) | |
.Cast<DateTime>()) | |
.Max(); | |
} | |
public class Table | |
{ | |
private readonly List<Entry> _entries = new(); | |
private int _autoIncrement = 1; | |
public void Add(int value) | |
=> _entries.Add(new Entry( | |
_autoIncrement++, | |
value, | |
CreatedAt: DateTime.Now, | |
UpdatedAt: null)); | |
public void Delete(int id) | |
=> _entries.Remove(_entries.Find(x => x.Id == id)!); | |
public void Update(int id, int value) | |
{ | |
var ix = _entries.FindIndex(e => e.Id == id)!; | |
_entries[ix] = _entries[ix] with | |
{ | |
Value = value, | |
UpdatedAt = DateTime.Now | |
}; | |
} | |
public QueryResult Query() | |
=> new(_entries.ToImmutableList()); | |
public int CountDeletedEntries(DateTime lastObservationTime, int lastQueryObservedCount) | |
=> lastQueryObservedCount - _entries | |
.Count(x => x.CreatedAt <= lastObservationTime); | |
public bool IsDeletionHappened(DateTime lastObservationTime, int lastQueryObservedCount) | |
=> CountDeletedEntries(lastObservationTime, lastQueryObservedCount) != lastQueryObservedCount; | |
public IReadOnlyList<Entry> GetUpdatedEntries(DateTime lastObservationTime) | |
=> _entries | |
.Where(x => x.CreatedAt > lastObservationTime | |
|| x.UpdatedAt > lastObservationTime) | |
.ToImmutableList(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using FluentAssertions; | |
namespace RxDbSyncTests; | |
public class SyncTests | |
{ | |
[Fact] | |
public void IsDeletionHappened() | |
{ | |
var table = GetExampleTable(); | |
var query0 = table.Query(); | |
// do some update | |
table.Update(query0.Entries[0].Id, 31); | |
table | |
.IsDeletionHappened(lastQueryObservedCount: query0.Count, lastObservationTime: query0.MaxChangeStamp) | |
.Should().BeFalse(); | |
// create some entries | |
table.Add(92); | |
table | |
.IsDeletionHappened(lastQueryObservedCount: query0.Count, lastObservationTime: query0.MaxChangeStamp) | |
.Should().BeFalse(); | |
// adding and then removing entries do not affect check operation | |
table.Add(41); | |
table.Delete(table.Query().Entries[^1].Id); | |
table | |
.IsDeletionHappened(lastQueryObservedCount: query0.Count, lastObservationTime: query0.MaxChangeStamp) | |
.Should().BeFalse(); | |
// do some deletion | |
table.Delete(query0.Entries[0].Id); | |
table | |
.IsDeletionHappened(lastQueryObservedCount: query0.Count, lastObservationTime: query0.MaxChangeStamp) | |
.Should().BeTrue(); | |
} | |
[Fact] | |
public void GetUpdateEntries() | |
{ | |
var table = GetExampleTable(); | |
var query0 = table.Query(); | |
table.GetUpdatedEntries(lastObservationTime: query0.MaxChangeStamp) | |
.Should() | |
.BeEmpty(); | |
// adding and then removing keep it in neutral state | |
table.Add(41); | |
table.Delete(table.Query().Entries[^1].Id); | |
table.GetUpdatedEntries(lastObservationTime: query0.MaxChangeStamp) | |
.Should() | |
.BeEmpty(); | |
// adding new entries | |
table.Add(13); | |
table.Add(124); | |
table.GetUpdatedEntries(lastObservationTime: query0.MaxChangeStamp) | |
.Select(x => x.Value) | |
.Should().BeEquivalentTo(new[] { 13, 124 }); | |
// delete operation do not affect GetUpdatedEntries-query | |
table.Delete(query0.Entries[0].Id); | |
table.GetUpdatedEntries(lastObservationTime: query0.MaxChangeStamp) | |
.Select(x => x.Value) | |
.Should().BeEquivalentTo(new[] { 13, 124 }); | |
// updating entries | |
table.Update(table.Query().Entries[0].Id, 140); | |
table.GetUpdatedEntries(lastObservationTime: query0.MaxChangeStamp) | |
.Select(x => x.Value) | |
.Should().BeEquivalentTo(new[] { 140, 13, 124 }); | |
// updating multiple times | |
table.Update(table.Query().Entries[0].Id, 140); | |
table.Update(table.Query().Entries[0].Id, 140); | |
table.GetUpdatedEntries(lastObservationTime: query0.MaxChangeStamp) | |
.Select(x => x.Value) | |
.Should().BeEquivalentTo(new[] { 140, 13, 124 }); | |
// entry was updated in mean time and then deleted: no updates received | |
table.Update(table.Query().Entries[0].Id, 140); | |
table.Delete(table.Query().Entries[0].Id); | |
table.GetUpdatedEntries(lastObservationTime: query0.MaxChangeStamp) | |
.Select(x => x.Value) | |
.Should().BeEquivalentTo(new[] { 13, 124 }); | |
} | |
private static Models.Table GetExampleTable() | |
{ | |
var table = new Models.Table(); | |
table.Add(2); | |
table.Add(19); | |
table.Add(4); | |
return table; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment