Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/EventTests/AllDatabasesDefaultTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Threading;
using System.Threading.Tasks;
using JasperFx.Descriptors;
using JasperFx.Events;
using JasperFx.Events.Daemon;
using JasperFx.Events.Descriptors;
using Microsoft.Extensions.Logging;
using Shouldly;

namespace EventTests;

public class AllDatabasesDefaultTests
{
// A bare IEventStore that does NOT override AllDatabases(), so the call below exercises the
// default interface implementation added for jasperfx#387 (the "return empty array" stand-in
// for stores that don't yet expose their databases store-agnostically). Everything else throws —
// those members are never invoked here.
private sealed class BareEventStore : IEventStore
{
public Task<EventStoreUsage?> TryCreateUsage(CancellationToken token) => throw new NotImplementedException();
public Uri Subject => throw new NotImplementedException();

public ValueTask<IProjectionDaemon> BuildProjectionDaemonAsync(
string? tenantIdOrDatabaseIdentifier = null, ILogger? logger = null)
=> throw new NotImplementedException();

public ValueTask<IProjectionDaemon> BuildProjectionDaemonAsync(DatabaseId id)
=> throw new NotImplementedException();

public Meter Meter => throw new NotImplementedException();
public ActivitySource ActivitySource => throw new NotImplementedException();
public string MetricsPrefix => throw new NotImplementedException();
public DatabaseCardinality DatabaseCardinality => throw new NotImplementedException();
public bool HasMultipleTenants => throw new NotImplementedException();
public EventStoreIdentity Identity => throw new NotImplementedException();
public IReadOnlyEventStore OpenReadOnlyEventStore() => throw new NotImplementedException();

public Task CompactStreamAsync(Guid streamId, CancellationToken token = default)
=> throw new NotImplementedException();

public Task CompactStreamAsync(string streamKey, CancellationToken token = default)
=> throw new NotImplementedException();
}

private readonly IEventStore theStore = new BareEventStore();

[Fact]
public async Task all_databases_default_returns_empty()
{
var databases = await theStore.AllDatabases();
databases.ShouldBeEmpty();
}
}
13 changes: 12 additions & 1 deletion src/JasperFx.Events/IEventStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,18 @@ ValueTask<IProjectionDaemon> BuildProjectionDaemonAsync(

DatabaseCardinality DatabaseCardinality { get; }
bool HasMultipleTenants { get; }


/// <summary>
/// Resolve every <see cref="IEventDatabase" /> backing this event store, store-agnostically.
/// This is the store-neutral counterpart to Marten's <c>IMartenStorage.AllDatabases()</c> — it lets
/// monitoring/tooling code (e.g. CritterWatch) obtain an <see cref="IEventDatabase" /> to call the read
/// abstractions (<c>AllProjectionProgress</c>, <c>FetchDeadLetterCountsAsync</c>, <c>CountDeadLetterEventsAsync</c>)
/// without referencing concrete store types. The default implementation returns an empty array as a
/// stand-in; event stores should override this to return their real databases. See jasperfx#387.
/// </summary>
ValueTask<IReadOnlyList<IEventDatabase>> AllDatabases()
=> ValueTask.FromResult<IReadOnlyList<IEventDatabase>>([]);

/// <summary>
/// Identifies the event store within an application
/// </summary>
Expand Down
Loading