using Microsoft.SqlServer.TransactSql.ScriptDom; using SQLLinter.Common; using SQLLinter.Core; using SQLLinter.Core.Interfaces; using SQLLinter.Infrastructure.Configuration.Overrides; using SQLLinter.Infrastructure.Interfaces; namespace SQLLinter.Infrastructure.Parser; public class FragmentBuilder : IFragmentBuilder { private readonly TSqlParser parser; private readonly IReporter _reporter; public FragmentBuilder(IReporter reporter) : this(reporter, Constants.DefaultCompatabilityLevel) { } public FragmentBuilder(IReporter reporter, int compatabilityLevel) { parser = GetSqlParser(compatabilityLevel); _reporter = reporter; } public TSqlFragment? GetFragment(string path, TextReader txtRdr, out IList errors, IEnumerable overrides = null) { TSqlFragment fragment; OverrideCompatabilityLevel? compatibilityLevel = null; if (overrides != null) { foreach (var lintingOverride in overrides) { if (lintingOverride is OverrideCompatabilityLevel overrideCompatability) { compatibilityLevel = overrideCompatability; } } } TSqlParser curParser; if (compatibilityLevel != null) { curParser = GetSqlParser(compatibilityLevel.CompatabilityLevel); } else { curParser = parser; } fragment = curParser.Parse(txtRdr, out errors); //TODO: Возвращать эти ошибки if (fragment == null) { foreach (var err in errors) { _reporter.ReportViolation(path, err.Line, err.Column, RuleViolationSeverity.Critical, "parse", err.Message); } } return fragment?.FirstTokenIndex != -1 ? fragment : null; } private static TSqlParser GetSqlParser(int compatabilityLevel) { TSqlParser parser = compatabilityLevel switch { 80 => new TSql80Parser(true), 90 => new TSql90Parser(true), 100 => new TSql100Parser(true), 110 => new TSql110Parser(true), 120 => new TSql120Parser(true), 130 => new TSql130Parser(true), 140 => new TSql140Parser(true), 150 => new TSql150Parser(true), 160 => new TSql160Parser(true), 170 => new TSql170Parser(true), _ => new TSql120Parser(true), }; return parser; } }