diff --git a/Directory.Build.props b/Directory.Build.props index 5cd567c..0925be3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,7 +11,7 @@ https://github.com/squidex/squidex true snupkg - 6.30.0 + 6.31.0 diff --git a/events/Squidex.Events.Mongo/FilterBuilder.cs b/events/Squidex.Events.Mongo/FilterBuilder.cs index 3d11330..314dfb3 100644 --- a/events/Squidex.Events.Mongo/FilterBuilder.cs +++ b/events/Squidex.Events.Mongo/FilterBuilder.cs @@ -44,12 +44,22 @@ public static FilterDefinition ByStream(StreamFilter filter) if (filter.Kind == StreamFilterKind.MatchStart) { - return builder.Or(filter.Prefixes.Select(p => builder.Regex(x => x.EventStream, $"^{p}"))); + return builder.Or(filter.Prefixes.Select(p => Buildregex(p, builder))); } return builder.In(x => x.EventStream, filter.Prefixes); } + private static FilterDefinition Buildregex(string prefix, FilterDefinitionBuilder builder) + { + if (prefix.StartsWith('%')) + { + prefix = $"([a-zA-Z0-9]+){prefix[1..]}"; + } + + return builder.Regex(x => x.EventStream, $"^{prefix}"); + } + public static FilterDefinition>? ByChangeInStream(StreamFilter filter) { var builder = Builders>.Filter; diff --git a/events/Squidex.Events.Tests/EventStoreTests.cs b/events/Squidex.Events.Tests/EventStoreTests.cs index 6331022..8e4a917 100644 --- a/events/Squidex.Events.Tests/EventStoreTests.cs +++ b/events/Squidex.Events.Tests/EventStoreTests.cs @@ -417,11 +417,12 @@ public async Task Should_query_all_reverse_by_names(int commits, int count) [InlineData(5, 30)] [InlineData(5, 300)] [InlineData(5, 3000)] - public async Task Should_query_all_reverse_by_filter(int commits, int count) + public async Task Should_query_all_reverse_by_prefix(int commits, int count) { var sut = await CreateSutAsync(); - var streamName = $"test-{Guid.NewGuid()}-suffix"; + var randomPart = Guid.NewGuid(); + var streamName = $"test-{randomPart}-suffix"; var streamFilter = StreamFilter.Prefix(streamName[..^7], "invalid"); var eventsWritten = await AppendEventsAsync(sut, streamName, count, commits); @@ -436,6 +437,30 @@ public async Task Should_query_all_reverse_by_filter(int commits, int count) } } + [Theory] + [InlineData(5, 30)] + [InlineData(5, 300)] + [InlineData(5, 3000)] + public async Task Should_query_all_reverse_by_wildcard_prefix(int commits, int count) + { + var sut = await CreateSutAsync(); + + var randomPart = Guid.NewGuid(); + var streamName = $"test-{randomPart}-suffix"; + var streamFilter = StreamFilter.Prefix($"%-{randomPart}", "invalid"); + + var eventsWritten = await AppendEventsAsync(sut, streamName, count, commits); + var eventsStored = eventsWritten.Select((x, i) => new StoredEvent(streamName, "Position", i, x)).ToArray(); + + for (var take = 0; take < count; take += count / 10) + { + var eventsExpected = eventsStored.Reverse().Take(take).ToArray(); + var eventsQueried = await sut.QueryAllReverseAsync(streamFilter, default, take, ct).ToArrayAsync(); + + ShouldBeEquivalentTo(eventsQueried, eventsExpected); + } + } + [Theory] [InlineData(5, 30)] [InlineData(5, 300)]