public override IList <SqlRuleProblem> Analyze(SqlRuleExecutionContext ruleExecutionContext) { var procedure = ruleExecutionContext.ModelElement; var script = procedure.GetScript(); var parser = new TSql120Parser(true); IList <ParseError> errors = new List <ParseError>(); var fragment = parser.Parse(new StringReader(script), out errors); var visitor = new TransactionVisitor(); fragment.Accept(visitor); var dif = visitor.GetDifference(); if (dif.Any()) { return new List <SqlRuleProblem>() { new SqlRuleProblem("No balanced transaction", procedure) } } ; return(new List <SqlRuleProblem>()); } }
/// <summary> /// Performs analysis and returns a list of problems detected /// </summary> /// <param name="ruleExecutionContext">Contains the schema model and model element to analyze</param> /// <returns> /// The problems detected by the rule in the given element /// </returns> public override IList <SqlRuleProblem> Analyze(SqlRuleExecutionContext ruleExecutionContext) { List <SqlRuleProblem> problems = new List <SqlRuleProblem>(); TSqlObject sqlObj = ruleExecutionContext.ModelElement; if (sqlObj == null || sqlObj.IsWhiteListed()) { return(problems); } var fragment = ruleExecutionContext.ScriptFragment.GetFragment(typeof(CreateProcedureStatement)); var name = sqlObj.Name.GetName(); var transactionVisitor = new TransactionVisitor(); var actionStatementVisitor = new ActionStatementVisitor() { TypeFilter = ObjectTypeFilter.PermanentOnly }; fragment.Accept(actionStatementVisitor); if (actionStatementVisitor.Count <= 1) { return(problems); } fragment.Accept(transactionVisitor); if (transactionVisitor.Count == 0) { problems.Add(new SqlRuleProblem(Message, sqlObj)); return(problems); } //eliminate rollbacks, and ensure all the action statements are wrapped inside the begin tran...commit tran var transactionStatements = transactionVisitor.Statements .Where(st => st.GetType() == typeof(BeginTransactionStatement) || st.GetType() == typeof(CommitTransactionStatement)); var possibleOffenders = new List <DataModificationStatement>(actionStatementVisitor.Statements); for (int i = 0; i < transactionStatements.Count(); i += 2) { var beginTranLine = transactionStatements.ElementAt(i).StartLine; var commitTranLine = transactionStatements.ElementAt(i + 1).StartLine; possibleOffenders.RemoveAll(st => st.StartLine > beginTranLine && st.StartLine < commitTranLine); } problems.AddRange(possibleOffenders.Select(po => new SqlRuleProblem(Message, sqlObj, po))); return(problems); }