Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }