110 lines
3.1 KiB
C#
110 lines
3.1 KiB
C#
using System;
|
|
using Svrnty.CQRS.Events.Abstractions.Schema;
|
|
using Svrnty.CQRS.Events.Abstractions.Models;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Svrnty.CQRS.Events.Abstractions;
|
|
|
|
namespace Svrnty.CQRS.Events.InMemory;
|
|
|
|
/// <summary>
|
|
/// In-memory implementation of <see cref="ISchemaStore"/> for testing and development.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This implementation stores schemas in memory and is suitable for:
|
|
/// - Unit tests
|
|
/// - Integration tests
|
|
/// - Development environments
|
|
/// - Single-instance deployments (no distributed systems)
|
|
/// </remarks>
|
|
public sealed class InMemorySchemaStore : ISchemaStore
|
|
{
|
|
private readonly ConcurrentDictionary<string, SchemaInfo> _schemas = new();
|
|
|
|
public Task StoreSchemaAsync(
|
|
SchemaInfo schema,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
schema.Validate();
|
|
|
|
var key = GetKey(schema.EventType, schema.Version);
|
|
|
|
if (!_schemas.TryAdd(key, schema))
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Schema for {schema.EventType} v{schema.Version} already exists");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<SchemaInfo?> GetSchemaAsync(
|
|
string eventType,
|
|
int version,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var key = GetKey(eventType, version);
|
|
_schemas.TryGetValue(key, out var schema);
|
|
return Task.FromResult(schema);
|
|
}
|
|
|
|
public Task<IReadOnlyList<SchemaInfo>> GetSchemaHistoryAsync(
|
|
string eventType,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var schemas = _schemas.Values
|
|
.Where(s => s.EventType == eventType)
|
|
.OrderBy(s => s.Version)
|
|
.ToList();
|
|
|
|
return Task.FromResult<IReadOnlyList<SchemaInfo>>(schemas);
|
|
}
|
|
|
|
public Task<int?> GetLatestVersionAsync(
|
|
string eventType,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var latestVersion = _schemas.Values
|
|
.Where(s => s.EventType == eventType)
|
|
.Select(s => (int?)s.Version)
|
|
.DefaultIfEmpty(null)
|
|
.Max();
|
|
|
|
return Task.FromResult(latestVersion);
|
|
}
|
|
|
|
public Task<IReadOnlyList<string>> GetAllEventTypesAsync(
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var eventTypes = _schemas.Values
|
|
.Select(s => s.EventType)
|
|
.Distinct()
|
|
.OrderBy(x => x)
|
|
.ToList();
|
|
|
|
return Task.FromResult<IReadOnlyList<string>>(eventTypes);
|
|
}
|
|
|
|
public Task<bool> SchemaExistsAsync(
|
|
string eventType,
|
|
int version,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var key = GetKey(eventType, version);
|
|
return Task.FromResult(_schemas.ContainsKey(key));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears all schemas (for testing).
|
|
/// </summary>
|
|
public void Clear()
|
|
{
|
|
_schemas.Clear();
|
|
}
|
|
|
|
private static string GetKey(string eventType, int version) => $"{eventType}:v{version}";
|
|
}
|