62 lines
1.9 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|