예제 #1
0
        public void UpdateSnapshots(Func <string, Type> aggregateTypeResolver, bool continueOnError)
        {
            if (!_isInitialized)
            {
                throw new Exception("Initialize Event Source first!");
            }

            var databaseName = DatabaseName.Invoke();

            PrepareDatabase(databaseName);

            using (var largeSession = string.IsNullOrWhiteSpace(databaseName) ? _store.OpenSession() : _store.OpenSession(databaseName))
            {
                var query = largeSession.Advanced.LuceneQuery <Raven.Json.Linq.RavenJObject>("Raven/DocumentsByEntityName").WhereStartsWith("Tag", "EventStreams");
                var ret   = largeSession.Advanced.Stream(query);

                while (ret.MoveNext())
                {
                    using (var t = new TransactionScope(TransactionScopeOption.RequiresNew))
                    {
                        using (var session = string.IsNullOrWhiteSpace(databaseName) ? _store.OpenSession() : _store.OpenSession(databaseName))
                        {
                            session.Advanced.AllowNonAuthoritativeInformation = false;

                            var stream = session.Load <EventStream>(ret.Current.Key);

                            var commits = FilteredCommits(stream.Commits.Select(x => x.Value));

                            var aggregateType = aggregateTypeResolver.Invoke(stream.AggregateType);
                            var instance      = (IAggregate)Activator.CreateInstance(aggregateType);

                            var exceptions = ApplyEventsToAggregate(commits, instance, continueOnError);
                            if (exceptions.Any())
                            {
                                var id          = stream.Id.ToGuidId().ToStringId <ErrorStream>();
                                var commitError = session.Load <ErrorStream>(id);
                                if (commitError == null)
                                {
                                    commitError = new ErrorStream
                                    {
                                        Id            = id,
                                        AggregateType = stream.AggregateType
                                    };

                                    session.Store(commitError);
                                }
                                foreach (var e in exceptions)
                                {
                                    var commit = stream.Commits[e.Key];
                                    commitError.Commits.Add(new ErrorCommit {
                                        Commit = commit, Error = e.Value
                                    });
                                    stream.Commits.Remove(e.Key);
                                }
                            }

                            stream.Version  = instance.Version;
                            stream.Snapshot = instance;

                            session.SaveChanges();
                        }
                        t.Complete();
                    }
                }
            }
        }
예제 #2
0
        public void StoreCommits(Type aggregateType, Guid aggregateId, IEnumerable <Commit> commits, bool continueOnError = false)
        {
            if (!_isInitialized)
            {
                throw new Exception("Initialize Event Source first!");
            }

            var databaseName = DatabaseName.Invoke();

            if (!string.IsNullOrWhiteSpace(databaseName))
            {
                _store.DatabaseCommands.GlobalAdmin.EnsureDatabaseExists(databaseName);
            }

            using (var t = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                using (var session = string.IsNullOrWhiteSpace(databaseName) ? _store.OpenSession() : _store.OpenSession(databaseName))
                {
                    session.Advanced.UseOptimisticConcurrency         = true;
                    session.Advanced.AllowNonAuthoritativeInformation = false;

                    var id     = aggregateId.ToStringId <EventStream>();
                    var stream = session.Load <EventStream>(id);
                    if (stream == null)
                    {
                        stream = new EventStream {
                            Id = id, AggregateType = aggregateType.FullName
                        };
                        session.Store(stream);
                    }

                    commits = FilteredCommits(commits.OrderBy(x => x.CommitStamp));
                    commits.ToList().ForEach(commit =>
                    {
                        commit.CommitSequence = stream.Commits.Count + 1;
                        stream.Commits.Add(commit.CommitId, commit);
                    });

                    var instance   = (IAggregate)Activator.CreateInstance(aggregateType);
                    var exceptions = ApplyEventsToAggregate(stream.Commits.Select(x => x.Value), instance, continueOnError);

                    if (exceptions.Any())
                    {
                        var errorId     = aggregateId.ToStringId <ErrorStream>();
                        var commitError = session.Load <ErrorStream>(errorId);
                        if (commitError == null)
                        {
                            commitError = new ErrorStream {
                                Id = errorId, AggregateType = stream.AggregateType
                            };
                            session.Store(commitError);
                        }
                        foreach (var e in exceptions)
                        {
                            var commit = stream.Commits[e.Key];
                            commitError.Commits.Add(new ErrorCommit {
                                Commit = commit, Error = e.Value
                            });
                            stream.Commits.Remove(e.Key);
                        }
                    }

                    stream.Version  = instance.Version;
                    stream.Snapshot = instance;

                    session.SaveChanges();
                }
                t.Complete();
            }
        }