예제 #1
0
        /// <summary>
        /// Checks if an object is:
        /// - Named
        /// - Starts with a letter or digit. This filters our parameters starting with '@', but may filter out other
        ///   objects you wish to test for. This is where you would extend the logic for more advanced cases
        /// - The first letter is not uppercase.
        /// </summary>
        private void CheckIfCapitalized(TSqlObject tSqlObject, List <SqlRuleProblem> problems)
        {
            ObjectIdentifier name = tSqlObject.Name;

            if (name != null &&
                name.HasName &&
                name.Parts.Count > 0)       // This check is equivalent to name.HasHame, including in case you don't trust the framework and want to verify yourself
            {
                string actualName = name.Parts[name.Parts.Count - 1];
                if (!string.IsNullOrEmpty(actualName) &&
                    Char.IsLetterOrDigit(actualName[0]) &&
                    !Char.IsUpper(actualName[0]))
                {
                    string description = string.Format(CultureInfo.CurrentCulture,
                                                       RuleResources.CapitalizedNames_ProblemDescription,
                                                       _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                    // Name fragment would have more precise location information than the overall object.
                    // This can be null, in which case the object's position will be used.
                    // note that the current implementation does not work for non-top level types as it
                    // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                    TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                    problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                }
            }
        }
 /// <summary>
 // Views must be schema bound if they reference a memory optimized table
 /// </summary>
 private static void ValidateViewHasSchemaBinding(SqlRuleExecutionContext context, TSqlObject view, TSqlObject table,
                                                  IList <SqlRuleProblem> problems)
 {
     if (!view.GetProperty <bool>(View.WithSchemaBinding))
     {
         string description = string.Format(CultureInfo.CurrentCulture,
                                            RuleResources.ViewsOnMemoryOptimizedTable_SchemaBindingProblemDescription,
                                            RuleUtils.GetElementName(context, view),
                                            RuleUtils.GetElementName(context, table));
         TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(view);
         problems.Add(new SqlRuleProblem(description, view, nameFragment));
     }
 }
        /// <summary>
        /// No Indexes of any kind are allowed on Views that reference a memory optimized table.
        /// </summary>
        private void ValidateViewHasNoIndexes(SqlRuleExecutionContext context, TSqlObject view, TSqlObject table, IList <SqlRuleProblem> problems)
        {
            foreach (TSqlObject index in view.GetReferencing(Index.IndexedObject))
            {
                string description = string.Format(CultureInfo.CurrentCulture,
                                                   RuleResources.ViewsOnMemoryOptimizedTable_IndexProblemDescription,
                                                   RuleUtils.GetElementName(context, index),
                                                   RuleUtils.GetElementName(context, view),
                                                   RuleUtils.GetElementName(context, table));
                TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(index);

                // Note that nameFragment can be null - in this case the index's position information will be used.
                // This is just a little less precise than pointing to the position of the name for that index
                problems.Add(new SqlRuleProblem(description, index, nameFragment));
            }
        }
        private void CheckNamingConvention(TSqlObject tSqlObject, List <SqlRuleProblem> problems)
        {
            ObjectIdentifier name = tSqlObject.Name;

            if (name != null &&
                name.HasName &&
                name.Parts.Count > 0)       // This check is equivalent to name.HasHame, including in case you don't trust the framework and want to verify yourself
            {
                string actualName = name.Parts[name.Parts.Count - 1];

                switch (tSqlObject.ObjectType.Name)
                {
                case "View":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("vw_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }

                case "Procedure":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("usp_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }

                case "PrimaryKeyConstraint":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("pk_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }

                case "ForeignKeyConstraint":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("fk_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }

                case "CheckConstraint":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("ck_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }

                case "DefaultConstraint":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("df_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }

                case "Synonym":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("syn_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }

                case "DmlTrigger":
                {
                    if (!string.IsNullOrEmpty(actualName) &&
                        !actualName.StartsWith("trg_"))
                    {
                        string description = string.Format(CultureInfo.CurrentCulture,
                                                           RuleResources.NamingConventions_ProblemDescription,
                                                           _model.DisplayServices.GetElementName(tSqlObject, ElementNameStyle.EscapedFullyQualifiedName));

                        // Name fragment would have more precise location information than the overall object.
                        // This can be null, in which case the object's position will be used.
                        // note that the current implementation does not work for non-top level types as it
                        // relies on the TSqlModelUtils.TryGetFragmentForAnalysis() method which doesn't support these.
                        TSqlFragment nameFragment = TsqlScriptDomUtils.LookupSchemaObjectName(tSqlObject);

                        problems.Add(new SqlRuleProblem(description, tSqlObject, nameFragment));
                    }
                    break;
                }
                }
            }
        }