private async Task <(TModel, ulong?)> ReadModelStateAsync(object id, TemporalOrder?temporalOrder, DateTime?temporalDateFrom, ulong?temporalNumberFrom)
        {
            if (temporalOrder != TemporalOrder.Newest && !temporalDateFrom.HasValue && !temporalNumberFrom.HasValue)
            {
                return(null, null);
            }

            var streamName = EventStoreCommon.GetStateStreamName <TModel>(id);

            TModel model            = null;
            ulong? modelEventNumber = null;

            long?count = null;

            if (temporalOrder == TemporalOrder.Newest)
            {
                count = 1;
            }

            if (temporalOrder == TemporalOrder.Newest || temporalDateFrom.HasValue || temporalNumberFrom.HasValue)
            {
                var eventData = (await Engine.ReadBackwardsAsync(streamName, null, count, temporalNumberFrom, null, temporalDateFrom)).LastOrDefault();
                if (eventData != null)
                {
                    var eventState = EventStoreCommon.Deserialize <EvenStoreStateData <TModel> >(eventData.Data.Span);
                    modelEventNumber = eventState.Number;
                    model            = eventState.Model;
                }
            }

            return(model, modelEventNumber);
        }
Beispiel #2
0
        public async Task <bool> Rebuild(ulong?maxEventNumber = null, DateTime?maxEventDate = null)
        {
            var startEventNumber = LastEventNumber.HasValue ? LastEventNumber + 1 : null;

            //TODO error handle if aggregate doesn't exist?????
            var eventDatas = await this.eventStore.ReadAsync(streamName, startEventNumber, null, maxEventNumber, null, maxEventDate);

            if (eventDatas.Length == 0)
            {
                return(false);
            }

            if (!IsCreated)
            {
                IsCreated = true;
            }

            foreach (var eventData in eventDatas)
            {
                this.LastEventNumber = eventData.Number;
                this.LastEventDate   = eventData.Date;
                this.LastEventName   = eventData.EventName;
                if (eventData.Deleted)
                {
                    this.IsDeleted = true;
                }
                var eventModel = EventStoreCommon.Deserialize <IEvent>(eventData.Data.Span);
                await ApplyEvent(eventModel, eventModel.GetType());
            }
            return(true);
        }
        private ICollection <EventModel <TModel> > LoadEventModelsFromEventDatas(EventStoreEventData[] eventDatas, TModel modelState, bool many, Query <TModel> query)
        {
            if (modelState == null && eventDatas.Length == 0)
            {
                return(Array.Empty <EventModel <TModel> >());
            }

            if (modelState == null)
            {
                modelState = Instantiator.CreateInstance <TModel>();
            }

            if (many)
            {
                switch (query.TemporalOrder ?? TemporalOrder.Newest)
                {
                case TemporalOrder.Newest:
                {
                    var eventModels = new List <EventModel <TModel> >();
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        var eventModelData = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModelData.Model, modelState, eventModelData.Graph);

                        if (query.TemporalDateTo.HasValue && query.TemporalDateTo.Value < eventData.Date)
                        {
                            break;
                        }
                        if (query.TemporalNumberTo.HasValue && query.TemporalNumberTo.Value < eventData.Number)
                        {
                            break;
                        }
                        if ((!query.TemporalDateFrom.HasValue && !query.TemporalNumberFrom.HasValue) || (query.TemporalDateFrom.HasValue && eventData.Date >= query.TemporalDateFrom.Value) || (query.TemporalNumberFrom.HasValue && eventData.Number >= query.TemporalNumberFrom.Value))
                        {
                            var copy       = Mapper.Copy(modelState);
                            var eventModel = new EventModel <TModel>()
                            {
                                EventID   = eventData.EventID,
                                EventName = eventData.EventName,
                                Date      = eventData.Date,
                                Number    = eventData.Number,
                                Deleted   = eventData.Deleted,

                                Model = copy,

                                ModelChange = eventModelData.Model,
                                GraphChange = eventModelData.Graph,
                                Source      = eventModelData.Source,
                                SourceType  = eventModelData.SourceType
                            };
                            eventModels.Add(eventModel);
                        }
                    }
                    if (query.TemporalSkip.HasValue && query.TemporalTake.HasValue)
                    {
                        eventModels.Reverse();
                        return(eventModels.Skip(query.TemporalSkip.Value).Take(query.TemporalTake.Value).Reverse().ToArray());
                    }
                    else if (query.TemporalSkip.HasValue)
                    {
                        eventModels.Reverse();
                        return(eventModels.Skip(query.TemporalSkip.Value).Reverse().ToArray());
                    }
                    else if (query.TemporalTake.HasValue)
                    {
                        eventModels.Reverse();
                        return(eventModels.Take(query.TemporalTake.Value).Reverse().ToArray());
                    }
                    else
                    {
                        return(eventModels);
                    }
                }

                case TemporalOrder.Oldest:
                {
                    var eventModels = new List <EventModel <TModel> >();
                    var skipCount   = 0;
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        var eventModelData = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModelData.Model, modelState, eventModelData.Graph);

                        if (query.TemporalDateTo.HasValue && query.TemporalDateTo.Value < eventData.Date)
                        {
                            break;
                        }
                        if (query.TemporalNumberTo.HasValue && query.TemporalNumberTo.Value < eventData.Number)
                        {
                            break;
                        }
                        if ((!query.TemporalDateFrom.HasValue && !query.TemporalNumberFrom.HasValue) || (query.TemporalDateFrom.HasValue && eventData.Date >= query.TemporalDateFrom.Value) || (query.TemporalNumberFrom.HasValue && eventData.Number >= query.TemporalNumberFrom.Value))
                        {
                            if (!query.TemporalSkip.HasValue || query.TemporalSkip.Value <= skipCount)
                            {
                                var copy       = Mapper.Copy(modelState);
                                var eventModel = new EventModel <TModel>()
                                {
                                    EventID   = eventData.EventID,
                                    EventName = eventData.EventName,
                                    Date      = eventData.Date,
                                    Number    = eventData.Number,
                                    Deleted   = eventData.Deleted,

                                    Model = copy,

                                    ModelChange = eventModelData.Model,
                                    GraphChange = eventModelData.Graph,
                                    Source      = eventModelData.Source,
                                    SourceType  = eventModelData.SourceType
                                };
                                eventModels.Add(eventModel);
                            }
                            else
                            {
                                skipCount++;
                            }
                        }
                    }
                    return(eventModels);
                }

                default:
                    throw new NotImplementedException();
                }
            }
            else
            {
                switch (query.TemporalOrder ?? TemporalOrder.Newest)
                {
                case TemporalOrder.Newest:
                {
                    EventStoreEventModelData <TModel> eventModelData = null;
                    EventStoreEventData thisEventData = null;
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        thisEventData  = eventData;
                        eventModelData = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModelData.Model, modelState, eventModelData.Graph);

                        if (query.TemporalDateTo.HasValue && query.TemporalDateTo.Value < eventData.Date)
                        {
                            break;
                        }
                        if (!query.TemporalNumberTo.HasValue && eventData.Number < query.TemporalNumberTo.Value)
                        {
                            break;
                        }
                    }
                    var eventModel = new EventModel <TModel>()
                    {
                        EventID   = thisEventData.EventID,
                        EventName = thisEventData.EventName,
                        Date      = thisEventData.Date,
                        Number    = thisEventData.Number,
                        Deleted   = thisEventData.Deleted,

                        Model = modelState,

                        ModelChange = eventModelData.Model,
                        GraphChange = eventModelData.Graph,
                        Source      = eventModelData.Source,
                        SourceType  = eventModelData.SourceType
                    };
                    return(new EventModel <TModel>[] { eventModel });
                }

                case TemporalOrder.Oldest:
                {
                    EventStoreEventModelData <TModel> eventModelData = null;
                    EventStoreEventData thisEventData = null;
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        thisEventData  = eventData;
                        eventModelData = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModelData.Model, modelState, eventModelData.Graph);

                        if (!query.TemporalDateFrom.HasValue || eventData.Date >= query.TemporalDateFrom)
                        {
                            break;
                        }
                        if (!query.TemporalNumberFrom.HasValue || eventData.Number >= query.TemporalNumberFrom.Value)
                        {
                            break;
                        }
                    }
                    var eventModel = new EventModel <TModel>()
                    {
                        EventID   = thisEventData.EventID,
                        EventName = thisEventData.EventName,
                        Date      = thisEventData.Date,
                        Number    = thisEventData.Number,
                        Deleted   = thisEventData.Deleted,

                        Model = modelState,

                        ModelChange = eventModelData.Model,
                        GraphChange = eventModelData.Graph,
                        Source      = eventModelData.Source,
                        SourceType  = eventModelData.SourceType
                    };
                    return(new EventModel <TModel>[] { eventModel });
                }

                default:
                    throw new NotImplementedException();
                }
            }
        }
        private ICollection <TModel> LoadModelsFromEventDatas(EventStoreEventData[] eventDatas, TModel modelState, bool many, Query <TModel> query)
        {
            if (modelState == null && eventDatas.Length == 0)
            {
                return(Array.Empty <TModel>());
            }

            if (modelState == null)
            {
                modelState = Instantiator.CreateInstance <TModel>();
            }

            if (many)
            {
                switch (query.TemporalOrder ?? TemporalOrder.Newest)
                {
                case TemporalOrder.Newest:
                {
                    var modelStates = new List <TModel>();
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        var eventModel = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModel.Model, modelState, eventModel.Graph);

                        if (query.TemporalDateTo.HasValue && query.TemporalDateTo.Value < eventData.Date)
                        {
                            break;
                        }
                        if (query.TemporalNumberTo.HasValue && query.TemporalNumberTo.Value < eventData.Number)
                        {
                            break;
                        }
                        if ((!query.TemporalDateFrom.HasValue && !query.TemporalNumberFrom.HasValue) || (query.TemporalDateFrom.HasValue && eventData.Date >= query.TemporalDateFrom.Value) || (query.TemporalNumberFrom.HasValue && eventData.Number >= query.TemporalNumberFrom.Value))
                        {
                            var copy = Mapper.Copy(modelState);
                            modelStates.Add(copy);
                        }
                    }

                    if (query.TemporalSkip.HasValue && query.TemporalTake.HasValue)
                    {
                        modelStates.Reverse();
                        return(modelStates.Skip(query.TemporalSkip.Value).Take(query.TemporalTake.Value).Reverse().ToArray());
                    }
                    else if (query.TemporalSkip.HasValue)
                    {
                        modelStates.Reverse();
                        return(modelStates.Skip(query.TemporalSkip.Value).Reverse().ToArray());
                    }
                    else if (query.TemporalTake.HasValue)
                    {
                        modelStates.Reverse();
                        return(modelStates.Take(query.TemporalTake.Value).Reverse().ToArray());
                    }
                    else
                    {
                        return(modelStates);
                    }
                }

                case TemporalOrder.Oldest:
                {
                    var modelStates = new List <TModel>();
                    var skipCount   = 0;
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        var eventModel = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModel.Model, modelState, eventModel.Graph);

                        if (query.TemporalDateTo.HasValue && query.TemporalDateTo.Value < eventData.Date)
                        {
                            break;
                        }
                        if (query.TemporalNumberTo.HasValue && query.TemporalNumberTo.Value < eventData.Number)
                        {
                            break;
                        }
                        if ((!query.TemporalDateFrom.HasValue && !query.TemporalNumberFrom.HasValue) || (query.TemporalDateFrom.HasValue && eventData.Date >= query.TemporalDateFrom.Value) || (query.TemporalNumberFrom.HasValue && eventData.Number >= query.TemporalNumberFrom.Value))
                        {
                            if (!query.TemporalSkip.HasValue || query.TemporalSkip.Value <= skipCount)
                            {
                                var copy = Mapper.Copy(modelState);
                                modelStates.Add(copy);
                                if (query.TemporalTake.HasValue && query.TemporalTake.Value == modelStates.Count)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                skipCount++;
                            }
                        }
                    }
                    return(modelStates);
                }

                default:
                    throw new NotImplementedException();
                }
            }
            else
            {
                switch (query.TemporalOrder ?? TemporalOrder.Newest)
                {
                case TemporalOrder.Newest:
                {
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        var eventModel = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModel.Model, modelState, eventModel.Graph);

                        if (query.TemporalDateTo.HasValue && query.TemporalDateTo.Value < eventData.Date)
                        {
                            break;
                        }
                        if (query.TemporalNumberTo.HasValue && eventData.Number < query.TemporalNumberTo.Value)
                        {
                            break;
                        }
                    }
                    return(new TModel[] { modelState });
                }

                case TemporalOrder.Oldest:
                {
                    foreach (var eventData in eventDatas.Reverse())
                    {
                        var eventModel = EventStoreCommon.Deserialize <EventStoreEventModelData <TModel> >(eventData.Data.Span);
                        Mapper.MapTo(eventModel.Model, modelState, eventModel.Graph);

                        if (query.TemporalDateFrom.HasValue && eventData.Date >= query.TemporalDateFrom.Value)
                        {
                            break;
                        }
                        if (query.TemporalNumberFrom.HasValue && eventData.Number >= query.TemporalNumberFrom.Value)
                        {
                            break;
                        }
                    }
                    return(new TModel[] { modelState });
                }

                default:
                    throw new NotImplementedException();
                }
            }
        }