using Microsoft.SqlServer.TransactSql.ScriptDom; using SQLLinter.Common; using SQLLinter.Common.Helpers; namespace SQLLinter.Infrastructure.Rules; public class ColumnNullabilityRule : BaseRuleVisitor { public override string Text => "При объявлении таблицы необходимо указывать для столбцов NULL/NOT NULL: таблица {0} - столбец [{1}]"; private string? _currentTable; public override void Visit(CreateTableStatement node) { _currentTable = SQLHelpers.ObjectGetFullName(node.SchemaObjectName); foreach (var element in node.Definition.ColumnDefinitions) { CheckColumn(element); } _currentTable = null; } public override void Visit(AlterTableAddTableElementStatement node) { _currentTable = SQLHelpers.ObjectGetFullName(node.SchemaObjectName); foreach (var element in node.Definition.ColumnDefinitions) { CheckColumn(element); } _currentTable = null; } public override void Visit(AlterTableAlterColumnStatement node) { _currentTable = SQLHelpers.ObjectGetFullName(node.SchemaObjectName); bool hasNullabilityConstraint = node.Options .OfType() .Any(); if (!hasNullabilityConstraint) { AddViolation(node, _currentTable ?? "", node.ColumnIdentifier?.Value ?? ""); } _currentTable = null; } public override void Visit(DeclareTableVariableStatement node) { _currentTable = node.Body.VariableName.Value; foreach (var column in node.Body.Definition.ColumnDefinitions) { CheckColumn(column); } } private void CheckColumn(ColumnDefinition node) { bool hasNullabilityConstraint = node.Constraints .OfType() .Any(); if (!hasNullabilityConstraint) { AddViolation(node, _currentTable ?? "", node.ColumnIdentifier?.Value ?? ""); } } }