chore(sonar): hoist constant array literals to static readonly fields (CA1861)
Applied via `dotnet format analyzers --diagnostics CA1861 --severity info`,
plus manual cleanup:
- Renamed two cryptic fixer-generated field names:
- QueryBreakdownCollection.stringArray -> SnowflakeFunctionNames (and
inlined the now-redundant local alias)
- ExpressionObjectTests.arg2 -> NotInValues
- Deduped three identical `separator = ['\r','\n']` fields the fixer
emitted in the same test class (kept the first declaration; the other
two test methods now reuse it).
8 files touched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
84b06557e5
commit
f5d539b906
@@ -182,6 +182,15 @@ public class QueryBreakdownCollection : SqlServer.QueryBreakdownCollectionBase<Q
|
||||
});
|
||||
}
|
||||
|
||||
private static readonly string[] SnowflakeFunctionNames =
|
||||
[
|
||||
"PARSE_JSON", "OBJECT_INSERT", "ARRAY_CONSTRUCT", "ARRAY_AGG",
|
||||
"FLATTEN", "GET_PATH", "TRY_PARSE_JSON", "JSON_EXTRACT_PATH_TEXT",
|
||||
"JSON_EXTRACT_PATH_WITH_DEFAULT", "HASHAGGREGATE", "LISTAGG",
|
||||
"APPROX_COUNT_DISTINCT", "APPROX_PERCENTILE", "GREATEST", "LEAST",
|
||||
"NULLIF", "ZEROIFNULL", "STRTOK", "SPLIT_PART", "PIVOT", "UNPIVOT"
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Filters queries that use Snowflake functions (PARSE_JSON, OBJECT_INSERT, ARRAY, etc.).
|
||||
/// </summary>
|
||||
@@ -191,17 +200,7 @@ public class QueryBreakdownCollection : SqlServer.QueryBreakdownCollectionBase<Q
|
||||
return QueryBreakdownList.Where(q =>
|
||||
{
|
||||
var sql = q.GetSql().ToUpperInvariant();
|
||||
|
||||
var snowflakeFunctions = new[]
|
||||
{
|
||||
"PARSE_JSON", "OBJECT_INSERT", "ARRAY_CONSTRUCT", "ARRAY_AGG",
|
||||
"FLATTEN", "GET_PATH", "TRY_PARSE_JSON", "JSON_EXTRACT_PATH_TEXT",
|
||||
"JSON_EXTRACT_PATH_WITH_DEFAULT", "HASHAGGREGATE", "LISTAGG",
|
||||
"APPROX_COUNT_DISTINCT", "APPROX_PERCENTILE", "GREATEST", "LEAST",
|
||||
"NULLIF", "ZEROIFNULL", "STRTOK", "SPLIT_PART", "PIVOT", "UNPIVOT"
|
||||
};
|
||||
|
||||
return snowflakeFunctions.Any(func => sql.Contains(func));
|
||||
return SnowflakeFunctionNames.Any(func => sql.Contains(func));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ public static partial class SqlUtils
|
||||
public const string DATETIME_INSERT_FORMAT = "yyyyMMdd HH:mm:ss";
|
||||
|
||||
private const string DEFAULT_SCHEMA = "dbo";
|
||||
private static readonly char[] separator = new[] { ',' };
|
||||
|
||||
#region SQL String Manipulation
|
||||
|
||||
@@ -34,7 +35,7 @@ public static partial class SqlUtils
|
||||
public static string StripColumnTableAlias(string sql)
|
||||
{
|
||||
// Break sql into words and remove "abc." from each column
|
||||
string[] commaWords = sql.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] commaWords = sql.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
||||
var newParts = new List<string>();
|
||||
|
||||
foreach (string commaWord in commaWords)
|
||||
|
||||
@@ -21,6 +21,7 @@ public class StatementParser
|
||||
public const string KeywordGroupBy = "GROUP BY";
|
||||
public const string KeywordHaving = "HAVING";
|
||||
public const string KeywordOrderBy = "ORDER BY";
|
||||
private static readonly char[] separator = new[] { '\r', '\n' };
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -50,7 +51,7 @@ public class StatementParser
|
||||
// Replace multiple spaces/tabs with single space, but preserve newlines for comment handling
|
||||
sql = Regex.Replace(sql, @"[ \t]+", " ", RegexOptions.None, RegexDefaults.MatchTimeout);
|
||||
// Remove leading/trailing whitespace from each line
|
||||
var lines = sql.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
|
||||
var lines = sql.Split(separator, StringSplitOptions.None);
|
||||
sql = string.Join("\n", lines.Select(line => line.Trim()));
|
||||
return sql.Trim();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Strata.SqlTools.LinqToSql.Tests;
|
||||
public class LinqQueryBreakdownTests
|
||||
{
|
||||
private TestDataContext _context = null!;
|
||||
private static readonly string[] separator = new[] { "AND" };
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
@@ -303,7 +304,7 @@ public class LinqQueryBreakdownTests
|
||||
Assert.That(filterSql, Does.Contain("IsActive = 1"));
|
||||
|
||||
// Should have multiple AND conditions
|
||||
var andCount = filterSql.Split(new[] { "AND" }, StringSplitOptions.None).Length - 1;
|
||||
var andCount = filterSql.Split(separator, StringSplitOptions.None).Length - 1;
|
||||
Assert.That(andCount, Is.GreaterThanOrEqualTo(2));
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ public class QueryBreakdownTests
|
||||
Assert.That(sql, Does.Contain("ORDER BY"));
|
||||
}
|
||||
|
||||
private static readonly char[] separator = new[] { '\r', '\n' };
|
||||
|
||||
[Test]
|
||||
public void GetSql_WithSingleWithClause_UsesSnowflakeIndentation()
|
||||
{
|
||||
@@ -114,7 +116,7 @@ public class QueryBreakdownTests
|
||||
Assert.That(sql, Does.Contain("WITH"));
|
||||
Assert.That(sql, Does.Contain("PRODUCT_SUMMARY AS ("));
|
||||
// Verify 4-space Snowflake indentation
|
||||
var lines = sql.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var lines = sql.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
||||
var indentedLines = lines.Where(l => l.StartsWith(" ")).ToList();
|
||||
Assert.That(indentedLines.Count, Is.GreaterThan(0));
|
||||
}
|
||||
@@ -1118,7 +1120,7 @@ public class QueryBreakdownTests
|
||||
_ = baseQueryBreakdown.GetSql();
|
||||
|
||||
// Assert - Snowflake should use 4-space indent, base uses 5-space
|
||||
var snowflakeLines = snowflakeSql.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var snowflakeLines = snowflakeSql.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
||||
var snowflakeIndentedLines = snowflakeLines.Where(l => l.StartsWith(" ") && !l.StartsWith(" ")).ToList();
|
||||
Assert.That(snowflakeIndentedLines.Count, Is.GreaterThan(0), "Snowflake should use 4-space indentation");
|
||||
}
|
||||
@@ -1322,7 +1324,7 @@ public class QueryBreakdownTests
|
||||
Assert.That(snowflakeSql, Does.Contain("WHERE"));
|
||||
Assert.That(snowflakeSql, Does.Contain("ORDER BY"));
|
||||
// Verify Snowflake-style formatting (4-space indentation)
|
||||
var lines = snowflakeSql.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var lines = snowflakeSql.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
||||
var indentedLines = lines.Where(l => l.StartsWith(" ")).ToList();
|
||||
Assert.That(indentedLines.Count, Is.GreaterThan(0), "Should have Snowflake-style indentation");
|
||||
}
|
||||
|
||||
+3
-1
@@ -5,6 +5,8 @@ namespace Strata.SqlTools.SqlBreakdown.Tests.ExpressionTests;
|
||||
[TestFixture]
|
||||
public class ExpressionFactoryFilterTests : ExpressionTestsBase
|
||||
{
|
||||
private static readonly string[] values = new[] { "FY2019", "FY2020", "FY2021", "FY2022" };
|
||||
|
||||
private static IEnumerable<TestCaseData> FilterTestCases()
|
||||
{
|
||||
var dischargeDate = DateTime.Now.Date.AddMonths(1);
|
||||
@@ -16,7 +18,7 @@ public class ExpressionFactoryFilterTests : ExpressionTestsBase
|
||||
).SetName("ListFilterContinuous_{m}");
|
||||
|
||||
yield return new TestCaseData(
|
||||
new Filter(4, FilterType.List, new[] { "FY2019", "FY2020", "FY2021", "FY2022" }, Array.Empty<FilterCondition>(), DatePart.FiscalYear, false, 0, 0),
|
||||
new Filter(4, FilterType.List, values, Array.Empty<FilterCondition>(), DatePart.FiscalYear, false, 0, 0),
|
||||
"(DEPT.DISCHARGE_DATE >= '2018-07-01' AND DEPT.DISCHARGE_DATE < '2019-07-01') OR \n(DEPT.DISCHARGE_DATE >= '2019-07-01' AND DEPT.DISCHARGE_DATE < '2020-07-01') OR \n(DEPT.DISCHARGE_DATE >= '2020-07-01' AND DEPT.DISCHARGE_DATE < '2021-07-01') OR \n(DEPT.DISCHARGE_DATE >= '2021-07-01' AND DEPT.DISCHARGE_DATE < '2022-07-01')"
|
||||
).SetName("DateListFilterFiscalYear_{m}");
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ public class ExpressionObjectTests : ExpressionTestsBase
|
||||
Assert.That(paramExp.ParameterName, Is.EqualTo("MY_PARAM"));
|
||||
}
|
||||
|
||||
private static readonly string[] NotInValues = new[] { "value1", "value2", "value3" };
|
||||
|
||||
private static IEnumerable<TestCaseData> ComparisonExpressionTestCases()
|
||||
{
|
||||
yield return new TestCaseData("GreaterThanOrEqual", 250, typeof(GreaterThanOrEqualToExpression))
|
||||
@@ -40,7 +42,7 @@ public class ExpressionObjectTests : ExpressionTestsBase
|
||||
yield return new TestCaseData("Equals", "TestDept", typeof(EqualToExpression))
|
||||
.SetName("Equals_{m}");
|
||||
|
||||
yield return new TestCaseData("NotIn", new[] { "value1", "value2", "value3" }, typeof(NotInExpression))
|
||||
yield return new TestCaseData("NotIn", NotInValues, typeof(NotInExpression))
|
||||
.SetName("NotIn_{m}");
|
||||
|
||||
yield return new TestCaseData("Like", "%pattern%", typeof(LikeExpression))
|
||||
|
||||
+3
-1
@@ -243,12 +243,14 @@ public class QueryBreakdownExtensionsTests
|
||||
Assert.That(query.WithClauses[1].TableName, Is.EqualTo("recent_orders"));
|
||||
}
|
||||
|
||||
private static readonly string[] columns = new[] { "id", "name", "email" };
|
||||
|
||||
[Test]
|
||||
public void WithCte_WithColumnList_AddsCtesWithColumns()
|
||||
{
|
||||
// Arrange & Act
|
||||
var query = new QueryBreakdown()
|
||||
.WithCte("active_users", new[] { "id", "name", "email" }, cte => cte
|
||||
.WithCte("active_users", columns, cte => cte
|
||||
.Select("user_id, user_name, user_email")
|
||||
.From("users")
|
||||
.Where("status = 'active'"))
|
||||
|
||||
Reference in New Issue
Block a user