public async Task <IReadOnlyCollection <ICommittedDomainEvent> > LoadCommittedEventsAsync(IIdentity id, int fromEventSequenceNumber, CancellationToken cancellationToken)
 {
     return(await MongoDbEventStoreCollection
            .Find(model => model.AggregateId == id.Value && model.AggregateSequenceNumber >= fromEventSequenceNumber)
            .ToListAsync(cancellationToken)
            .ConfigureAwait(continueOnCapturedContext: false));
 }
        public async Task <IReadOnlyCollection <ICommittedDomainEvent> > CommitEventsAsync(IIdentity id, IReadOnlyCollection <SerializedEvent> serializedEvents, CancellationToken cancellationToken)
        {
            if (!serializedEvents.Any())
            {
                return(new ICommittedDomainEvent[] { });
            }

            var eventDataModels = serializedEvents
                                  .Select((e, i) => new MongoDbEventDataModel
            {
                _id                     = _mongoDbEventSequenceStore.GetNextSequence(_collectionName),
                AggregateId             = id.Value,
                AggregateName           = e.Metadata[MetadataKeys.AggregateName],
                BatchId                 = Guid.Parse(e.Metadata[MetadataKeys.BatchId]),
                Data                    = e.SerializedData,
                Metadata                = e.SerializedMetadata,
                AggregateSequenceNumber = e.AggregateSequenceNumber
            })
                                  .OrderBy(x => x.AggregateSequenceNumber)
                                  .ToList();

            _log.Verbose("Committing {0} events to MongoDb event store for entity with ID '{1}'", eventDataModels.Count, id);
            await MongoDbEventStoreCollection
            .InsertManyAsync(eventDataModels, cancellationToken : cancellationToken)
            .ConfigureAwait(continueOnCapturedContext: false);

            return(eventDataModels);
        }
        public async Task <IReadOnlyCollection <ICommittedDomainEvent> > CommitEventsAsync(IIdentity id, IReadOnlyCollection <SerializedEvent> serializedEvents, CancellationToken cancellationToken)
        {
            if (!serializedEvents.Any())
            {
                return(Array.Empty <ICommittedDomainEvent>());
            }

            var eventDataModels = serializedEvents
                                  .Select((e, i) => new MongoDbEventDataModel
            {
                _id                     = DateTime.UtcNow.Ticks,
                AggregateId             = id.Value,
                AggregateName           = e.Metadata[MetadataKeys.AggregateName],
                BatchId                 = Guid.Parse(e.Metadata[MetadataKeys.BatchId]),
                Data                    = e.SerializedData,
                Metadata                = e.SerializedMetadata,
                AggregateSequenceNumber = e.AggregateSequenceNumber
            })
                                  .OrderBy(x => x.AggregateSequenceNumber)
                                  .ToList();

            _log.Verbose("Committing {0} events to MongoDb event store for entity with ID '{1}'", eventDataModels.Count, id);
            try
            {
                await MongoDbEventStoreCollection
                .InsertManyAsync(eventDataModels, cancellationToken : cancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false);
            }
            catch (MongoBulkWriteException e)
            {
                throw new OptimisticConcurrencyException(e.Message, e);
            }
            return(eventDataModels);
        }
        public async Task DeleteEventsAsync(IIdentity id, CancellationToken cancellationToken)
        {
            DeleteResult affectedRows = await MongoDbEventStoreCollection
                                        .DeleteManyAsync(x => x.AggregateId == id.Value, cancellationToken)
                                        .ConfigureAwait(continueOnCapturedContext: false);

            _log.Verbose("Deleted entity with ID '{0}' by deleting all of its {1} events", id, affectedRows.DeletedCount);
        }
        public async Task <AllCommittedEventsPage> LoadAllCommittedEvents(GlobalPosition globalPosition, int pageSize, CancellationToken cancellationToken)
        {
            long startPosition = globalPosition.IsStart
                ? 0
                : long.Parse(globalPosition.Value);
            long endPosition = startPosition + pageSize;

            List <MongoDbEventDataModel> eventDataModels = await MongoDbEventStoreCollection
                                                           .Find(model => model._id >= startPosition && model._id <= endPosition)
                                                           .ToListAsync(cancellationToken)
                                                           .ConfigureAwait(continueOnCapturedContext: false);

            long nextPosition = eventDataModels.Any()
                ? eventDataModels.Max(e => e._id) + 1
                : startPosition;

            return(new AllCommittedEventsPage(new GlobalPosition(nextPosition.ToString()), eventDataModels));
        }
        public async Task <AllCommittedEventsPage> LoadAllCommittedEvents(GlobalPosition globalPosition, int pageSize, CancellationToken cancellationToken)
        {
            var startPosition = globalPosition.IsStart ? 0 : long.Parse(globalPosition.Value, CultureInfo.InvariantCulture);

            var eventDataModels = await(await MongoDbEventStoreCollection
                                        .FindAsync(model => model._id >= startPosition,
                                                   new FindOptions <MongoDbEventDataModel, MongoDbEventDataModel> {
                Limit = pageSize
            }, cancellationToken)
                                        .ConfigureAwait(false))
                                  .ToListAsync(cancellationToken)
                                  .ConfigureAwait(continueOnCapturedContext: false);

            var nextPosition = eventDataModels.Any()
                ? eventDataModels.Max(e => e._id) + 1
                : startPosition;

            return(new AllCommittedEventsPage(new GlobalPosition(nextPosition.ToString(CultureInfo.InvariantCulture)), eventDataModels));
        }