Resolve SonarQube Tech Debt #3

Merged
bermudalamb merged 6 commits from fix/Sonarqube-Tech-Debt into main 2026-05-20 13:23:09 -05:00
44 changed files with 36 additions and 445 deletions
Showing only changes of commit 5cb32d2311 - Show all commits
+11 -1
View File
@@ -13,7 +13,17 @@
"PowerShell(git *)",
"Bash(dotnet build *)",
"Bash(command -v gh)",
"Bash(command -v tea)"
"Bash(command -v tea)",
"PowerShell(if \\($env:SONARQUBE_URL -and $env:SONARQUBE_TOKEN\\) { \"URL set: $\\($env:SONARQUBE_URL\\)\"; \"Token set: $\\($env:SONARQUBE_TOKEN.Substring\\(0,8\\)\\)...\" } else { \"MISSING: URL=$\\($env:SONARQUBE_URL -ne $null\\) TOKEN=$\\($env:SONARQUBE_TOKEN -ne $null\\)\" })",
"PowerShell($u = [Environment]::GetEnvironmentVariable\\(\"SONARQUBE_URL\",\"User\"\\); $t = [Environment]::GetEnvironmentVariable\\(\"SONARQUBE_TOKEN\",\"User\"\\); \"User URL: $u\"; if \\($t\\) { \"User TOKEN: $\\($t.Substring\\(0,8\\)\\)... \\(len $\\($t.Length\\)\\)\" } else { \"User TOKEN: <none>\" })",
"Bash(grep -iE \"/\\(QueryConfig|CalculationFilter|LogicalOperator\\)\\\\.cs$\")",
"PowerShell(dotnet build C:\\\\gitea\\\\sql-utilities --nologo -clp:NoSummary 2>&1 | Select-String -Pattern \"warning S\\\\d+\" | ForEach-Object { $_.Line.Trim\\(\\) } | Sort-Object -Unique)",
"Bash(grep -oE 'S[0-9]{3,4}' build-sonar.log)",
"Bash(dotnet sln *)",
"Bash(Get-ChildItem src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/*.cs)",
"Bash(Measure-Object)",
"Bash(Select-Object -ExpandProperty Count)",
"PowerShell(dotnet build *)"
]
}
}
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public enum AggregationType
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class CalculationFilter : Filter
{
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class CalculationFilterGroup
{
@@ -24,7 +24,7 @@ public class CalculationFilterGroup
public IEnumerable<CalculationFilter> GetValidFilters()
{
return Filters?.Where(x => x.IsValid()).ToList() ?? new List<CalculationFilter>();
return Filters?.Where(x => x.IsValid()).ToList() ?? [];
}
public bool IsValid()
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class ColumnQueryConfig
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public enum DatePart
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class Field
{
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
/// <summary>
/// Represents a filter criteria for querying data with support for various filter types including lists, date ranges, and timeframes.
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class FilterCondition
{
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class FilterGroup
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public enum FilterOperator
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public enum FilterType
{
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public enum LogicalOperator
{
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class QueryConfig
{
@@ -1,5 +1,5 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public static class QueryConfigExtensions
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class Row : Field
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public enum SortDirection
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class SqlResponse
{
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class Value
{
@@ -1,4 +1,4 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
namespace Strata.SqlTools.Query;
public class ValueFilter
{
@@ -1,12 +0,0 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public class CalculationFilter : Filter
{
public IEnumerable<string> AliasedDataColumnIds { get; }
public CalculationFilter(int dataColumnId, IEnumerable<string> aliasedDataColumnIds, IEnumerable<object> values, IEnumerable<FilterCondition> conditions)
: base(dataColumnId, FilterType.Conditions, values, conditions, DatePart.Continuous, false, 0, 0)
{
AliasedDataColumnIds = aliasedDataColumnIds;
}
}
@@ -1,23 +0,0 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public class ColumnQueryConfig
{
public int DataColumnId { get; set; }
public DatePart DatePart { get; set; }
public Filter? Filter { get; set; }
public int RowLimit { get; set; }
[JsonConstructor]
public ColumnQueryConfig(int dataColumnId, DatePart datePart, Filter? filter, int rowLimit)
{
DataColumnId = dataColumnId;
DatePart = datePart;
Filter = filter != null && filter.IsValid() ? filter : null;
RowLimit = rowLimit;
}
}
@@ -1,13 +0,0 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public enum DatePart
{
Continuous = 0,
Year,
Quarter,
Month,
Week,
Day,
FiscalYear,
FiscalQuarter
}
@@ -1,8 +0,0 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public class Field
{
public string ColumnAlias { get; set; } = string.Empty;
public int DataColumnId { get; set; }
public DatePart DatePart { get; set; }
}
@@ -1,29 +0,0 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public class FilterGroup
{
// Hereditary logical operation applied to all Filters
public LogicalOperator LogicalOperator { get; set; }
public IEnumerable<Filter> Filters { get; }
public FilterGroup()
{
LogicalOperator = LogicalOperator.And;
Filters = new List<Filter>();
}
[JsonConstructor]
public FilterGroup(IEnumerable<Filter> filters, LogicalOperator logicalOperator)
{
Filters = filters.Where(x => x.IsValid()).ToList();
LogicalOperator = logicalOperator;
}
public bool IsValid()
{
return Filters != null && Filters.Any();
}
}
@@ -1,15 +0,0 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public enum FilterOperator
{
Equals = 0,
NotEquals = 1,
LessThan = 2,
LessThanOrEqualTo = 3,
GreaterThan = 4,
GreaterThanOrEqualTo = 5,
Between = 6, // this is a function, not a comparison - x BETWEEN a AND b is the same as: x >= a AND x <= z
Contains = 7,
StartsWith = 8,
EndsWith = 9
}
@@ -1,9 +0,0 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public enum FilterType
{
List = 0,
Conditions = 1,
Calendar = 2,
Timeframe = 3
}
@@ -1,30 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public enum LogicalOperator
{
[Display(Name = "and")]
And,
[Display(Name = "or")]
Or
}
public static class LogicalOperatorExtensions
{
public static string ToSql(this LogicalOperator logicalOperator, bool withSpaces = true)
{
var sql = "";
switch (logicalOperator)
{
case LogicalOperator.And:
sql = "and";
break;
case LogicalOperator.Or:
sql = "or";
break;
}
return withSpaces ? $" {sql} " : sql;
}
}
@@ -1,15 +0,0 @@
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public enum SortDirection
{
Asc = 0,
Desc = 1
}
public static class SortDirectionExtensions
{
public static string ToSql(this SortDirection sortDirection)
{
return sortDirection.ToString().ToUpper();
}
}
@@ -1,28 +0,0 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query;
public class Value
{
public string ColumnAlias { get; }
public string Calculation { get; }
public IEnumerable<int> CalculationDataColumnIds { get; }
public IEnumerable<string> AliasedIds { get; }
public IEnumerable<CalculationFilterGroup> FilterGroups { get; }
public Value() : this(string.Empty, string.Empty, new int[0], new string[0], new CalculationFilterGroup[0])
{
// FilterGroups = new List<CalculationFilterGroup>();
}
[JsonConstructor]
public Value(string columnAlias, string calculation, IEnumerable<int> calculationDataColumnIds, IEnumerable<string> aliasedIds, IEnumerable<CalculationFilterGroup> filterGroups)
{
ColumnAlias = columnAlias;
Calculation = calculation;
CalculationDataColumnIds = calculationDataColumnIds ?? Array.Empty<int>();
AliasedIds = aliasedIds ?? aliasedIds ?? Array.Empty<string>();
FilterGroups = filterGroups?.Where(x => x.IsValid()).ToList() ?? new List<CalculationFilterGroup>();
}
}
@@ -41,6 +41,7 @@
<ItemGroup>
<ProjectReference Include="..\Strata.SqlTools.SqlServer\Strata.SqlTools.SqlServer.csproj" />
<ProjectReference Include="..\Strata.SqlTools.Query\Strata.SqlTools.Query.csproj" />
</ItemGroup>
</Project>
@@ -4,7 +4,7 @@ using Strata.SqlTools.SqlBreakdown.Expressions.Conditional;
using Strata.SqlTools.SqlBreakdown.Expressions.Conditional.Comparisons;
using Strata.SqlTools.SqlBreakdown.Expressions.Functions.Conditional;
using Strata.SqlTools.SqlBreakdown.Expressions.Functions.DateTime;
using Strata.SqlTools.SqlServer.ExpressionFactory.Query;
using Strata.SqlTools.Query;
namespace Strata.SqlTools.SqlServer.ExpressionFactory;
@@ -1,12 +0,0 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public enum AggregationType
{
Sum = 0,
Count = 1,
CountDistinct = 2,
Avg = 3,
Median = 4,
Min = 5,
Max = 6
}
@@ -1,34 +0,0 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public class CalculationFilterGroup
{
// Hereditary logical operation applied to all Filters
public LogicalOperator LogicalOperator { get; set; }
public IEnumerable<CalculationFilter> Filters { get; set; }
public CalculationFilterGroup()
{
LogicalOperator = LogicalOperator.And;
Filters = new List<CalculationFilter>();
}
[JsonConstructor]
public CalculationFilterGroup(IEnumerable<CalculationFilter> filters, LogicalOperator logicalOperator)
{
Filters = filters;
LogicalOperator = logicalOperator;
}
public IEnumerable<CalculationFilter> GetValidFilters()
{
return Filters?.Where(x => x.IsValid()).ToList() ?? new List<CalculationFilter>();
}
public bool IsValid()
{
return Filters != null && Filters.Any(x => x.IsValid());
}
}
@@ -1,91 +0,0 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
/// <summary>
/// Represents a filter criteria for querying data with support for various filter types including lists, date ranges, and timeframes.
/// Filters can be applied to specific data columns and support different date granularities.
/// </summary>
public class Filter
{
/// <summary>
/// Gets the identifier of the data column to which this filter applies.
/// </summary>
public int DataColumnId { get; }
/// <summary>
/// Gets the type of filter being applied (e.g., List, Calendar, Timeframe).
/// </summary>
public FilterType FilterType { get; }
/// <summary>
/// Gets the collection of values to filter by. The interpretation depends on the <see cref="FilterType"/>.
/// </summary>
public IEnumerable<object> Values { get; }
/// <summary>
/// Gets the collection of filter conditions that define complex filtering logic.
/// Only valid conditions are retained.
/// </summary>
public IEnumerable<FilterCondition> Conditions { get; }
/// <summary>
/// Gets the date granularity part for date-based filtering (e.g., Year, Month, Day, FiscalYear).
/// </summary>
public DatePart DatePart { get; }
/// <summary>
/// Gets a value indicating whether to use NOT IN instead of IN for list-type filters.
/// Only applies when <see cref="FilterType"/> is List.
/// </summary>
public bool ListUseNotIn { get; }
/// <summary>
/// Gets the offset from the current time for timeframe-based filters.
/// Used in conjunction with <see cref="DateTimeFrameCount"/> to define relative time periods.
/// </summary>
public int DateTimeFrameOffset { get; }
/// <summary>
/// Gets the zero-based number of time increments from the offset.
/// A value of 0 means current period, -1 means one period backward, and 1 means one period forward.
/// The unit (year, month, day, etc.) is determined by the <see cref="DatePart"/> property.
/// </summary>
public int DateTimeFrameCount { get; }
/// <summary>
/// Initializes a new instance of the <see cref="Filter"/> class with the specified filter criteria.
/// </summary>
/// <param name="dataColumnId">The identifier of the data column to filter.</param>
/// <param name="filterType">The type of filter to apply.</param>
/// <param name="values">The collection of values for the filter.</param>
/// <param name="conditions">The collection of filter conditions (invalid conditions are automatically removed).</param>
/// <param name="datePart">The date granularity for date-based filtering.</param>
/// <param name="listUseNotIn">Whether to use NOT IN for list filters; false to use IN.</param>
/// <param name="dateTimeFrameOffset">The offset from current time for timeframe filters.</param>
/// <param name="dateTimeFrameCount">The number of time increments from the offset (0 = current, negative = past, positive = future).</param>
[JsonConstructor]
public Filter(int dataColumnId, FilterType filterType, IEnumerable<object> values, IEnumerable<FilterCondition> conditions, DatePart datePart, bool listUseNotIn, int dateTimeFrameOffset, int dateTimeFrameCount)
{
DataColumnId = dataColumnId;
FilterType = filterType;
Values = values;
Conditions = conditions.Where(x => x.IsValid()).ToList();
DatePart = datePart;
ListUseNotIn = listUseNotIn;
DateTimeFrameOffset = dateTimeFrameOffset;
DateTimeFrameCount = dateTimeFrameCount;
}
/// <summary>
/// Determines whether this filter has valid criteria that can be applied.
/// A filter is valid if it has values, conditions, or non-default timeframe settings.
/// </summary>
/// <returns>
/// <c>true</c> if the filter has values, conditions, or timeframe settings; otherwise, <c>false</c>.
/// </returns>
public bool IsValid()
{
return (Values != null && Values.Any()) || (Conditions != null && Conditions.Any()) || (DateTimeFrameCount != default || DateTimeFrameOffset != default);
}
}
@@ -1,17 +0,0 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public class FilterCondition
{
public FilterOperator Operator { get; set; }
public IEnumerable<object>? Values { get; set; }
// This is not hereditary to Values; it is used for combination with the next FilterCondition in the set
// todo: That could be indexed to ensure accuracy
public LogicalOperator LogicalOperator { get; set; }
public bool IsValid()
{
return Values != null && Values.Any();
}
}
@@ -1,33 +0,0 @@
using System.Text.Json.Serialization;
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public class QueryConfig
{
public IEnumerable<Row> Rows { get; set; }
public IEnumerable<Value> Values { get; set; }
public IEnumerable<FilterGroup> FilterGroups { get; }
public bool WithTotals { get; set; }
public int RowLimit { get; set; }
public QueryConfig()
{
Rows = new List<Row>();
Values = new List<Value>();
FilterGroups = new List<FilterGroup>();
}
[JsonConstructor]
public QueryConfig(IEnumerable<FilterGroup> filterGroups, IEnumerable<Row> rows, IEnumerable<Value> values, bool withTotals, int rowLimit)
{
FilterGroups = filterGroups.Where(x => x.IsValid()).ToList();
Rows = rows;
Values = values;
WithTotals = withTotals;
RowLimit = rowLimit;
}
}
@@ -1,20 +0,0 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public static class QueryConfigExtensions
{
/// <summary>
/// Gets all column ids referenced by this <see cref="QueryConfig"/>
/// </summary>
/// <param name="queryConfig"></param>
/// <returns></returns>
public static int[] GetAllColumnIds(this QueryConfig queryConfig)
{
return queryConfig.Values.SelectMany(value => value.CalculationDataColumnIds)
.Union(queryConfig.Values.SelectMany(x => x.FilterGroups.SelectMany(y => y.GetValidFilters().Select(f => f.DataColumnId))))
.Union(queryConfig.Rows.Select(row => row.DataColumnId))
// FilterGroup.Filters is pre-filtered at construction (see FilterGroup.cs JsonConstructor); no GetValidFilters() equivalent is needed here.
.Union(queryConfig.FilterGroups.SelectMany(filterGroup => filterGroup.Filters.Select(filter => filter.DataColumnId)))
.ToArray();
}
}
@@ -1,11 +0,0 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public class Row : Field
{
public SortDirection sortDirection { get; set; }
public Row()
{
sortDirection = SortDirection.Asc;
}
}
@@ -1,13 +0,0 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public class SqlResponse
{
public string SqlQuery { get; }
public IEnumerable<KeyValuePair<string, object>> Parameters { get; }
public SqlResponse(string sqlQuery, IEnumerable<KeyValuePair<string, object>> parameters)
{
SqlQuery = sqlQuery;
Parameters = parameters;
}
}
@@ -1,8 +0,0 @@
namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query;
public class ValueFilter
{
public int DataColumnId { get; set; }
public object? FilterValue { get; set; }
}
@@ -41,6 +41,7 @@
<ItemGroup>
<ProjectReference Include="..\Strata.SqlTools.SqlBreakdown\Strata.SqlTools.SqlBreakdown.csproj" />
<ProjectReference Include="..\Strata.SqlTools.Query\Strata.SqlTools.Query.csproj" />
</ItemGroup>
<ItemGroup>
@@ -1,4 +1,4 @@
using Strata.SqlTools.SqlServer.ExpressionFactory.Query;
using Strata.SqlTools.Query;
namespace Strata.SqlTools.SqlBreakdown.Tests.ExpressionTests;
@@ -1,7 +1,7 @@
using Strata.SqlTools.SqlBreakdown.Classes;
using Strata.SqlTools.SqlBreakdown.Expressions;
using Strata.SqlTools.SqlBreakdown.Expressions.Conditional;
using Strata.SqlTools.SqlServer.ExpressionFactory.Query;
using Strata.SqlTools.Query;
using Strata.SqlTools.SqlBreakdown.Tests.RegisteredTables;
using Strata.SqlTools.Visitors.Snowflake;
using ExpressionFactoryBase = Strata.SqlTools.SqlServer.ExpressionFactory.ExpressionFactory;