Ejemplo n.º 1
0
            public static CodegenExpression Codegen(
                IntervalOpDateTimeOffsetForge forge,
                CodegenExpression start,
                CodegenExpression end,
                CodegenExpression parameter,
                Type parameterType,
                CodegenMethodScope codegenMethodScope,
                ExprForgeCodegenSymbol exprSymbol,
                CodegenClassScope codegenClassScope)
            {
                var methodNode = codegenMethodScope
                    .MakeChild(typeof(bool?), typeof(IntervalOpDateTimeOffsetEval), codegenClassScope)
                    .AddParam(typeof(long), "startTs")
                    .AddParam(typeof(long), "endTs")
                    .AddParam(typeof(DateTimeOffset), "parameter");

                methodNode.Block
                    .DeclareVar<long>(
                        "time",
                        StaticMethod(
                            typeof(DatetimeLongCoercerDateTimeOffset),
                            "CoerceToMillis",
                            Ref("parameter")))
                    .MethodReturn(
                        forge.intervalComputer.Codegen(
                            Ref("startTs"),
                            Ref("endTs"),
                            Ref("time"),
                            Ref("time"),
                            methodNode,
                            exprSymbol,
                            codegenClassScope));
                return LocalMethod(methodNode, start, end, parameter);
            }
Ejemplo n.º 2
0
        public IntervalForgeImpl(
            DateTimeMethodEnum method,
            string methodNameUse,
            StreamTypeService streamTypeService,
            IList<ExprNode> expressions,
            TimeAbacus timeAbacus,
            TableCompileTimeResolver tableCompileTimeResolver)
        {
            ExprForge forgeEndTimestamp = null;
            Type timestampType;

            if (expressions[0] is ExprStreamUnderlyingNode) {
                var und = (ExprStreamUnderlyingNode) expressions[0];
                parameterStreamNum = und.StreamId;
                var type = streamTypeService.EventTypes[parameterStreamNum];
                parameterPropertyStart = type.StartTimestampPropertyName;
                if (parameterPropertyStart == null) {
                    throw new ExprValidationException(
                        "For date-time method '" +
                        methodNameUse +
                        "' the first parameter is event type '" +
                        type.Name +
                        "', however no timestamp property has been defined for this event type");
                }

                timestampType = type.GetPropertyType(parameterPropertyStart);
                var getter = ((EventTypeSPI) type).GetGetterSPI(parameterPropertyStart);
                var getterReturnTypeBoxed = type.GetPropertyType(parameterPropertyStart).GetBoxedType();
                ForgeTimestamp = new ExprEvaluatorStreamDTProp(parameterStreamNum, getter, getterReturnTypeBoxed);

                if (type.EndTimestampPropertyName != null) {
                    parameterPropertyEnd = type.EndTimestampPropertyName;
                    var getterEndTimestamp =
                        ((EventTypeSPI) type).GetGetterSPI(type.EndTimestampPropertyName);
                    forgeEndTimestamp = new ExprEvaluatorStreamDTProp(
                        parameterStreamNum,
                        getterEndTimestamp,
                        getterReturnTypeBoxed);
                }
                else {
                    parameterPropertyEnd = parameterPropertyStart;
                }
            }
            else {
                ForgeTimestamp = expressions[0].Forge;
                timestampType = ForgeTimestamp.EvaluationType;

                string unresolvedPropertyName = null;
                if (expressions[0] is ExprIdentNode) {
                    var identNode = (ExprIdentNode) expressions[0];
                    parameterStreamNum = identNode.StreamId;
                    parameterPropertyStart = identNode.ResolvedPropertyName;
                    parameterPropertyEnd = parameterPropertyStart;
                    unresolvedPropertyName = identNode.UnresolvedPropertyName;
                }

                if (!TypeHelper.IsDateTime(ForgeTimestamp.EvaluationType)) {
                    // ident node may represent a fragment
                    if (unresolvedPropertyName != null) {
                        var propertyDesc = ExprIdentNodeUtil.GetTypeFromStream(
                            streamTypeService,
                            unresolvedPropertyName,
                            false,
                            true,
                            tableCompileTimeResolver);
                        if (propertyDesc.First.FragmentEventType != null) {
                            var type = propertyDesc.First.FragmentEventType.FragmentType;
                            parameterPropertyStart = type.StartTimestampPropertyName;
                            if (parameterPropertyStart == null) {
                                throw new ExprValidationException(
                                    "For date-time method '" +
                                    methodNameUse +
                                    "' the first parameter is event type '" +
                                    type.Name +
                                    "', however no timestamp property has been defined for this event type");
                            }

                            timestampType = type.GetPropertyType(parameterPropertyStart);
                            var getterFragment =
                                ((EventTypeSPI) streamTypeService.EventTypes[parameterStreamNum]).GetGetterSPI(
                                    unresolvedPropertyName);
                            var getterStartTimestamp =
                                ((EventTypeSPI) type).GetGetterSPI(parameterPropertyStart);
                            ForgeTimestamp = new ExprEvaluatorStreamDTPropFragment(
                                parameterStreamNum,
                                getterFragment,
                                getterStartTimestamp);

                            if (type.EndTimestampPropertyName != null) {
                                parameterPropertyEnd = type.EndTimestampPropertyName;
                                var getterEndTimestamp =
                                    ((EventTypeSPI) type).GetGetterSPI(type.EndTimestampPropertyName);
                                forgeEndTimestamp = new ExprEvaluatorStreamDTPropFragment(
                                    parameterStreamNum,
                                    getterFragment,
                                    getterEndTimestamp);
                            }
                            else {
                                parameterPropertyEnd = parameterPropertyStart;
                            }
                        }
                    }
                    else {
                        throw new ExprValidationException(
                            "For date-time method '" +
                            methodNameUse +
                            "' the first parameter expression returns '" +
                            ForgeTimestamp.EvaluationType +
                            "', however requires a Date, DateTimeEx, Long-type return value or event (with timestamp)");
                    }
                }
            }

            var intervalComputerForge =
                IntervalComputerForgeFactory.Make(method, expressions, timeAbacus);

            // evaluation without end timestamp
            var timestampTypeBoxed = timestampType.GetBoxedType();
            if (forgeEndTimestamp == null) {
                if (TypeHelper.IsSubclassOrImplementsInterface(timestampType, typeof(DateTimeEx))) {
                    IntervalOpForge = new IntervalOpDateTimeExForge(intervalComputerForge);
                }
                else if (timestampTypeBoxed == typeof(long?)) {
                    IntervalOpForge = new IntervalOpForgeLong(intervalComputerForge);
                }
                else if (timestampTypeBoxed == typeof(DateTimeOffset?)) {
                    IntervalOpForge = new IntervalOpDateTimeOffsetForge(intervalComputerForge);
                }
                else if (timestampTypeBoxed == typeof(DateTime?)) {
                    IntervalOpForge = new IntervalOpDateTimeForge(intervalComputerForge);
                }
                else {
                    throw new ArgumentException("Invalid interval first parameter type '" + timestampType + "'");
                }
            }
            else {
                if (TypeHelper.IsSubclassOrImplementsInterface(timestampType, typeof(DateTimeEx))) {
                    IntervalOpForge = new IntervalOpDateTimeExWithEndForge(intervalComputerForge, forgeEndTimestamp);
                }
                else if (timestampTypeBoxed == typeof(long?)) {
                    IntervalOpForge = new IntervalOpLongWithEndForge(intervalComputerForge, forgeEndTimestamp);
                }
                else if (timestampTypeBoxed == typeof(DateTimeOffset?)) {
                    IntervalOpForge = new IntervalOpDateTimeOffsetWithEndForge(
                        intervalComputerForge,
                        forgeEndTimestamp);
                }
                else if (timestampTypeBoxed == typeof(DateTime?)) {
                    IntervalOpForge = new IntervalOpDateTimeWithEndForge(intervalComputerForge, forgeEndTimestamp);
                }
                else {
                    throw new ArgumentException("Invalid interval first parameter type '" + timestampType + "'");
                }
            }
        }