protected override sealed async Task PersistModelAsync(PersistEvent @event, TModel model, Graph <TModel> graph, bool create) { var id = ModelAnalyzer.GetIdentity(model); var streamName = EventStoreCommon.GetStreamName <TModel>(id); var eventStoreModel = new EventStoreEventModelData <TModel>() { Source = @event.Source, SourceType = @event.Source?.GetType().Name, Model = model, Graph = graph }; var data = EventStoreCommon.Serialize(eventStoreModel); var eventNumber = await Engine.AppendAsync(@event.ID, @event.Name, streamName, null, create?EventStoreState.NotExisting : EventStoreState.Existing, data); if (eventNumber > 0 && eventNumber % SaveStateEvery == 0) { var thisEventData = (await Engine.ReadBackwardsAsync(streamName, eventNumber, 1, null, null, null))[0]; var where = ModelAnalyzer.GetIdentityExpression <TModel>(id); var eventStates = await Repo.QueryAsync(new EventQueryMany <TModel>(thisEventData.Date, thisEventData.Date, where)); var eventState = eventStates.Where(x => x.Number == eventNumber).Single(); await SaveModelStateAsync(id, eventState.Model, eventState.Number); } }
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(); } } }