private async Task ProjectTransaction(Transaction transaction, IAsyncDocumentSession session) { foreach (EventEnvelope eventEnvelope in transaction.Events) { var context = new RavenProjectionContext { TransactionId = transaction.Id, Session = session, StreamId = transaction.StreamId, TimeStampUtc = transaction.TimeStampUtc, Checkpoint = transaction.Checkpoint, EventHeaders = eventEnvelope.Headers, TransactionHeaders = transaction.Headers }; try { await mapConfigurator.ProjectEvent(eventEnvelope.Body, context).ConfigureAwait(false); } catch (ProjectionException projectionException) { projectionException.TransactionId = transaction.Id; projectionException.CurrentEvent = eventEnvelope; throw; } catch (Exception exception) { throw new ProjectionException("Projector failed to project an event.", exception) { TransactionId = transaction.Id, CurrentEvent = eventEnvelope }; } } }
async Task IRavenChildProjector.ProjectEvent(object anEvent, RavenProjectionContext context) { if (anEvent == null) { throw new ArgumentNullException(nameof(anEvent)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } try { await mapConfigurator.ProjectEvent(anEvent, context).ConfigureAwait(false); } catch (ProjectionException projectionException) { if (string.IsNullOrEmpty(projectionException.ChildProjector)) { projectionException.ChildProjector = typeof(TProjection).ToString(); } throw; } catch (Exception exception) { throw new ProjectionException("Projector failed to project an event.", exception) { ChildProjector = typeof(TProjection).ToString() }; } }
public async Task ProjectEvent(object anEvent, RavenProjectionContext context) { foreach (IRavenChildProjector child in children) { await child.ProjectEvent(anEvent, context).ConfigureAwait(false); } await map.Handle(anEvent, context).ConfigureAwait(false); }
private async Task HandleProjectionDeletion(string key, RavenProjectionContext context, ProjectionDeletionOptions options) { string databaseId = BuildDatabaseId(key); // If the projection is already loaded, we have to delete it via the loaded instance. // If the projection is not cached, we have to load it to verify that it exists. // Otherwise we can delete fast by id without loading the projection. if (context.Session.Advanced.IsLoaded(databaseId) || !await IsCached(databaseId).ConfigureAwait(false)) { TProjection projection = await context.Session.LoadAsync <TProjection>(databaseId).ConfigureAwait(false); if (projection == null) { switch (options.MissingProjectionBehavior) { case MissingProjectionDeletionBehavior.Ignore: { break; } case MissingProjectionDeletionBehavior.Throw: { throw new ProjectionException( $"Cannot delete projection with id {databaseId}. The projection does not exist."); } default: { throw new NotSupportedException( $"Not supported missing projection behavior {options.MissingProjectionBehavior}."); } } } else { context.Session.Delete(projection); cache.Remove(databaseId); } } else { context.Session.Delete(databaseId); cache.Remove(databaseId); } }
private async Task HandleProjectionModification(string key, RavenProjectionContext context, Func <TProjection, Task> projector, ProjectionModificationOptions options) { string databaseId = BuildDatabaseId(key); var projection = (TProjection)await cache.TryGet(databaseId).ConfigureAwait(false); if (projection == null) { projection = await context.Session.LoadAsync <TProjection>(databaseId).ConfigureAwait(false); if (projection != null) { cache.Add(projection); } } if (projection == null) { switch (options.MissingProjectionBehavior) { case MissingProjectionModificationBehavior.Create: { projection = new TProjection { Id = databaseId }; await projector(projection).ConfigureAwait(false); cache.Add(projection); await context.Session.StoreAsync(projection).ConfigureAwait(false); break; } case MissingProjectionModificationBehavior.Ignore: { break; } case MissingProjectionModificationBehavior.Throw: { throw new ProjectionException($"Projection with id {databaseId} does not exist."); } default: { throw new NotSupportedException( $"Not supported missing projection behavior {options.MissingProjectionBehavior}."); } } } else { switch (options.ExistingProjectionBehavior) { case ExistingProjectionModificationBehavior.Update: { await projector(projection).ConfigureAwait(false); await context.Session.StoreAsync(projection).ConfigureAwait(false); break; } case ExistingProjectionModificationBehavior.Ignore: { break; } case ExistingProjectionModificationBehavior.Throw: { throw new ProjectionException($"Projection with id {databaseId} already exists."); } default: { throw new NotSupportedException( $"Not supported existing projection behavior {options.ExistingProjectionBehavior}."); } } } }