示例#1
0
        public DeclareCursorHandlerStatement ParseDeclareHandler(DeclareHandlerContext node)
        {
            DeclareCursorHandlerStatement statement = new DeclareCursorHandlerStatement();

            statement.Conditions.AddRange(node.handlerConditionValue().Select(item => new TokenInfo(item)
            {
                Type = TokenType.Condition
            }));
            statement.Statements.AddRange(this.ParseRoutineBody(node.routineBody()));

            return(statement);
        }
示例#2
0
        public string GenerateRoutineScripts(RoutineScript script)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine($"CREATE {script.Type.ToString()} {script.FullName}");

            sb.AppendLine("(");

            if (script.Parameters.Count > 0)
            {
                int i = 0;
                foreach (Parameter parameter in script.Parameters)
                {
                    ParameterType parameterType = parameter.ParameterType;

                    string strParameterType = "";

                    if (parameterType.HasFlag(ParameterType.IN) && parameterType.HasFlag(ParameterType.OUT))
                    {
                        strParameterType = "INOUT";
                    }
                    else if (parameterType != ParameterType.NONE)
                    {
                        strParameterType = parameterType.ToString();
                    }

                    sb.AppendLine($"{strParameterType} {parameter.Name} {parameter.DataType}{(i == script.Parameters.Count - 1 ? "" : ",")}");

                    i++;
                }
            }

            sb.AppendLine(")");

            if (script.Type == RoutineType.FUNCTION)
            {
                sb.AppendLine($"RETURNS {script.ReturnDataType}");
            }

            int  beginIndex        = sb.Length - 1;
            bool hasLeaveStatement = false;

            sb.AppendLine("BEGIN");

            foreach (Statement statement in script.Statements.Where(item => item is DeclareStatement))
            {
                sb.AppendLine(this.BuildStatement(statement));
            }

            #region Cursor

            Action appendDeclareCursor = () =>
            {
                foreach (Statement statement in script.Statements.Where(item => item is DeclareCursorStatement))
                {
                    sb.AppendLine(this.BuildStatement(statement));
                }
            };

            if (script.Statements.Any(item => item is OpenCursorStatement) && !script.Statements.Any(item => item is DeclareCursorHandlerStatement))
            {
                if (!script.Statements.Any(item => item is DeclareStatement && (item as DeclareStatement).Name.Symbol == "FINISHED"))
                {
                    DeclareStatement declareStatement = new DeclareStatement()
                    {
                        Name = new TokenInfo("FINISHED")
                        {
                            Type = TokenType.VariableName
                        },
                        DataType = new TokenInfo("INT")
                        {
                            Type = TokenType.DataType
                        },
                        DefaultValue = new TokenInfo("0")
                    };

                    sb.AppendLine(this.BuildStatement(declareStatement));
                }

                appendDeclareCursor();

                DeclareCursorHandlerStatement handler = new DeclareCursorHandlerStatement();
                handler.Statements.Add(new SetStatement()
                {
                    Key = new TokenInfo("FINISHED")
                    {
                        Type = TokenType.VariableName
                    }, Value = new TokenInfo("1")
                });

                sb.AppendLine(this.BuildStatement(handler));
            }
            else
            {
                appendDeclareCursor();
            }

            #endregion

            if (script.ReturnTable != null)
            {
                sb.AppendLine(MySqlStatementScriptBuilder.BuildTemporaryTable(script.ReturnTable));
            }

            FetchCursorStatement fetchCursorStatement = null;

            foreach (Statement statement in script.Statements.Where(item => !(item is DeclareStatement || item is DeclareCursorStatement)))
            {
                if (statement is FetchCursorStatement fetch)
                {
                    fetchCursorStatement = fetch;
                    continue;
                }
                else if (statement is WhileStatement @while)
                {
                    FetchCursorStatement fs = @while.Statements.FirstOrDefault(item => item is FetchCursorStatement) as FetchCursorStatement;

                    if (fetchCursorStatement != null && fs != null)
                    {
                        @while.Condition.Symbol = "FINISHED = 0";

                        if (fs.Variables.Count == 0)
                        {
                            @while.Statements.Insert(0, fetchCursorStatement);
                        }
                    }
                }

                if (statement is LeaveStatement)
                {
                    hasLeaveStatement = true;
                }

                sb.AppendLine(this.BuildStatement(statement));
            }

            sb.AppendLine("END");

            if (hasLeaveStatement)
            {
                sb.Insert(beginIndex, "sp:");
            }

            return(this.FormatScripts(sb.ToString()));
        }