예제 #1
0
        public static void MatchInvoke()
        {
            var name = ObjectName.Parse("a.func");
            var info = new SqlFunctionInfo(name, PrimitiveTypes.Integer());

            info.Parameters.Add(new SqlParameterInfo("a", PrimitiveTypes.Integer()));

            var function = new SqlFunctionDelegate(info, context => Task.CompletedTask);

            var invoke = new Invoke(name, new [] { new InvokeArgument(SqlObject.BigInt(11)) });

            Assert.True(function.Matches(null, invoke));
        }
예제 #2
0
        internal MethodContext(IContext context, SqlMethod method, Invoke invoke)
            : base(context, $"Method({method.MethodInfo.MethodName})")
        {
            Invoke = invoke;
            Method = method;

            namedArgs = BuildArguments(method.MethodInfo, invoke);

            ResultValue = SqlExpression.Constant(SqlObject.Null);
            output      = new Dictionary <string, SqlExpression>();

            Metadata = new Dictionary <string, object>();
        }
예제 #3
0
        internal MethodContext(IContext context, SqlMethod method, Invoke invoke)
            : base(context, method.Type == MethodType.Function ? "function" : "procedure")
        {
            Invoke = invoke;
            Method = method;

            namedArgs = BuildArguments(method.MethodInfo, invoke);

            ResultValue = SqlExpression.Constant(SqlObject.Null);
            output      = new Dictionary <string, SqlExpression>();

            Metadata = new Dictionary <string, object>();
        }
