Exemplo n.º 1
0
        public static IEnumerable <RewriteRule> AtomInvokeParam(SqlExprParams pars)
        {
            var invokeRule = RewriteRule.Create(
                "atomInvokeParam",
                () => RewriteSpecial.Call <RewriteTypes.C2>(null, "Invoke"),
                null,
                null,
                (match, expr, visit) =>
            {
                var exprCall = (MethodCallExpression)expr;
                var origArgs = exprCall.Arguments;

                //Aplicar la transformación del from a los parametros, esto es importante porque el from
                //en algunos casos se usa sólo para especificar el tipo en un método generico pero su valor
                //no es importante.
                var fromArgs = origArgs
                               .Select(x => Rewriter.RecApplyRules(x, ExprParamsRules(pars), ExcludeFromRewrite))
                               .ToList()
                ;

                var arg  = fromArgs[0];
                var args = fromArgs;

                var atomArg  = Expression.Call(typeof(RewriteSpecial), "Atom", new[] { arg.Type }, arg);
                var atomArgs = new[] { atomArg }.Concat(args.Skip(1)).ToList();



                var retCall = Expression.Call(exprCall.Object, exprCall.Method, atomArgs);
                return(retCall);
            });

            return(new[] { invokeRule });
        }
Exemplo n.º 2
0
        public void EvalBooleanRule()
        {
            //Evalua las expresiones booleanas, sólo se aplica la regla si la expresión no es ya una constante
            var evalBool = RewriteRule.Create("", (bool x) => RewriteSpecial.NotConstant(x), null, null, (_, x, visit) => ExprEval.EvalExprExpr(x));

            var rules = new[]
            {
                evalBool
            };

            var a = true;
            Expression <Func <bool, bool, bool> > expr = (x, y) => x && y || !(true || a);
            var red = ApplyRules(expr, rules);

            //Note que la expresión !(true || a) se evaluó por completo:
            Assert.AreEqual("(x, y) => ((x AndAlso y) OrElse False)", red.ToString());
        }
Exemplo n.º 3
0
        public static IEnumerable <RewriteRule> ExprParamsRules(SqlExprParams pars)
        {
            var ret = new List <RewriteRule>();

            //Puede ser null el param en caso de que todo sea por sustituciones del replace
            if (pars.Param != null)
            {
                //Es posible que el fromParam este envuelto en un Convert, por ejemplo cuando se usan propiedades de una interfaz
                ret.Add(
                    RewriteRule.Create(
                        "convertFromParam",
                        (RewriteTypes.C1 p) => RewriteSpecial.Operator <RewriteTypes.C1, RewriteTypes.C2>(p, ExpressionType.Convert),
                        (RewriteTypes.C1 p) => Sql.FromParam <RewriteTypes.C2>(),
                        (match, expr) => match.Args[0] == pars.Param
                        ));

                ret.Add(
                    new RewriteRule(
                        "fromParam",
                        Expression.Lambda(pars.Param), Expression.Lambda(Expression.Call(typeof(Sql), nameof(Sql.FromParam), new[] { pars.Param.Type })), null, null)
                    );
            }
            return(ret);
        }
Exemplo n.º 4
0
        /// <summary>
        /// La regla que se aplica a las llamadas Atom(Raw(x)), lo que hace es convertir las llamadas ToSql del Atom(Raw(x))
        /// </summary>
        public static IEnumerable <RewriteRule> AtomRawRule(SqlExprParams pars)
        {
            var deferredToSqlRule = RewriteRule.Create(
                "deferredToSql",
                (RewriteTypes.C1 x) => SqlFunctions.ToSql <RewriteTypes.C1>(x),
                null,
                null,
                (match, expr, visit) => Expression.Call(
                    typeof(SqlExpression),
                    nameof(SqlExpression.ExprToSql),
                    new Type[0],
                    Expression.Constant(match.Args[0]),
                    Expression.Constant(pars),
                    Expression.Constant(true)));

            var toSqlRule = RewriteRule.Create(
                "toSql",
                () => RewriteSpecial.Call <string>(typeof(SqlFunctions), nameof(ToSql)),
                null,
                null,
                (match, expr, visit) => Expression.Constant(SqlExpression.ExprToSql(((MethodCallExpression)expr).Arguments[0], pars, true)));

            var toSelectBodySqlRule = RewriteRule.Create(
                "toSelectBodySqlRule",
                () => RewriteSpecial.Call <string>(typeof(SqlFunctions), nameof(ToSelectBodySql)),
                null,
                null,
                (match, expr, visit) =>
                Expression.Constant(
                    SqlSelect.SelectExprToStr(SqlSelect.SelectBodyToStr(((MethodCallExpression)expr).Arguments[0], pars).Values)
                    )
                );
            var windowToSqlRule = RewriteRule.Create(
                "windowToSql",
                (ISqlWindow a) => WindowToSql(a),
                null,
                null,
                (match, expr, visit) => Expression.Constant(SqlCalls.WindowToSql(match.Args[0]))
                );
            var toSqlRules = new[]
            {
                toSelectBodySqlRule,
                toSqlRule,
                windowToSqlRule
            };
            Func <Expression, Expression> applySqlRule = (Expression ex) => new RewriteVisitor(toSqlRules, ExcludeFromRewrite).Visit(ex);

            var atomRawRule = RewriteRule.Create(
                "executeAtomRaw",
                (string x) => RewriteSpecial.Atom(Sql.Raw <RewriteTypes.C1>(RewriteSpecial.NotConstant(x))),
                null,
                null,
                (match, expr, visit) =>
            {
                var arg      = match.Args[0];
                var applySql = applySqlRule(arg);
                if (applySql == arg)
                {
                    return(expr);
                }

                var type  = match.Types[typeof(RewriteTypes.C1)];
                var value = ExprEval.EvalExpr <string>(applySql).Value;

                var ret = Expression.Call(typeof(RewriteSpecial), nameof(RewriteSpecial.Atom), new[] { type },
                                          Expression.Call(typeof(Sql), nameof(Sql.Raw), new[] { type }, Expression.Constant(value))
                                          );

                return(ret);
            });

            return(new[] { atomRawRule });
        }