示例#1
0
        /// <summary>
        /// Call a function
        /// </summary>
        /// <param name="tree">Tree to be executed</param>
        /// <returns>The result of the function</returns>
        private KObject Call(KermitAST tree)
        {
            string    fName    = tree.GetChild(0).Text;
            KFunction function = GetFunction(fName);

            if (function == null)
            {
                ThrowHelper.NameNotExists(fName, StackTrace);
                //Listener.Error($"Function name {fName} is not defined");
                return(null);
            }

            int argCount = tree.ChildCount - 1;

            if (!function.IsNative &&
                (function.Value.Arguments == null && argCount > 0 ||
                 function.Value.Arguments != null && argCount != function.Value.Arguments.Count))
            {
                ThrowHelper.TypeError($"Function {fName} takes {argCount} arguments", StackTrace);
                //Listener.Error($"Function {fName}: argument list mismatch");
                return(null);
            }

            List <KLocal> param     = new List <KLocal>(argCount);
            var           arguments = function.Value.Arguments.Values.GetEnumerator();

            for (int i = 0; i < argCount; ++i)
            {
                arguments.MoveNext();
                string    name         = function.IsNative ? "" : arguments.Current.Name;
                KermitAST argumentTree = (KermitAST)tree.GetChild(i + 1);
                KLocal    var;
                if (argumentTree.Type == KermitParser.REF)
                {
                    var = new KGlobal(name, argumentTree.GetChild(0).Text, _currentSpace);
                }
                else
                {
                    KObject argumentValue = Execute(argumentTree);
                    var = new KLocal(name, argumentValue);
                }
                param.Add(var);
            }

            return(CallFunction(function, param));
        }
示例#2
0
        /// <summary>
        /// Execute a function inside the interpreter
        /// </summary>
        /// <param name="function">Function to be executed</param>
        /// <param name="parameters">Parameters to be passed to a function</param>
        /// <returns>The result of the function</returns>
        public override KObject CallFunction(KFunction function, List <KLocal> parameters)
        {
            FunctionSymbol fSymbol = function.Value;

            FunctionSpace fSpace     = new FunctionSpace(fSymbol);
            MemorySpace   savedSpace = _currentSpace;

            _currentSpace = fSpace;

            if (!function.IsNative)
            {
                parameters.ForEach(x => fSpace[x.Name] = x);
            }

            KObject result = null;

            _stack.Push(fSpace);
            try
            {
                if (function.IsNative)
                {
                    FunctionCallbackInfo cInfo = new FunctionCallbackInfo(parameters, this);
                    ((NativeFunctionSymbol)fSymbol).NativeFunction.SafeExecute(cInfo);
                    result = cInfo.ReturnValue.Value;
                }
                else
                {
                    Execute(fSymbol.BlockAst);
                }
            }
            catch (ReturnValue returnValue)
            {
                result = returnValue.Value;
            }
            finally
            {
                _currentSpace = savedSpace;
            }
            _stack.Pop();
            return(result);
        }
示例#3
0
 /// <summary>
 /// Call a function
 /// </summary>
 /// <param name="function">The function to be called</param>
 /// <param name="parameters">The parameters to be passed to the function</param>
 /// <returns>The result of the call</returns>
 public abstract KObject CallFunction(KFunction function, List <KLocal> parameters);
        private List <KFunction> CreateSqlFunctionsInDb(KDataStoreProject kDataStoreProject, string connectionString, string sqlText)
        {
            var functions = new List <KFunction>();

            var scriptGen = new Sql120ScriptGenerator(new SqlScriptGeneratorOptions {
                IncludeSemicolons = true
            });

            using (var sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                var parser = new TSql120Parser(false);

                var script2 = parser.Parse(new StringReader(sqlText), out var errors) as TSqlScript;
                if (errors.Count > 0)
                {
                    var errorList = new StringBuilder();
                    foreach (var error in errors)
                    {
                        errorList.AppendLine($"{error.Message}<br/>");
                    }
                    throw new ApplicationException(errorList.ToString());
                }
                for (var batchNo = 0; batchNo < script2.Batches.Count; batchNo++)
                {
                    var batch2 = script2.Batches[batchNo];
                    //get the doc above the stored proc
                    var betweenBatchStart = 0;
                    if (batchNo > 0)
                    {
                        betweenBatchStart = script2.Batches[batchNo - 1].StartOffset +
                                            script2.Batches[batchNo - 1].FragmentLength;
                    }

                    var    betweenBatchEnd = batch2.StartOffset - 1;
                    string batchText       = null;
                    if (betweenBatchEnd > 0)
                    {
                        batchText = sqlText.Substring(betweenBatchStart, betweenBatchEnd - betweenBatchStart);
                        //clean up the doc
                        batchText = batchText.Replace("GO", "");
                        batchText = batchText.Replace(Environment.NewLine, "");
                        batchText = batchText.Replace("\r", "");
                        batchText = batchText.Replace("/*", "");
                        batchText = batchText.Replace("*/", "");
                        batchText = batchText.Trim();
                    }
                    foreach (var statement in batch2.Statements)
                    {
                        var createFunctionStatement = statement as CreateFunctionStatement;

                        if (createFunctionStatement == null)
                        {
                            continue;
                        }
                        var viewSchemaName = createFunctionStatement.Name.SchemaIdentifier.Value;

                        var createSchemaCommand = new SqlCommand(
                            $@" IF NOT EXISTS (SELECT name FROM sys.schemas WHERE name = N'{viewSchemaName}')
                                    BEGIN
                                        EXEC sp_executesql N'CREATE SCHEMA {viewSchemaName}'
                                    END", sqlConnection);
                        createSchemaCommand.ExecuteNonQuery();

                        scriptGen.GenerateScript(statement, out var scriptOut, out var errors2);

                        //fixup CTE
                        //var tempScript = scriptOut.Replace(Environment.NewLine, " ").ToUpper();
                        //might insert extra ; it won't hurt anything
                        if (scriptOut.Contains(" WITH "))
                        {
                            scriptOut = scriptOut.Replace(" WITH ", "; WITH ");
                        }
                        else if (scriptOut.Contains(Environment.NewLine + "WITH "))
                        {
                            scriptOut = scriptOut.Replace(Environment.NewLine + "WITH ", ";" + Environment.NewLine + " WITH ");
                        }
                        var sqlCommand = new SqlCommand(scriptOut, sqlConnection);
                        sqlCommand.ExecuteNonQuery();

                        var function = new KFunction(DataStoreTypes.SqlServer)
                        {
                            Schema = new CSchema()
                            {
                                SchemaName =
                                    createFunctionStatement.Name.SchemaIdentifier.Value
                            },
                            FunctionName =
                                createFunctionStatement.Name.BaseIdentifier.Value,
                            FunctionText = scriptOut,
                            //StoredProcedureDescription = batchText,
                            ResultSetName = createFunctionStatement.Name.BaseIdentifier.Value + "Dto"// "ResultSet"
                        };

                        /*
                         * var oldStoredProc = kDataStoreProject.OldStoredProcedure.FirstOrDefault(s => s.StoredProcedureName == function.FunctionName); //todo: compare schema
                         * if (oldStoredProc != null)
                         * {
                         *  function.DerivedFrom = oldStoredProc.DerivedFrom;
                         * }
                         */
                        functions.Add(function);
                    }
                }
                sqlConnection.Close();
            }
            return(functions);
        }