/// <summary> /// For element-scoped rules the Analyze method is executed once for every matching object in the model. /// </summary> /// <param name="ruleExecutionContext">The context object contains the TSqlObject being analyzed, a TSqlFragment /// that's the AST representation of the object, the current rule's descriptor, and a reference to the model being /// analyzed. /// </param> /// <returns>A list of problems should be returned. These will be displayed in the Visual Studio error list</returns> public override IList <SqlRuleProblem> Analyze(XtendSqlRuleExecutionContext context) { IList <SqlRuleProblem> problems = new List <SqlRuleProblem>(); CursorVisitor visitor = new CursorVisitor(false, true); context.ScriptFragment.Accept(visitor); foreach (var element in visitor.IncorrectFetchCursorStatements) { var fetch = element.Key; int fetchCount = fetch.IntoVariables.Count; string cursorName = element.Value; SqlRuleProblem problem = new SqlRuleProblem( String.Format( CultureInfo.CurrentCulture, context.RuleDescriptor.DisplayDescription, cursorName, fetchCount), context.ModelElement, fetch); problems.Add(problem); } return(problems); }
/// <summary> /// For element-scoped rules the Analyze method is executed once for every matching object in the model. /// </summary> /// <param name="ruleExecutionContext">The context object contains the TSqlObject being analyzed, a TSqlFragment /// that's the AST representation of the object, the current rule's descriptor, and a reference to the model being /// analyzed. /// </param> /// <returns>A list of problems should be returned. These will be displayed in the Visual Studio error list</returns> public override IList <SqlRuleProblem> Analyze(SqlRuleExecutionContext ruleExecutionContext) { IList <SqlRuleProblem> problems = new List <SqlRuleProblem>(); TSqlObject modelElement = ruleExecutionContext.ModelElement; string elementName = ruleExecutionContext.SchemaModel.DisplayServices.GetElementName(modelElement, ElementNameStyle.EscapedFullyQualifiedName); TSqlFragment fragment = ruleExecutionContext.ScriptFragment; RuleDescriptor ruleDescriptor = ruleExecutionContext.RuleDescriptor; // Get schema of the procedure. TSqlObject schema = modelElement.GetReferenced(Procedure.Schema).SingleOrDefault(); if (schema != null && fragment.FragmentLength > 0) { CursorVisitor visitor = new CursorVisitor(true, false); fragment.Accept(visitor); foreach (var element in visitor.DeclareCursorStatementsMissingDeallocate) { string cursorName = element.Name.Value; SqlRuleProblem problem = new SqlRuleProblem( String.Format( CultureInfo.CurrentCulture, ruleDescriptor.DisplayDescription, "Missing deallocate", cursorName, elementName), modelElement, element.CursorDefinition); problems.Add(problem); } foreach (var element in visitor.IncorrectDeallocateCursorStatements) { string cursorName = element.Cursor?.Name.Value ?? "NULL"; SqlRuleProblem problem = new SqlRuleProblem( String.Format( CultureInfo.CurrentCulture, ruleDescriptor.DisplayDescription, "Invalid deallocate", cursorName, elementName), modelElement, element); problems.Add(problem); } foreach (var element in visitor.DeclareCursorStatementsMissingOpen) { string cursorName = element.Name.Value; SqlRuleProblem problem = new SqlRuleProblem( String.Format( CultureInfo.CurrentCulture, ruleDescriptor.DisplayDescription, "Missing open", cursorName, elementName), modelElement, element.CursorDefinition); problems.Add(problem); } foreach (var element in visitor.IncorrectOpenCursorStatements) { string cursorName = element.Cursor?.Name.Value ?? "NULL"; SqlRuleProblem problem = new SqlRuleProblem( String.Format( CultureInfo.CurrentCulture, ruleDescriptor.DisplayDescription, "Invalid open", cursorName, elementName), modelElement, element); problems.Add(problem); } } return(problems); }