Пример #1
0
        public void TestCalculationExpressionWithDies()
        {
            var d1 = new DiceExpression("1d6");
            var d2 = new DiceExpression("1d8");

            var ce = new CalculationExpression("+", d1, d2);

            Assert.AreEqual(8, ce.GetExpected());
            Assert.AreEqual(2, ce.GetMin());
            Assert.AreEqual(14, ce.GetMax());

            ce = new CalculationExpression("-", d1, d2);
            Assert.AreEqual(-1, ce.GetExpected());
            Assert.AreEqual(-7, ce.GetMin());
            Assert.AreEqual(5, ce.GetMax());

            ce = new CalculationExpression("*", d1, d2);
            Assert.AreEqual(3.5 * 4.5, ce.GetExpected());
            Assert.AreEqual(1, ce.GetMin());
            Assert.AreEqual(48, ce.GetMax());

            ce = new CalculationExpression("/", d1, d2);
            Assert.AreEqual(3.5 / 4.5, ce.GetExpected());
            Assert.AreEqual(0.125, ce.GetMin());
            Assert.AreEqual(6, ce.GetMax());
        }
Пример #2
0
        public void TestCalculationExpressionWithConstants()
        {
            var const1 = new ConstantExpression("1");
            var const2 = new ConstantExpression("-1");

            var ce = new CalculationExpression("+", const1, const2);

            Assert.AreEqual(0, ce.GetExpected());
            Assert.AreEqual(0, ce.GetMin());
            Assert.AreEqual(0, ce.GetMax());
            Assert.AreEqual(0, ce.Roll());

            ce = new CalculationExpression("-", const1, const2);
            Assert.AreEqual(2, ce.GetExpected());
            Assert.AreEqual(2, ce.GetMin());
            Assert.AreEqual(2, ce.GetMax());
            Assert.AreEqual(2, ce.Roll());

            ce = new CalculationExpression("*", const1, const2);
            Assert.AreEqual(-1, ce.GetExpected());
            Assert.AreEqual(-1, ce.GetMin());
            Assert.AreEqual(-1, ce.GetMax());
            Assert.AreEqual(-1, ce.Roll());

            ce = new CalculationExpression("/", const1, const2);
            Assert.AreEqual(-1, ce.GetExpected());
            Assert.AreEqual(-1, ce.GetMin());
            Assert.AreEqual(-1, ce.GetMax());
            Assert.AreEqual(-1, ce.Roll());
        }
Пример #3
0
        public void TestCalculationExpressionWithCalculations()
        {
            var const1 = new ConstantExpression("1");
            var const2 = new ConstantExpression("-1");
            var d1     = new DiceExpression("1d6");
            var d2     = new DiceExpression("1d8");

            var ce = new CalculationExpression("+", new CalculationExpression("+", d1, d2), new CalculationExpression("+", const1, const2));

            Assert.AreEqual(8, ce.GetExpected());
            Assert.AreEqual(2, ce.GetMin());
            Assert.AreEqual(14, ce.GetMax());
        }
Пример #4
0
        protected override ScalarExpression OnBuildQuery(QueryBuilderContext context)
        {
            var result = new CalculationExpression
            {
                Operator     = CalculationOperator.DateName,
                DateTimePart = DateTimePart,
                Expressions  = new List <ScalarExpression>
                {
                    Argument.BuildQuery(context)
                }
            };

            return(result);
        }
Пример #5
0
        /// <summary>
        /// Convert the expression tree into a structured query expression.
        /// </summary>
        /// <param name="context">Context information about this query building session, including the target structured query object.</param>
        /// <returns>A scalar expression that can be used within the query.</returns>
        protected virtual ScalarExpression OnBuildQuery(QueryBuilderContext context)
        {
            // Reflect for attributes
            Type type = GetType();
            var  queryEngAttribute = GetQueryEngineOperator(type);

            if (queryEngAttribute == null)
            {
                throw new NotImplementedException(type.Name);
            }

            // Build arguments
            var arguments = new List <ScalarExpression>();

            foreach (ExpressionNode argument in Arguments)
            {
                ScalarExpression queryExpr = argument.BuildQuery(context);
                arguments.Add(queryExpr);
            }

            // Generic Calculation Expression
            if (queryEngAttribute.CalculationOperator != null)
            {
                var result = new CalculationExpression();
                result.Operator    = queryEngAttribute.CalculationOperator.Value;
                result.Expressions = arguments;
                return(result);
            }

            // Generic Comparison Expression
            if (queryEngAttribute.ComparisonOperator != null)
            {
                var result = new ComparisonExpression();
                result.Operator    = queryEngAttribute.ComparisonOperator.Value;
                result.Expressions = arguments;
                return(result);
            }

            // Generic Comparison Expression
            if (queryEngAttribute.LogicalOperator != null)
            {
                var result = new LogicalExpression();
                result.Operator    = queryEngAttribute.LogicalOperator.Value;
                result.Expressions = arguments;
                return(result);
            }

            throw new InvalidOperationException(type.Name);
        }
