private IList <ViewFactory> GetRetainViewFactories(EventType parentEventType, IList <ViewFactory> viewFactories, bool isUnion, StatementContext context) { ICollection <int> groupByFactory = new HashSet <int>(); ICollection <int> mergeFactory = new HashSet <int>(); IList <ViewFactory> derivedValueViews = new List <ViewFactory>(); IList <ViewFactory> dataWindowViews = new List <ViewFactory>(); for (var i = 0; i < viewFactories.Count; i++) { var factory = viewFactories[i]; if (factory is GroupByViewFactoryMarker) { groupByFactory.Add(i); } else if (factory is MergeViewFactoryMarker) { mergeFactory.Add(i); } else if (factory is DataWindowViewFactory) { dataWindowViews.Add(factory); } else { derivedValueViews.Add(factory); } } if (groupByFactory.Count > 1) { throw new ViewProcessingException("Multiple groupwin views are not allowed in conjuntion with multiple data windows"); } if ((groupByFactory.IsNotEmpty()) && (groupByFactory.First() != 0)) { throw new ViewProcessingException("The groupwin view must occur in the first position in conjuntion with multiple data windows"); } if ((groupByFactory.IsNotEmpty()) && (mergeFactory.First() != (viewFactories.Count - 1))) { throw new ViewProcessingException("The merge view cannot be used in conjuntion with multiple data windows"); } GroupByViewFactoryMarker groupByViewFactory = null; MergeViewFactoryMarker mergeViewFactory = null; if (groupByFactory.IsNotEmpty()) { groupByViewFactory = (GroupByViewFactoryMarker)viewFactories[0]; mergeViewFactory = (MergeViewFactoryMarker)viewFactories[viewFactories.Count - 1]; viewFactories.RemoveAt(0); viewFactories.RemoveAt(viewFactories.Count - 1); } ViewFactory retainPolicy; if (isUnion) { var viewFactory = (UnionViewFactory)context.ViewResolutionService.Create("internal", "union"); viewFactory.ParentEventType = parentEventType; viewFactory.ViewFactories = dataWindowViews; retainPolicy = viewFactory; } else { var viewFactory = (IntersectViewFactory)context.ViewResolutionService.Create("internal", "intersect"); viewFactory.ParentEventType = parentEventType; viewFactory.ViewFactories = dataWindowViews; retainPolicy = viewFactory; } IList <ViewFactory> nonRetainViewFactories = new List <ViewFactory>(); nonRetainViewFactories.Add(retainPolicy); if (groupByViewFactory != null) { nonRetainViewFactories.Insert(0, (ViewFactory)groupByViewFactory); nonRetainViewFactories.AddAll(derivedValueViews); nonRetainViewFactories.Add((ViewFactory)mergeViewFactory); } else { nonRetainViewFactories.AddAll(derivedValueViews); } return(nonRetainViewFactories); }
public void Attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, IList <ViewFactory> parentViewFactories) { // Find the group by view matching the merge view GroupByViewFactoryMarker groupByViewFactory = null; var unvalidated = _viewParameters.ToArray(); foreach (var parentView in parentViewFactories) { if (!(parentView is GroupByViewFactoryMarker)) { continue; } var candidateGroupByView = (GroupByViewFactoryMarker)parentView; if (ExprNodeUtility.DeepEquals(candidateGroupByView.CriteriaExpressions, unvalidated, false)) { groupByViewFactory = candidateGroupByView; } } if (groupByViewFactory == null) { throw new ViewParameterException("Groupwin view for this merge view could not be found among parent views"); } _criteriaExpressions = groupByViewFactory.CriteriaExpressions; _removable = groupByViewFactory.IsReclaimAged; // determine types of fields var fieldTypes = new Type[_criteriaExpressions.Length]; for (var i = 0; i < fieldTypes.Length; i++) { fieldTypes[i] = _criteriaExpressions[i].ExprEvaluator.ReturnType; } // Determine the readonly event type that the merge view generates // This event type is ultimatly generated by AddPropertyValueView which is added to each view branch for each // group key. // If the parent event type contains the merge fields, we use the same event type var parentContainsMergeKeys = true; var fieldNames = new String[_criteriaExpressions.Length]; for (var i = 0; i < _criteriaExpressions.Length; i++) { var name = ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(_criteriaExpressions[i]); fieldNames[i] = name; try { if (!(parentEventType.IsProperty(name))) { parentContainsMergeKeys = false; } } catch (PropertyAccessException) { // expected parentContainsMergeKeys = false; } } // If the parent view contains the fields to group by, the event type after merging stays the same if (parentContainsMergeKeys) { _eventType = parentEventType; } else // If the parent event type does not contain the fields, such as when a statistics views is // grouped which simply provides a map of calculated values, // then we need to add in the merge field as an event property thus changing event types. { IDictionary <String, Object> additionalProps = new Dictionary <String, Object>(); for (var i = 0; i < fieldNames.Length; i++) { additionalProps.Put(fieldNames[i], fieldTypes[i]); } var outputEventTypeName = statementContext.StatementId + "_mergeview_" + _streamNumber; _eventType = statementContext.EventAdapterService.CreateAnonymousWrapperType(outputEventTypeName, parentEventType, additionalProps); } }