Skip to content

Instantly share code, notes, and snippets.

@robie2011
Created July 6, 2023 10:19
Show Gist options
  • Save robie2011/1d2ae29b716b15ec9e1b7e720afcb879 to your computer and use it in GitHub Desktop.
Save robie2011/1d2ae29b716b15ec9e1b7e720afcb879 to your computer and use it in GitHub Desktop.
RxDb Sync Poco
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();
}
}
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