using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using ZB.MOM.WW.LocalDb; namespace ZB.MOM.WW.ScadaBridge.SiteEventLogging.Tests; /// /// A real over a temp file, for tests that construct a /// directly. /// /// /// /// takes rather than a connection /// string, and there is no in-memory mode — LocalDbOptions.Path is a filesystem /// path. A real one is used rather than a stub on purpose: connections handed out by /// ILocalDb carry the zb_hlc_next() UDF that site_events' capture /// triggers call, so a stub returning a bare SqliteConnection would pass these /// tests while failing closed the moment the table is registered for replication. /// /// /// No onReady callback and no RegisterReplicated: the logger's own /// InitializeSchema creates the table, which is what keeps a directly-constructed /// logger self-sufficient. Registration is the host's job /// (SiteLocalDbSetup.OnReady). /// /// public sealed class TestLocalDb : IDisposable { private readonly ServiceProvider _provider; private TestLocalDb(ServiceProvider provider, ILocalDb db) { _provider = provider; Db = db; } /// The live local database. public ILocalDb Db { get; } /// Opens a local database at . public static TestLocalDb Create(string databasePath) { var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["LocalDb:Path"] = databasePath, }) .Build(); var provider = new ServiceCollection() .AddZbLocalDb(configuration) .BuildServiceProvider(); return new TestLocalDb(provider, provider.GetRequiredService()); } /// /// Deletes and its WAL sidecars. Call only after the /// owning is disposed — the master connection anchors the WAL. /// public static void DeleteFiles(string databasePath) { foreach (var suffix in new[] { "", "-wal", "-shm" }) { try { File.Delete(databasePath + suffix); } catch { /* best effort */ } } } public void Dispose() => _provider.Dispose(); }