Пример #6
0
        protected override ScalarExpression OnBuildQuery(QueryBuilderContext context)
        {
            var result = new CalculationExpression
            {
                Operator     = CalculationOperator.DateAdd,
                DateTimePart = DateTimePart,
                InputType    = InputType.Type,
                Expressions  = new List <ScalarExpression>
                {
                    // Caution.. CalculationOperator.DateAdd was implemented backwards
                    Right.BuildQuery(context),
                    Left.BuildQuery(context)
                }
            };

            return(result);
        }
Пример #7
0
        public static ScalarExpression CastPrecision(ScalarExpression decimalExpression, int precision)
        {
            var result = new CalculationExpression
            {
                Operator    = CalculationOperator.Cast,
                CastType    = DatabaseType.DecimalType,
                Expressions = new List <ScalarExpression>
                {
                    decimalExpression,
                    new LiteralExpression {
                        Value = new EDC.ReadiNow.Metadata.TypedValue(precision)
                    }
                }
            };

            return(result);
        }
Пример #8
0
        protected override ScalarExpression OnBuildQuery(QueryBuilderContext context)
        {
            DatabaseType dbType = DataTypeHelper.ToDatabaseType(ResultType.Type);

            ScalarExpression argument = Argument.BuildQuery(context);
            var result = new CalculationExpression
            {
                Expressions = new List <ScalarExpression>
                {
                    argument
                },
                Operator    = CalculationOperator.Cast,
                CastType    = dbType,
                DisplayType = dbType,
                InputType   = Argument.ResultType.Type
            };

            return(result);
        }
Пример #9
0
        protected override ScalarExpression OnBuildQuery(QueryBuilderContext context)
        {
            ScalarExpression arg = Argument.BuildQuery(context);

            if (ResultType.Type == DataType.Entity)
            {
                return(arg);
            }

            // Special case for AggregateExpression, because if we aggregate a choicefield, then it presents
            // as an Entity type, therefore requesting this cast - but the query builder wants to receive the aggregate expression directly.
            if (arg is EDC.ReadiNow.Metadata.Query.Structured.AggregateExpression)
            {
                var result = new MutateExpression {
                    Expression = arg
                };

                switch (ResultType.Type)
                {
                case DataType.String:
                    result.MutateType = MutateType.DisplaySql;
                    break;

                case DataType.Bool:
                    result.MutateType = MutateType.BoolSql;
                    break;

                default:
                    throw new InvalidOperationException(ResultType.Type.ToString( ));
                }
                return(result);
            }

            // Just refer to the node
            var queryNode = context.GetNode(Argument);

            switch (ResultType.Type)
            {
            case DataType.String:
                var nameResult = new ResourceDataColumn
                {
                    FieldId = "core:name",
                    NodeId  = queryNode.NodeId
                };
                return(nameResult);

            case DataType.Bool:
                var boolResult = new CalculationExpression
                {
                    Operator    = CalculationOperator.IsNull,
                    Expressions = new List <ScalarExpression>
                    {
                        new IdExpression {
                            NodeId = queryNode.NodeId
                        }
                    }
                };
                return(boolResult);

            default:
                throw new InvalidOperationException(ResultType.Type.ToString());
            }
        }
