From 3c9bfbd041bfde3b86dd33a299432e97d73416b8 Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Tue, 29 Oct 2024 09:49:28 -0500 Subject: [PATCH] Fix for quick append + mandatory stream type behavior. Closes GH-3518 --- .../mandatory_stream_type_behavior.cs | 33 +++++++++++++++++++ .../QuickAppendEventsOperationBase.cs | 18 ++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/EventSourcingTests/mandatory_stream_type_behavior.cs b/src/EventSourcingTests/mandatory_stream_type_behavior.cs index 9bf20f5038..9938941236 100644 --- a/src/EventSourcingTests/mandatory_stream_type_behavior.cs +++ b/src/EventSourcingTests/mandatory_stream_type_behavior.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using EventSourcingTests.Aggregation; +using EventSourcingTests.FetchForWriting; using JasperFx.Core; using Marten; using Marten.Events; @@ -88,6 +89,38 @@ await Should.ThrowAsync(async () => }); } + [Theory] + [InlineData(EventAppendMode.Rich, StreamIdentity.AsGuid)] + [InlineData(EventAppendMode.Rich, StreamIdentity.AsString)] + [InlineData(EventAppendMode.Quick, StreamIdentity.AsGuid)] + [InlineData(EventAppendMode.Quick, StreamIdentity.AsString)] + public async Task happy_path_append_event_after_the_stream_exists(EventAppendMode mode, StreamIdentity identity) + { + StoreOptions(opts => + { + opts.Events.AppendMode = mode; + opts.Events.StreamIdentity = identity; + opts.Events.UseMandatoryStreamTypeDeclaration = true; + }); + + if (identity == StreamIdentity.AsGuid) + { + var streamId = Guid.NewGuid(); + theSession.Events.StartStream(streamId, new BEvent()); + await theSession.SaveChangesAsync(); + theSession.Events.Append(streamId, new AEvent()); + await theSession.SaveChangesAsync(); + } + else + { + var streamId = Guid.NewGuid().ToString(); + theSession.Events.StartStream(streamId, new BEvent()); + await theSession.SaveChangesAsync(); + theSession.Events.Append(streamId, new AEvent()); + await theSession.SaveChangesAsync(); + } + } + [Fact] public async Task happy_path_usage_with_guid() { diff --git a/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs b/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs index f5595d5d01..916822609e 100644 --- a/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs +++ b/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs @@ -46,6 +46,13 @@ public void Postprocess(DbDataReader reader, IList exceptions) { var values = reader.GetFieldValue(0); + var finalVersion = values[0]; + foreach (var e in Stream.Events.Reverse()) + { + e.Version = finalVersion; + finalVersion--; + } + // Ignore the first value for (int i = 1; i < values.Length; i++) { @@ -53,7 +60,7 @@ public void Postprocess(DbDataReader reader, IList exceptions) Stream.Events[i - 1].Sequence = values[i]; } - if (Events is { UseMandatoryStreamTypeDeclaration: true } && Stream.Events[0].Version == 0) + if (Events is { UseMandatoryStreamTypeDeclaration: true } && Stream.Events[0].Version == 1) { throw new NonExistentStreamException(Events.StreamIdentity == StreamIdentity.AsGuid ? Stream.Id @@ -119,6 +126,13 @@ public async Task PostprocessAsync(DbDataReader reader, IList excepti { var values = await reader.GetFieldValueAsync(0, token).ConfigureAwait(false); + var finalVersion = values[0]; + foreach (var e in Stream.Events.Reverse()) + { + e.Version = finalVersion; + finalVersion--; + } + // Ignore the first value for (int i = 1; i < values.Length; i++) { @@ -126,7 +140,7 @@ public async Task PostprocessAsync(DbDataReader reader, IList excepti Stream.Events[i - 1].Sequence = values[i]; } - if (Events is { UseMandatoryStreamTypeDeclaration: true } && Stream.Events[0].Version == 0) + if (Events is { UseMandatoryStreamTypeDeclaration: true } && Stream.Events[0].Version == 1) { throw new NonExistentStreamException(Events.StreamIdentity == StreamIdentity.AsGuid ? Stream.Id