Each insert, delete and rescore update was its own commit to disk, so a resync of about a thousand QSOs froze the window thread. LogStore has a new Batch() scope that commits its writes together. ContestSession uses it in AddRangeFromNetwork, ClearFromNetwork and Rescore. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
73 lines
2.1 KiB
C#
73 lines
2.1 KiB
C#
using Nonemm.Core;
|
|
using Nonemm.Storage;
|
|
|
|
namespace Nonemm.Session.Tests;
|
|
|
|
/// A log store that keeps everything in memory, so session tests do not need a
|
|
/// file. It keeps the one rule the sqlite store enforces: no two contacts with
|
|
/// the same call in the same second.
|
|
public sealed class FakeLogStore : LogStore
|
|
{
|
|
private readonly List<Qso> qsos = [];
|
|
private readonly List<ContestInstance> contests = [];
|
|
private readonly List<ContestDefinition> definitions = [];
|
|
|
|
public IReadOnlyList<ContestDefinition> Definitions => definitions;
|
|
|
|
public void SaveContestDefinition(ContestDefinition definition) =>
|
|
definitions.Add(definition);
|
|
|
|
public IReadOnlyList<ContestInstance> Contests() => contests;
|
|
|
|
public ContestInstance? Contest(int contestNumber) =>
|
|
contests.FirstOrDefault(c => c.ContestNumber == contestNumber);
|
|
|
|
public ContestInstance AddContest(ContestInstance instance)
|
|
{
|
|
ContestInstance stored = instance with { ContestNumber = contests.Count + 1 };
|
|
contests.Add(stored);
|
|
return stored;
|
|
}
|
|
|
|
public void UpdateContest(ContestInstance instance)
|
|
{
|
|
int at = contests.FindIndex(c => c.ContestNumber == instance.ContestNumber);
|
|
contests[at] = instance;
|
|
}
|
|
|
|
public IReadOnlyList<Qso> Qsos(int contestNumber) =>
|
|
qsos.Where(q => q.ContestNumber == contestNumber).OrderBy(q => q.TimestampUtc).ToList();
|
|
|
|
public Qso Add(Qso qso)
|
|
{
|
|
Qso candidate = qso;
|
|
while (qsos.Any(q => q.Call.Text == candidate.Call.Text && q.TimestampUtc == candidate.TimestampUtc))
|
|
{
|
|
candidate = candidate with { TimestampUtc = candidate.TimestampUtc.AddSeconds(1) };
|
|
}
|
|
qsos.Add(candidate);
|
|
return candidate;
|
|
}
|
|
|
|
public void Update(Qso qso)
|
|
{
|
|
int at = qsos.FindIndex(q => q.Id == qso.Id);
|
|
qsos[at] = qso;
|
|
}
|
|
|
|
public void Delete(string id) => qsos.RemoveAll(q => q.Id == id);
|
|
|
|
public IDisposable Batch() => new NoBatch();
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
private sealed class NoBatch : IDisposable
|
|
{
|
|
public void Dispose()
|
|
{
|
|
}
|
|
}
|
|
}
|