Пример #10
0
        /// <summary>
        /// Create a structured query that will return types/objects matching a particular name.
        /// </summary>
        /// <remarks>
        /// Returns objects, system types, enums, and activity types. But not other things that derive from type (such as fieldType).
        /// </remarks>
        /// <returns>
        /// StructuredQuery with a @scriptName query parameter.
        /// </returns>
        private static StructuredQuery BuildTypeByNameQuery()
        {
            // List of types that we allow to be referenced by names
            long[] allowedTypeTypes = new[] {
                Definition.Definition_Type.Id,
                ManagedType.ManagedType_Type.Id,
                EntityType.EntityType_Type.Id,
                EnumType.EnumType_Type.Id,
                ActivityType.ActivityType_Type.Id
            };

            // Create the structured query
            var rootEntity = new ResourceEntity(new EntityRef(WellKnownAliases.CurrentTenant.Type));
            var typeType   = new RelatedResource(new EntityRef(WellKnownAliases.CurrentTenant.IsOfType));

            rootEntity.RelatedEntities.Add(typeType);
            var query = new StructuredQuery()
            {
                RootEntity = rootEntity
            };
            var col = new SelectColumn {
                Expression = new SQ.IdExpression {
                    NodeId = rootEntity.NodeId
                }
            };

            query.SelectColumns.Add(col);

            // Allowed-type condition
            var typeCondition = new QueryCondition
            {
                Expression = new SQ.IdExpression {
                    NodeId = typeType.NodeId
                },
                Operator  = ConditionType.AnyOf,
                Arguments = allowedTypeTypes.Select(id => new TypedValue()
                {
                    Value = id, Type = DatabaseType.IdentifierType
                }).ToList()
            };

            query.Conditions.Add(typeCondition);

            // Script-name condition
            var calcExpr = new CalculationExpression
            {
                Operator    = CalculationOperator.IsNull,
                Expressions = new List <ScalarExpression>
                {
                    new ResourceDataColumn(rootEntity, new EntityRef("core:typeScriptName")),
                    new ResourceDataColumn(rootEntity, new EntityRef("core:name")),
                }
            };
            var nameCondition = new QueryCondition
            {
                Expression = calcExpr,
                Operator   = ConditionType.Equal,
                Parameter  = "@scriptName"
            };

            query.Conditions.Add(nameCondition);

            return(query);
        }
        private static IExpression ParseInternal(string formula, Random random, Dictionary <string, string> substitutionDictionary)
        {
            IExpression result = null;
            var         reg    = new Regex("#[0-9]+#");

            if (reg.Match(formula).Value.Equals(formula))
            {
                formula = substitutionDictionary[formula];
            }

            // Add + Subtract
            var subExpr = formula.Split(new[] { '+', '-' });

            if (subExpr.Length > 1)
            {
                var opsString = (string)formula.Clone();
                foreach (var sub in subExpr)
                {
                    opsString = opsString.Remove(opsString.IndexOf(sub, StringComparison.InvariantCulture), sub.Length);
                }
                var ops  = opsString.ToCharArray();
                var expr = subExpr.Select(f => ParseInternal(f, random, substitutionDictionary)).ToList();
                result = new CalculationExpression(ops[0].ToString(), expr[0], expr[1]);
                for (var i = 2; i < expr.Count; i++)
                {
                    result = new CalculationExpression(ops[i - 1].ToString(), result, expr[i]);
                }
            }
            if (result != null)
            {
                return(result);
            }


            // Multiply + Divide
            subExpr = formula.Split(new[] { '*', '/' });
            if (subExpr.Length > 1)
            {
                var opsString = (string)formula.Clone();
                foreach (var sub in subExpr)
                {
                    opsString = opsString.Remove(opsString.IndexOf(sub, StringComparison.InvariantCulture), sub.Length);
                }
                var ops  = opsString.ToCharArray();
                var expr = subExpr.Select(f => ParseInternal(f, random, substitutionDictionary)).ToList();
                result = new CalculationExpression(ops[0].ToString(), expr[0], expr[1]);
                for (var i = 2; i < expr.Count; i++)
                {
                    result = new CalculationExpression(ops[i - 1].ToString(), result, expr[i]);
                }
            }
            if (result != null)
            {
                return(result);
            }

            // Dice
            if (formula.Contains("d"))
            {
                result = new DiceExpression(formula, random);
            }
            if (result != null)
            {
                return(result);
            }

            // Constant
            result = new ConstantExpression(formula);

            return(result);
        }