public async Task <StreamEventsPage> ReadStream( string streamName, long fromVersion, long maxCount, StreamReadDirection direction = StreamReadDirection.Forward, CancellationToken cancellationToken = new CancellationToken()) { StreamEventsSlice slice; using (var connection = _getEventStoreConnection()) { slice = await connection .ReadStreamEventsForwardAsync(streamName, fromVersion, (int)maxCount, false) .ConfigureAwait(false); } var events = await Task .WhenAll(slice.Events.Select(resolvedEvent => _resolveStreamEvent(resolvedEvent.Event, cancellationToken))) .ConfigureAwait(false); return(new StreamEventsPage( streamName: slice.Stream, fromVersion: slice.FromEventNumber, nextVersion: slice.NextEventNumber, lastVersion: slice.LastEventNumber, events: events, direction: direction, isEndOfStream: slice.IsEndOfStream)); }
public async Task <StreamEventsPage> ReadStream( string streamName, long fromVersion, long maxCount, StreamReadDirection direction = StreamReadDirection.Forward, CancellationToken cancellationToken = new CancellationToken()) { if (direction == StreamReadDirection.Backward) { throw new NotSupportedException("Marten only supports forward reads."); } if (fromVersion != 1) { throw new NotSupportedException("Marten only supports reading streams forward from the beginning (version:1)."); } var streamId = GetStreamId(streamName); IReadOnlyList <IEvent> martenEvents; StreamState streamState; using (var session = _getDocumentSession()) { var getEvents = session.Events.FetchStreamAsync(streamId, (int)maxCount, null, cancellationToken); var getStreamState = session.Events.FetchStreamStateAsync(streamId, cancellationToken); await Task .WhenAll(getEvents, getStreamState) .ConfigureAwait(false); martenEvents = await getEvents; streamState = await getStreamState; } var events = martenEvents.Select(martenEvent => new StreamEvent(martenEvent.Id, martenEvent.Data, new Dictionary <string, string> { //{ EventMetadataKeys.Id , martenEvent.Id.ToString() }, { EventMetadataKeys.Timestamp, martenEvent.Timestamp.ToString(CultureInfo.InvariantCulture) }, { EventMetadataKeys.Owner, streamState.AggregateType.Name }, //{ EventMetadataKeys.OwnerId , martenEvent.. }, { EventMetadataKeys.OwnerVersion, martenEvent.Version.ToString() }, { EventMetadataKeys.ClrType, martenEvent.Data.GetType().AssemblyQualifiedName }, })); return(new StreamEventsPage( streamName: streamId.ToString(), fromVersion: 1, nextVersion: martenEvents.LastOrDefault()?.Version + 1 ?? 1, lastVersion: streamState.Version, isEndOfStream: false, events: events, direction: StreamReadDirection.Forward)); }
public StreamEventsPage( string streamName, long fromVersion, long nextVersion, long lastVersion, bool isEndOfStream, IEnumerable <StreamEvent> events, StreamReadDirection direction) { IsEndOfStream = isEndOfStream; StreamName = streamName; FromVersion = fromVersion; NextVersion = nextVersion; LastVersion = lastVersion; Events = events.ToArray(); Direction = direction; }
public async Task <StreamEventsPage> ReadStream( string streamName, long fromVersion, long maxCount, StreamReadDirection direction = StreamReadDirection.Forward, CancellationToken cancellationToken = default(CancellationToken)) { var page = await _streamStore .ReadStreamForwards(streamName, (int)fromVersion, (int)maxCount, cancellationToken) .ConfigureAwait(false); var events = await Task .WhenAll(page.Messages.Select(streamMessage => _resolveStreamEvent(streamMessage, cancellationToken))) .ConfigureAwait(false); return(new StreamEventsPage( streamName: page.StreamId, fromVersion: page.FromStreamVersion, nextVersion: page.NextStreamVersion, lastVersion: page.LastStreamVersion, isEndOfStream: page.IsEnd, events: events, direction: direction)); }
public StreamEventsPage( string streamId, int fromVersion, int toVersion, int lastVersion, IEnumerable<StreamEvent> events, StreamReadDirection direction) { var readonlyEvents = events.ToList().AsReadOnly(); IsEndOfStream = direction == StreamReadDirection.Forward ? toVersion == lastVersion : toVersion == 0; StreamId = streamId; FromVersion = fromVersion; NextVersion = IsEndOfStream ? -1 : direction == StreamReadDirection.Forward ? toVersion + 1 : toVersion - 1; LastVersion = lastVersion; Events = readonlyEvents; Direction = direction; }
public Task<StreamEventsPage> ReadStream(string streamId, int fromVersion, int count, StreamReadDirection direction = StreamReadDirection.Forward) { throw new NotImplementedException(); }
public async Task<StreamEventsPage> ReadStream(string streamId, int fromVersion, int count, StreamReadDirection direction = StreamReadDirection.Forward) { Guard.NullOrWhiteSpace(() => streamId); await _log.Debug("Reading stream {@streamId} from version {fromVersion} to version {count}", streamId, fromVersion, count); // create parameters var parameters = new DynamicParameters(); parameters.AddDynamicParams(new { StreamId = streamId, FromVersion = fromVersion, Count = count, ReadForward = direction == StreamReadDirection.Forward ? 1 : 0 }); parameters.AddOutput("Error"); parameters.AddReturnValue(); IEnumerable<StreamEventData> result; // execute operation using(var connection = new SqlConnection(_settings.ConnectionString)) { // found a hardcore bug with Dapper! // if we exit a query without executing a select, the .QueryAsync<T> fails because it // tries to read the resultsetschema and fails. // therefore we do not have access to return or output values. result = await connection .QueryAsync<StreamEventData>( sql : "ReadStream", param : parameters, commandType: CommandType.StoredProcedure) .ConfigureAwait(false); } // check for errors switch(parameters.GetOutput<int>("Error")) { case -100: throw new StreamNotFoundException(streamId); case -200: throw new StreamDeletedException(streamId, fromVersion); } await _log.Information("Stream {@streamId} read from version {fromVersion} to version {count}", streamId, fromVersion, count); // return stream page var streamVersion = parameters.GetReturnValue(); var streamEvents = result.Select( streamEventData => { var metadata = _serializer.Deserialize<IDictionary<string, string>>(streamEventData.Metadata); var domainEventType = Type.GetType(metadata[EventMetadataKeys.ClrType].ToString()); var streamEvent = _serializer.DeserializeAs<object>(streamEventData.Data, domainEventType); return new StreamEvent(streamEvent, metadata); }).ToList(); var lastReadEventVersion = streamEvents.Any() ? int.Parse(streamEvents.Last().Metadata[EventMetadataKeys.Version]) : -1; await _log.Debug("Stream {@streamId} event serialization finished", streamId); return new StreamEventsPage( streamId : streamId, fromVersion: fromVersion, toVersion : lastReadEventVersion, lastVersion: streamVersion, events : streamEvents, direction : direction); }
public async Task <StreamReadResults> ReadFrom(string streamId, Func <IAmAStoredEvent, bool> predicate = null, StreamReadDirection direction = StreamReadDirection.Backwards, CancellationToken cancellationToken = default) { predicate ??= _ => true; IAsyncEnumerable <StoredEvent> storedEvents; if (direction == StreamReadDirection.Backwards) { var readResult = await connection.ReadStreamEventsBackwardAsync(streamId, StreamPosition.End, pageSize, true); if (!StreamExists(readResult)) { return(new StreamReadResults(EmptyReadResult, false, StoredEventPosition.FromInt64(-1))); } storedEvents = readResult.Events // Trust me, resharper is wrong in this one. Event can be null // ReSharper disable once ConditionIsAlwaysTrueOrFalse .Where(e => e.Event != null) .Select((e, _) => e.Event.ToStoredEvent(stateFactory)) .TakeWhile(e => e.DeserializedEvent is not EntitySoftDeleted) .Where(e => predicate(e)) .ToAsyncEnumerable(); } else { var readResult = await connection.ReadStreamEventsForwardAsync(streamId, StreamPosition.Start, pageSize, true); if (!StreamExists(readResult)) { return(new StreamReadResults(EmptyReadResult, false, StoredEventPosition.FromInt64(-1))); } storedEvents = readResult.Events // Trust me, resharper is wrong in this one. Event can be null // ReSharper disable once ConditionIsAlwaysTrueOrFalse .Where(e => e.Event != null) .Select((e, c) => e.Event.ToStoredEvent(stateFactory)) .Where(e => predicate(e)) .ToAsyncEnumerable(); } var result = await connection.ReadEventAsync(streamId, StreamPosition.End, false); var idx = result.Event?.OriginalEventNumber ?? -1; return(new StreamReadResults(storedEvents, true, StoredEventPosition.FromInt64(idx))); }
public async Task <StreamReadResults> ReadFrom(string streamId, Func <IAmAStoredEvent, bool> predicate = null, StreamReadDirection direction = StreamReadDirection.Backwards, CancellationToken cancellationToken = default) { var readResult = client.ReadStreamAsync( direction == StreamReadDirection.Backwards ? Direction.Backwards : Direction.Forwards, streamId, direction == StreamReadDirection.Backwards ? StreamPosition.End : StreamPosition.Start, resolveLinkTos: true, configureOperationOptions: options => options.TimeoutAfter = TimeSpan.FromSeconds(30), cancellationToken: cancellationToken); bool streamExists = false; try { var readState = await readResult.ReadState; streamExists = readState == ReadState.Ok; } #pragma warning disable 168 catch (StreamDeletedException ex) // This happens when the stream is hard-deleted. We don't want to throw in that case #pragma warning restore 168 { streamExists = false; } if (!streamExists) { return(new StreamReadResults(EmptyReadResult, false, StoredEventPosition.FromInt64(-1))); } predicate ??= _ => true; var lastIndex = (await client.ReadStreamAsync(Direction.Backwards, streamId, StreamPosition.End, 1, resolveLinkTos: false).FirstAsync(cancellationToken)).OriginalEventNumber; IAsyncEnumerable <StoredEvent> storedEvents; if (direction == StreamReadDirection.Backwards) { storedEvents = readResult // Trust me, resharper is wrong in this one. Event can be null // ReSharper disable once ConditionIsAlwaysTrueOrFalse .Where(e => e.Event != null) .Select(e => e.Event.ToStoredEvent(stateFactory)) .TakeWhile(e => e.DeserializedEvent is not EntitySoftDeleted) .Where(e => predicate(e)); } else { storedEvents = readResult // Trust me, resharper is wrong in this one. Event can be null // ReSharper disable once ConditionIsAlwaysTrueOrFalse .Where(e => e.Event != null) .Select(e => e.Event.ToStoredEvent(stateFactory)) .Where(e => predicate(e)); } return(new StreamReadResults(storedEvents, true, StoredEventPosition.FromInt64(lastIndex.ToInt64()))); }