Exemple #1
0
        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}.");
                }
                }
            }
        }