/// <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);
        }
        public override IList <SqlRuleProblem> Analyze(SqlRuleExecutionContext ruleExecutionContext)
        {
            var problems = new List <SqlRuleProblem>();
            var sqlObj   = ruleExecutionContext.ModelElement;

            if (sqlObj == null || sqlObj.IsWhiteListed())
            {
                return(problems);
            }

            var fragment = ruleExecutionContext.ScriptFragment.GetFragment(ProgrammingAndViewSchemaTypes);

            var selectStatementVisitor = new SelectStatementVisitor();

            fragment.Accept(selectStatementVisitor);

            foreach (var select in selectStatementVisitor.Statements)
            {
                var booleanCompareVisitor = new BooleanComparisonVisitor();
                select.Accept(booleanCompareVisitor);

                var offenders =
                    from cmp in booleanCompareVisitor.NotIgnoredStatements(RuleId)
                    where TestCompare(cmp)
                    select cmp;

                problems.AddRange(offenders.Select(t => new SqlRuleProblem(Message, sqlObj, t)));
            }

            var actionStatementVisitor = new ActionStatementVisitor();

            fragment.Accept(actionStatementVisitor);

            foreach (var action in actionStatementVisitor.Statements)
            {
                var booleanCompareVisitor = new BooleanComparisonVisitor();
                action.Accept(booleanCompareVisitor);

                var offenders =
                    from cmp in booleanCompareVisitor.NotIgnoredStatements(RuleId)
                    where TestCompare(cmp)
                    select cmp;

                problems.AddRange(offenders.Select(t => new SqlRuleProblem(Message, sqlObj, t)));
            }

            return(problems);
        }
        public override IList <SqlRuleProblem> Analyze(SqlRuleExecutionContext ruleExecutionContext)
        {
            var problems   = new List <SqlRuleProblem>();
            var candidates = new List <StatementWithCtesAndXmlNamespaces>();
            var sqlObj     = ruleExecutionContext.ModelElement;

            if (sqlObj == null)
            {
                return(problems);
            }

            var fragment = ruleExecutionContext.ScriptFragment.GetFragment(ProgrammingSchemaTypes);

            List <StatementWithCtesAndXmlNamespaces> statements = new List <StatementWithCtesAndXmlNamespaces>();

            var selectVisitor = new SelectStatementVisitor();

            fragment.Accept(selectVisitor);
            statements.AddRange(selectVisitor.NotIgnoredStatements(RuleId));

            var actionStatementVisitor = new ActionStatementVisitor();

            fragment.Accept(actionStatementVisitor);
            statements.AddRange(actionStatementVisitor.NotIgnoredStatements(RuleId));

            if (statements.Count() > 1)
            {
                statements.ForEach(statement =>
                {
                    if (DoesStatementHaveDateFunction(statement))
                    {
                        candidates.Add(statement);
                    }
                });
            }

            problems.AddRange(candidates.Select(s => new SqlRuleProblem(Message, sqlObj, s)));

            return(problems);
        }
Пример #4
0
        /// <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 tryCatchVisitor        = new TryCatchVisitor();
            var actionStatementVisitor = new ActionStatementVisitor(); // not going to ignore temps for this rule as they should be wrapped in a try

            fragment.Accept(actionStatementVisitor);
            if (actionStatementVisitor.Count <= 1)
            {
                return(problems);
            }
            fragment.Accept(tryCatchVisitor);
            if (tryCatchVisitor.Count == 0)
            {
                problems.Add(new SqlRuleProblem(Message, sqlObj));
                return(problems);
            }

            var possibleOffenders = new List <DataModificationStatement>(actionStatementVisitor.Statements);

            foreach (var statement in tryCatchVisitor.Statements)
            {
                var startLine = statement.StartLine;
                var endline   = statement.CatchStatements.StartLine;
                possibleOffenders.RemoveAll(st => st.StartLine > startLine && st.StartLine < endline);
            }

            problems.AddRange(possibleOffenders.Select(po => new SqlRuleProblem(Message, sqlObj, po)));

            return(problems);
        }