Files
SQLLint/SQLLinter/Infrastructure/Rules/CountStarRule.cs

62 lines
1.9 KiB
C#

using Microsoft.SqlServer.TransactSql.ScriptDom;
using SQLLinter.Common;
using SQLLinter.Common.Helpers;
namespace SQLLinter.Infrastructure.Rules;
public class CountStarRule : BaseRuleVisitor, IRule
{
public override string Text => "COUNT(*) запрещен. Используйте COUNT(1) или COUNT(<PK>)";
public override void Visit(FunctionCall node)
{
var functionName = node.FunctionName?.Value;
if (functionName == null || !functionName.ToUpper().Equals("COUNT"))
{
return;
}
foreach (ScalarExpression param in node.Parameters)
{
var paramVisitor = new ParameterVisitor();
param.Accept(paramVisitor);
if (paramVisitor.IsWildcard)
{
AddViolation(node);
}
}
}
public override void FixViolation(List<string> fileLines, IRuleViolation ruleViolation, FileLineActions actions)
{
var node = FixHelpers.FindViolatingNode<FunctionCall>(fileLines, ruleViolation);
foreach (ScalarExpression param in node.Parameters)
{
var paramVisitor = new ParameterVisitor();
param.Accept(paramVisitor);
if (paramVisitor.IsWildcard)
{
var whileCard = paramVisitor.Expression;
actions.RepaceInlineAt(whileCard.StartLine - 1, whileCard.StartColumn - 1, "1");
}
}
}
private class ParameterVisitor : TSqlFragmentVisitor
{
public bool IsWildcard { get; private set; }
public ColumnReferenceExpression Expression { get; private set; }
public ParameterVisitor()
{
IsWildcard = false;
}
public override void Visit(ColumnReferenceExpression node)
{
IsWildcard = node.ColumnType.Equals(ColumnType.Wildcard);
Expression = node;
}
}
}