예제 #4
0
        public static bool IsSystemFunction(this IContext context, ObjectName name, params InvokeArgument[] arguments)
        {
            var invoke    = new Invoke(name, arguments);
            var resolvers = context.Scope.ResolveAll <IMethodResolver>();

            foreach (var resolver in resolvers)
            {
                var method = resolver.ResolveMethod(context, invoke);
                if (method != null && method.IsFunction && method.IsSystem)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        public static void CreateInvokeWithNamedArguments(string methodName, string argName1, object value1, string argName2, object value2)
        {
            var name = ObjectName.Parse(methodName);
            var arg1 = SqlExpression.Constant(SqlObject.New(SqlValueUtil.FromObject(value1)));
            var arg2 = SqlExpression.Constant(SqlObject.New(SqlValueUtil.FromObject(value2)));

            var invoke = new Invoke(name);

            invoke.Arguments.Add(new InvokeArgument(argName1, arg1));
            invoke.Arguments.Add(new InvokeArgument(argName2, arg2));

            Assert.Equal(name, invoke.MethodName);
            Assert.Equal(2, invoke.Arguments.Count);
            Assert.True(invoke.IsNamed);
            Assert.True(invoke.Arguments[0].IsNamed);
            Assert.True(invoke.Arguments[1].IsNamed);
        }
예제 #6
0
        public async Task <SqlMethodResult> ExecuteAsync(IContext context, Invoke invoke)
        {
            using (var methodContext = new MethodContext(context, this, invoke)) {
                try {
                    await ExecuteContextAsync(methodContext);
                } catch (MethodException) {
                    throw;
                } catch (Exception ex) {
                    throw new MethodException($"Error while executing {MethodInfo.MethodName}: see inner exception for more information", ex);
                }

                var result = methodContext.CreateResult();

                result.Validate(this, context);

                return(result);
            }
        }
예제 #7
0
        public static void SetAnonArgumentToNamedContext()
        {
            var name = ObjectName.Parse("sys.func1");
            var arg1 = SqlExpression.Constant(SqlObject.New(SqlValueUtil.FromObject(3452)));
            var arg2 = SqlExpression.Constant(SqlObject.New(SqlValueUtil.FromObject(false)));

            var invoke = new Invoke(name);

            invoke.Arguments.Add(new InvokeArgument("a", arg1));
            invoke.Arguments.Add(new InvokeArgument("b", arg2));

            Assert.Equal(name, invoke.MethodName);
            Assert.Equal(2, invoke.Arguments.Count);
            Assert.True(invoke.IsNamed);
            Assert.True(invoke.Arguments[0].IsNamed);
            Assert.True(invoke.Arguments[1].IsNamed);

            Assert.Throws <ArgumentException>(() => invoke.Arguments[0] = new InvokeArgument(invoke.Arguments[0].Value));
        }
        public override bool Matches(IContext context, Invoke invoke)
        {
            var ignoreCase = context.IgnoreCase();

            if (!MethodInfo.MethodName.Equals(invoke.MethodName, ignoreCase))
            {
                return(false);
            }

            if (invoke.Arguments == null)
            {
                return(MethodInfo.Parameters.Count == 0);
            }

            if (invoke.Arguments.Any(x => !(x.Value is SqlReferenceExpression)))
            {
                return(false);
            }

            return(true);
        }
예제 #9
0
        public void RegisterAndResolveFunction()
        {
            var name = ObjectName.Parse("a.func");
            var info = new SqlFunctionInfo(name, PrimitiveTypes.Integer());

            info.Parameters.Add(new SqlParameterInfo("a", PrimitiveTypes.Integer()));
            var function = new SqlFunctionDelegate(info, ctx => {
                var a = ctx.Value("a");
                return(Task.FromResult(a.Multiply(SqlObject.BigInt(2))));
            });

            registry.Register(function);

            var invoke = new Invoke(name);

            invoke.Arguments.Add(new InvokeArgument("a", SqlObject.Integer(11)));

            var method = (registry as IMethodResolver).ResolveMethod(context, invoke);

            Assert.NotNull(method);
            Assert.True(method.IsFunction);
            Assert.Equal(name, method.MethodInfo.MethodName);
        }
예제 #10
0
 public ArgumentList(Invoke invoke)
 {
     this.invoke = invoke;
 }
예제 #11
0
 public virtual bool Matches(IContext context, Invoke invoke)
 {
     return(MethodInfo.Matches(context, ValidateInvoke, invoke));
 }
예제 #12
0
        private static Dictionary <string, SqlExpression> BuildArguments(SqlMethodInfo methodInfo, Invoke invoke)
        {
            var result = new Dictionary <string, SqlExpression>();

            if (invoke.IsNamed)
            {
                var invokeArgs   = invoke.Arguments.ToDictionary(x => x.Name, y => y.Value);
                var methodParams = methodInfo.Parameters.ToDictionary(x => x.Name, y => y);

                foreach (var invokeArg in invokeArgs)
                {
                    SqlParameterInfo paramInfo;
                    if (!methodParams.TryGetValue(invokeArg.Key, out paramInfo))
                    {
                        throw new InvalidOperationException(
                                  $"Invoke argument {invokeArg.Key} does not correspond to any parameter of the method");
                    }

                    result[invokeArg.Key] = invokeArg.Value;
                }

                foreach (var methodParam in methodParams)
                {
                    if (!result.ContainsKey(methodParam.Key))
                    {
                        var paramInfo = methodParam.Value;
                        if (paramInfo.IsRequired)
                        {
                            throw new InvalidOperationException(
                                      $"The invoke to {methodInfo.MethodName} has no value for required parameter {paramInfo.Name} and no default value was set");
                        }

                        result[methodParam.Key] = paramInfo.DefaultValue;
                    }
                }
            }
            else
            {
                if (methodInfo.Parameters.Count != invoke.Arguments.Count)
                {
                    throw new NotSupportedException($"Invoke arguments mismatch the number of parameters of {methodInfo.MethodName}");
                }

                for (int i = 0; i < methodInfo.Parameters.Count; i++)
                {
                    var parmInfo = methodInfo.Parameters[i];
                    result[parmInfo.Name] = invoke.Arguments[i].Value;
                }
            }

            return(result);
        }