Esempio n. 1
0
        private void UpdateInternal(EventBean[] eventsPerStream, ExprEvaluatorContext exprEvaluatorContext, EventBean target)
        {
            var evaluateParams = new EvaluateParams(eventsPerStream, true, exprEvaluatorContext);

            for (int i = 0; i < _updateItems.Length; i++)
            {
                EventBeanUpdateItem updateItem = _updateItems[i];

                if (InstrumentationHelper.ENABLED)
                {
                    InstrumentationHelper.Get().QInfraUpdateRHSExpr(i, updateItem);
                }
                Object result = updateItem.Expression.Evaluate(evaluateParams);
                if (InstrumentationHelper.ENABLED)
                {
                    InstrumentationHelper.Get().AInfraUpdateRHSExpr(result);
                }

                if (updateItem.OptionalWriter != null)
                {
                    if (result == null && updateItem.IsNotNullableField)
                    {
                        Log.Warn("Null value returned by expression for assignment to property '" + updateItem.OptionalPropertyName + " is ignored as the property type is not nullable for expression");
                        continue;
                    }

                    if (updateItem.OptionalWidener != null)
                    {
                        result = updateItem.OptionalWidener.Invoke(result);
                    }
                    updateItem.OptionalWriter.Write(result, target);
                }
            }
        }
Esempio n. 2
0
        public static EventBeanUpdateHelper Make(
            string updatedWindowOrTableName,
            EventTypeSPI eventTypeSPI,
            IList <OnTriggerSetAssignment> assignments,
            string updatedAlias,
            EventType optionalTriggeringEventType,
            bool isCopyOnWrite)
        {
            IList <EventBeanUpdateItem> updateItems = new List <EventBeanUpdateItem>();
            IList <string> properties = new List <string>();

            for (var i = 0; i < assignments.Count; i++)
            {
                var assignment = assignments[i];
                EventBeanUpdateItem updateItem;

                // determine whether this is a "property=value" assignment, we use property setters in this case
                var possibleAssignment = ExprNodeUtility.CheckGetAssignmentToProp(assignment.Expression);

                // handle assignment "property = value"
                if (possibleAssignment != null)
                {
                    var propertyName     = possibleAssignment.First;
                    var writableProperty = eventTypeSPI.GetWritableProperty(propertyName);

                    // check assignment to indexed or mapped property
                    if (writableProperty == null)
                    {
                        var nameWriteablePair = CheckIndexedOrMappedProp(possibleAssignment.First, updatedWindowOrTableName, updatedAlias, eventTypeSPI);
                        propertyName     = nameWriteablePair.First;
                        writableProperty = nameWriteablePair.Second;
                    }

                    var evaluator        = possibleAssignment.Second.ExprEvaluator;
                    var writers          = eventTypeSPI.GetWriter(propertyName);
                    var notNullableField = writableProperty.PropertyType.IsPrimitive;

                    properties.Add(propertyName);
                    var widener = TypeWidenerFactory.GetCheckPropertyAssignType(ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(possibleAssignment.Second), possibleAssignment.Second.ExprEvaluator.ReturnType,
                                                                                writableProperty.PropertyType, propertyName);

                    // check event type assignment
                    if (optionalTriggeringEventType != null && possibleAssignment.Second is ExprIdentNode)
                    {
                        var node        = (ExprIdentNode)possibleAssignment.Second;
                        var fragmentRHS = optionalTriggeringEventType.GetFragmentType(node.ResolvedPropertyName);
                        var fragmentLHS = eventTypeSPI.GetFragmentType(possibleAssignment.First);
                        if (fragmentRHS != null && fragmentLHS != null && !EventTypeUtility.IsTypeOrSubTypeOf(fragmentRHS.FragmentType, fragmentLHS.FragmentType))
                        {
                            throw new ExprValidationException("Invalid assignment to property '" +
                                                              possibleAssignment.First + "' event type '" + fragmentLHS.FragmentType.Name +
                                                              "' from event type '" + fragmentRHS.FragmentType.Name + "'");
                        }
                    }

                    updateItem = new EventBeanUpdateItem(evaluator, propertyName, writers, notNullableField, widener);
                }
                // handle non-assignment, i.e. UDF or other expression
                else
                {
                    var evaluator = assignment.Expression.ExprEvaluator;
                    updateItem = new EventBeanUpdateItem(evaluator, null, null, false, null);
                }

                updateItems.Add(updateItem);
            }

            // copy-on-write is the default event semantics as events are immutable
            EventBeanCopyMethod copyMethod;

            if (isCopyOnWrite)
            {
                // obtain copy method
                IList <string> propertiesUniqueList = new List <string>(new HashSet <string>(properties));
                var            propertiesArray      = propertiesUniqueList.ToArray();
                copyMethod = eventTypeSPI.GetCopyMethod(propertiesArray);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Event type does not support event bean copy");
                }
            }
            else
            {
                // for in-place update, determine assignment expressions to use "initial" to access prior-change values
                // the copy-method is optional
                copyMethod = null;
                var propertiesInitialValue = DeterminePropertiesInitialValue(assignments);
                if (!propertiesInitialValue.IsEmpty())
                {
                    var propertiesInitialValueArray = propertiesInitialValue.ToArray();
                    copyMethod = eventTypeSPI.GetCopyMethod(propertiesInitialValueArray);
                }
            }

            var updateItemsArray = updateItems.ToArray();

            return(new EventBeanUpdateHelper(copyMethod, updateItemsArray));
        }