From 5cb32d231195baf4d68de5145e60278d294ed0b6 Mon Sep 17 00:00:00 2001 From: Thom Lamb Date: Wed, 20 May 2026 12:04:01 -0500 Subject: [PATCH] refactor(query): extract shared Strata.SqlTools.Query model project Moves the byte-identical 19-file ExpressionFactory/Query tree (duplicated across Snowflake and SqlServer) into the new Strata.SqlTools.Query project under the flat namespace Strata.SqlTools.Query. Both dialect projects now reference the shared project; the Snowflake copies are deleted. Also folds in the IDE0028 fix on CalculationFilterGroup.GetValidFilters (collection expression []), which resolves both new-code IDE0028 smells in one place now that there is a single copy. Eliminates the 63 new duplicate lines flagged on the PR and removes the largest contributor to the project's 11.1% duplication density. No behavioral change: the moved types are identical to the originals. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/settings.local.json | 12 ++- .../AggregationType.cs | 2 +- .../CalculationFilter.cs | 2 +- .../CalculationFilterGroup.cs | 4 +- .../ColumnQueryConfig.cs | 2 +- .../DatePart.cs | 2 +- .../Query => Strata.SqlTools.Query}/Field.cs | 2 +- .../Query => Strata.SqlTools.Query}/Filter.cs | 2 +- .../FilterCondition.cs | 2 +- .../FilterGroup.cs | 2 +- .../FilterOperator.cs | 2 +- .../FilterType.cs | 2 +- .../LogicalOperator.cs | 2 +- .../QueryConfig.cs | 2 +- .../QueryConfigExtensions.cs | 2 +- .../Query => Strata.SqlTools.Query}/Row.cs | 2 +- .../SortDirection.cs | 2 +- .../SqlResponse.cs | 2 +- .../Query => Strata.SqlTools.Query}/Value.cs | 2 +- .../ValueFilter.cs | 2 +- .../Query/CalculationFilter.cs | 12 --- .../Query/ColumnQueryConfig.cs | 23 ----- .../ExpressionFactory/Query/DatePart.cs | 13 --- .../ExpressionFactory/Query/Field.cs | 8 -- .../ExpressionFactory/Query/FilterGroup.cs | 29 ------ .../ExpressionFactory/Query/FilterOperator.cs | 15 --- .../ExpressionFactory/Query/FilterType.cs | 9 -- .../Query/LogicalOperator.cs | 30 ------ .../ExpressionFactory/Query/SortDirection.cs | 15 --- .../ExpressionFactory/Query/Value.cs | 28 ------ .../Strata.SqlTools.Snowflake.csproj | 1 + .../ExpressionFactory/ExpressionFactory.cs | 2 +- .../Query/AggregationType.cs | 12 --- .../Query/CalculationFilterGroup.cs | 34 ------- .../ExpressionFactory/Query/Filter.cs | 91 ------------------- .../Query/FilterCondition.cs | 17 ---- .../ExpressionFactory/Query/QueryConfig.cs | 33 ------- .../Query/QueryConfigExtensions.cs | 20 ---- .../ExpressionFactory/Query/Row.cs | 11 --- .../ExpressionFactory/Query/SqlResponse.cs | 13 --- .../ExpressionFactory/Query/ValueFilter.cs | 8 -- .../Strata.SqlTools.SqlServer.csproj | 1 + .../ExpressionFactoryFilterTests.cs | 2 +- .../ExpressionTests/ExpressionTestsBase.cs | 2 +- 44 files changed, 36 insertions(+), 445 deletions(-) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/AggregationType.cs (69%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/CalculationFilter.cs (87%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/CalculationFilterGroup.cs (83%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/ColumnQueryConfig.cs (89%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/DatePart.cs (68%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/Field.cs (73%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/Filter.cs (98%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/FilterCondition.cs (87%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/FilterGroup.cs (91%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/FilterOperator.cs (84%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/FilterType.cs (61%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/LogicalOperator.cs (90%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/QueryConfig.cs (93%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/QueryConfigExtensions.cs (93%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/Row.cs (71%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/SortDirection.cs (79%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/SqlResponse.cs (83%) rename src/{Strata.SqlTools.SqlServer/ExpressionFactory/Query => Strata.SqlTools.Query}/Value.cs (94%) rename src/{Strata.SqlTools.Snowflake/ExpressionFactory/Query => Strata.SqlTools.Query}/ValueFilter.cs (65%) delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/CalculationFilter.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/ColumnQueryConfig.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/DatePart.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Field.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterGroup.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterOperator.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterType.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/LogicalOperator.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/SortDirection.cs delete mode 100644 src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Value.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/AggregationType.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/CalculationFilterGroup.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Filter.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterCondition.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfig.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfigExtensions.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Row.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/SqlResponse.cs delete mode 100644 src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/ValueFilter.cs diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 3970ede..d9b3047 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -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: \" })", + "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 *)" ] } } diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/AggregationType.cs b/src/Strata.SqlTools.Query/AggregationType.cs similarity index 69% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/AggregationType.cs rename to src/Strata.SqlTools.Query/AggregationType.cs index debf2b3..088cf1d 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/AggregationType.cs +++ b/src/Strata.SqlTools.Query/AggregationType.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public enum AggregationType { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/CalculationFilter.cs b/src/Strata.SqlTools.Query/CalculationFilter.cs similarity index 87% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/CalculationFilter.cs rename to src/Strata.SqlTools.Query/CalculationFilter.cs index 7a2ae1d..c83d340 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/CalculationFilter.cs +++ b/src/Strata.SqlTools.Query/CalculationFilter.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class CalculationFilter : Filter { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/CalculationFilterGroup.cs b/src/Strata.SqlTools.Query/CalculationFilterGroup.cs similarity index 83% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/CalculationFilterGroup.cs rename to src/Strata.SqlTools.Query/CalculationFilterGroup.cs index ce0f011..b31ef36 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/CalculationFilterGroup.cs +++ b/src/Strata.SqlTools.Query/CalculationFilterGroup.cs @@ -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 GetValidFilters() { - return Filters?.Where(x => x.IsValid()).ToList() ?? new List(); + return Filters?.Where(x => x.IsValid()).ToList() ?? []; } public bool IsValid() diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/ColumnQueryConfig.cs b/src/Strata.SqlTools.Query/ColumnQueryConfig.cs similarity index 89% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/ColumnQueryConfig.cs rename to src/Strata.SqlTools.Query/ColumnQueryConfig.cs index 99cd89a..9fa045d 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/ColumnQueryConfig.cs +++ b/src/Strata.SqlTools.Query/ColumnQueryConfig.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class ColumnQueryConfig { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/DatePart.cs b/src/Strata.SqlTools.Query/DatePart.cs similarity index 68% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/DatePart.cs rename to src/Strata.SqlTools.Query/DatePart.cs index 85f5976..98228ea 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/DatePart.cs +++ b/src/Strata.SqlTools.Query/DatePart.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public enum DatePart { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Field.cs b/src/Strata.SqlTools.Query/Field.cs similarity index 73% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Field.cs rename to src/Strata.SqlTools.Query/Field.cs index 32b695a..84d5b08 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Field.cs +++ b/src/Strata.SqlTools.Query/Field.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class Field { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Filter.cs b/src/Strata.SqlTools.Query/Filter.cs similarity index 98% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Filter.cs rename to src/Strata.SqlTools.Query/Filter.cs index b55e919..bbaff2d 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Filter.cs +++ b/src/Strata.SqlTools.Query/Filter.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; /// /// Represents a filter criteria for querying data with support for various filter types including lists, date ranges, and timeframes. diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterCondition.cs b/src/Strata.SqlTools.Query/FilterCondition.cs similarity index 87% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterCondition.cs rename to src/Strata.SqlTools.Query/FilterCondition.cs index c8f0dc8..a670099 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterCondition.cs +++ b/src/Strata.SqlTools.Query/FilterCondition.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class FilterCondition { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterGroup.cs b/src/Strata.SqlTools.Query/FilterGroup.cs similarity index 91% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterGroup.cs rename to src/Strata.SqlTools.Query/FilterGroup.cs index ff1e7d5..209d3cd 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterGroup.cs +++ b/src/Strata.SqlTools.Query/FilterGroup.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class FilterGroup { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterOperator.cs b/src/Strata.SqlTools.Query/FilterOperator.cs similarity index 84% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterOperator.cs rename to src/Strata.SqlTools.Query/FilterOperator.cs index 970f181..b92d6a2 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterOperator.cs +++ b/src/Strata.SqlTools.Query/FilterOperator.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public enum FilterOperator { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterType.cs b/src/Strata.SqlTools.Query/FilterType.cs similarity index 61% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterType.cs rename to src/Strata.SqlTools.Query/FilterType.cs index 712c008..047048f 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterType.cs +++ b/src/Strata.SqlTools.Query/FilterType.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public enum FilterType { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/LogicalOperator.cs b/src/Strata.SqlTools.Query/LogicalOperator.cs similarity index 90% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/LogicalOperator.cs rename to src/Strata.SqlTools.Query/LogicalOperator.cs index fef184c..f1510e5 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/LogicalOperator.cs +++ b/src/Strata.SqlTools.Query/LogicalOperator.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public enum LogicalOperator { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/QueryConfig.cs b/src/Strata.SqlTools.Query/QueryConfig.cs similarity index 93% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/QueryConfig.cs rename to src/Strata.SqlTools.Query/QueryConfig.cs index 2b9073f..0157dda 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/QueryConfig.cs +++ b/src/Strata.SqlTools.Query/QueryConfig.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class QueryConfig { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/QueryConfigExtensions.cs b/src/Strata.SqlTools.Query/QueryConfigExtensions.cs similarity index 93% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/QueryConfigExtensions.cs rename to src/Strata.SqlTools.Query/QueryConfigExtensions.cs index 7d62951..3297933 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/QueryConfigExtensions.cs +++ b/src/Strata.SqlTools.Query/QueryConfigExtensions.cs @@ -1,5 +1,5 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public static class QueryConfigExtensions { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Row.cs b/src/Strata.SqlTools.Query/Row.cs similarity index 71% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Row.cs rename to src/Strata.SqlTools.Query/Row.cs index 22d4f4f..22d7590 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Row.cs +++ b/src/Strata.SqlTools.Query/Row.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class Row : Field { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/SortDirection.cs b/src/Strata.SqlTools.Query/SortDirection.cs similarity index 79% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/SortDirection.cs rename to src/Strata.SqlTools.Query/SortDirection.cs index 3ddf421..c5f9f02 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/SortDirection.cs +++ b/src/Strata.SqlTools.Query/SortDirection.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public enum SortDirection { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/SqlResponse.cs b/src/Strata.SqlTools.Query/SqlResponse.cs similarity index 83% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/SqlResponse.cs rename to src/Strata.SqlTools.Query/SqlResponse.cs index 9274b07..4ab1125 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/SqlResponse.cs +++ b/src/Strata.SqlTools.Query/SqlResponse.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class SqlResponse { diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Value.cs b/src/Strata.SqlTools.Query/Value.cs similarity index 94% rename from src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Value.cs rename to src/Strata.SqlTools.Query/Value.cs index 56ec66a..514c024 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Value.cs +++ b/src/Strata.SqlTools.Query/Value.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class Value { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/ValueFilter.cs b/src/Strata.SqlTools.Query/ValueFilter.cs similarity index 65% rename from src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/ValueFilter.cs rename to src/Strata.SqlTools.Query/ValueFilter.cs index 6f741fd..62cfad6 100644 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/ValueFilter.cs +++ b/src/Strata.SqlTools.Query/ValueFilter.cs @@ -1,4 +1,4 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; +namespace Strata.SqlTools.Query; public class ValueFilter { diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/CalculationFilter.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/CalculationFilter.cs deleted file mode 100644 index c0278f7..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/CalculationFilter.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; - -public class CalculationFilter : Filter -{ - public IEnumerable AliasedDataColumnIds { get; } - - public CalculationFilter(int dataColumnId, IEnumerable aliasedDataColumnIds, IEnumerable values, IEnumerable conditions) - : base(dataColumnId, FilterType.Conditions, values, conditions, DatePart.Continuous, false, 0, 0) - { - AliasedDataColumnIds = aliasedDataColumnIds; - } -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/ColumnQueryConfig.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/ColumnQueryConfig.cs deleted file mode 100644 index 37f472e..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/ColumnQueryConfig.cs +++ /dev/null @@ -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; - } -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/DatePart.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/DatePart.cs deleted file mode 100644 index 798ca43..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/DatePart.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; - -public enum DatePart -{ - Continuous = 0, - Year, - Quarter, - Month, - Week, - Day, - FiscalYear, - FiscalQuarter -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Field.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Field.cs deleted file mode 100644 index 2608032..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Field.cs +++ /dev/null @@ -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; } -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterGroup.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterGroup.cs deleted file mode 100644 index b5c3e37..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterGroup.cs +++ /dev/null @@ -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 Filters { get; } - - public FilterGroup() - { - LogicalOperator = LogicalOperator.And; - Filters = new List(); - } - - [JsonConstructor] - public FilterGroup(IEnumerable filters, LogicalOperator logicalOperator) - { - Filters = filters.Where(x => x.IsValid()).ToList(); - LogicalOperator = logicalOperator; - } - - public bool IsValid() - { - return Filters != null && Filters.Any(); - } -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterOperator.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterOperator.cs deleted file mode 100644 index 2bcef52..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterOperator.cs +++ /dev/null @@ -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 -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterType.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterType.cs deleted file mode 100644 index 6ee9e9b..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/FilterType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Strata.SqlTools.Snowflake.ExpressionFactory.Query; - -public enum FilterType -{ - List = 0, - Conditions = 1, - Calendar = 2, - Timeframe = 3 -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/LogicalOperator.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/LogicalOperator.cs deleted file mode 100644 index 3e022da..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/LogicalOperator.cs +++ /dev/null @@ -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; - } -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/SortDirection.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/SortDirection.cs deleted file mode 100644 index 69c1a3a..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/SortDirection.cs +++ /dev/null @@ -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(); - } -} diff --git a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Value.cs b/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Value.cs deleted file mode 100644 index 075c5d8..0000000 --- a/src/Strata.SqlTools.Snowflake/ExpressionFactory/Query/Value.cs +++ /dev/null @@ -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 CalculationDataColumnIds { get; } - public IEnumerable AliasedIds { get; } - - public IEnumerable FilterGroups { get; } - - public Value() : this(string.Empty, string.Empty, new int[0], new string[0], new CalculationFilterGroup[0]) - { - // FilterGroups = new List(); - } - - [JsonConstructor] - public Value(string columnAlias, string calculation, IEnumerable calculationDataColumnIds, IEnumerable aliasedIds, IEnumerable filterGroups) - { - ColumnAlias = columnAlias; - Calculation = calculation; - CalculationDataColumnIds = calculationDataColumnIds ?? Array.Empty(); - AliasedIds = aliasedIds ?? aliasedIds ?? Array.Empty(); - FilterGroups = filterGroups?.Where(x => x.IsValid()).ToList() ?? new List(); - } -} diff --git a/src/Strata.SqlTools.Snowflake/Strata.SqlTools.Snowflake.csproj b/src/Strata.SqlTools.Snowflake/Strata.SqlTools.Snowflake.csproj index 15ea2d1..9b2ace2 100644 --- a/src/Strata.SqlTools.Snowflake/Strata.SqlTools.Snowflake.csproj +++ b/src/Strata.SqlTools.Snowflake/Strata.SqlTools.Snowflake.csproj @@ -41,6 +41,7 @@ + diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/ExpressionFactory.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/ExpressionFactory.cs index ee33eb7..7e9dd1d 100644 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/ExpressionFactory.cs +++ b/src/Strata.SqlTools.SqlServer/ExpressionFactory/ExpressionFactory.cs @@ -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; diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/AggregationType.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/AggregationType.cs deleted file mode 100644 index 2cd015a..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/AggregationType.cs +++ /dev/null @@ -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 -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/CalculationFilterGroup.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/CalculationFilterGroup.cs deleted file mode 100644 index ce4f1b1..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/CalculationFilterGroup.cs +++ /dev/null @@ -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 Filters { get; set; } - - public CalculationFilterGroup() - { - LogicalOperator = LogicalOperator.And; - Filters = new List(); - } - - [JsonConstructor] - public CalculationFilterGroup(IEnumerable filters, LogicalOperator logicalOperator) - { - Filters = filters; - LogicalOperator = logicalOperator; - } - - public IEnumerable GetValidFilters() - { - return Filters?.Where(x => x.IsValid()).ToList() ?? new List(); - } - - public bool IsValid() - { - return Filters != null && Filters.Any(x => x.IsValid()); - } -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Filter.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Filter.cs deleted file mode 100644 index 726e6f1..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Filter.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; - -/// -/// 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. -/// -public class Filter -{ - /// - /// Gets the identifier of the data column to which this filter applies. - /// - public int DataColumnId { get; } - - /// - /// Gets the type of filter being applied (e.g., List, Calendar, Timeframe). - /// - public FilterType FilterType { get; } - - /// - /// Gets the collection of values to filter by. The interpretation depends on the . - /// - public IEnumerable Values { get; } - - /// - /// Gets the collection of filter conditions that define complex filtering logic. - /// Only valid conditions are retained. - /// - public IEnumerable Conditions { get; } - - /// - /// Gets the date granularity part for date-based filtering (e.g., Year, Month, Day, FiscalYear). - /// - public DatePart DatePart { get; } - - /// - /// Gets a value indicating whether to use NOT IN instead of IN for list-type filters. - /// Only applies when is List. - /// - public bool ListUseNotIn { get; } - - /// - /// Gets the offset from the current time for timeframe-based filters. - /// Used in conjunction with to define relative time periods. - /// - public int DateTimeFrameOffset { get; } - - /// - /// 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 property. - /// - public int DateTimeFrameCount { get; } - - /// - /// Initializes a new instance of the class with the specified filter criteria. - /// - /// The identifier of the data column to filter. - /// The type of filter to apply. - /// The collection of values for the filter. - /// The collection of filter conditions (invalid conditions are automatically removed). - /// The date granularity for date-based filtering. - /// Whether to use NOT IN for list filters; false to use IN. - /// The offset from current time for timeframe filters. - /// The number of time increments from the offset (0 = current, negative = past, positive = future). - [JsonConstructor] - public Filter(int dataColumnId, FilterType filterType, IEnumerable values, IEnumerable 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; - } - - /// - /// 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. - /// - /// - /// true if the filter has values, conditions, or timeframe settings; otherwise, false. - /// - public bool IsValid() - { - return (Values != null && Values.Any()) || (Conditions != null && Conditions.Any()) || (DateTimeFrameCount != default || DateTimeFrameOffset != default); - } -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterCondition.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterCondition.cs deleted file mode 100644 index 9856236..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/FilterCondition.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; - -public class FilterCondition -{ - public FilterOperator Operator { get; set; } - - public IEnumerable? 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(); - } -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfig.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfig.cs deleted file mode 100644 index f64ddfc..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfig.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; - -public class QueryConfig -{ - public IEnumerable Rows { get; set; } - - public IEnumerable Values { get; set; } - - public IEnumerable FilterGroups { get; } - - public bool WithTotals { get; set; } - - public int RowLimit { get; set; } - - public QueryConfig() - { - Rows = new List(); - Values = new List(); - FilterGroups = new List(); - } - - [JsonConstructor] - public QueryConfig(IEnumerable filterGroups, IEnumerable rows, IEnumerable values, bool withTotals, int rowLimit) - { - FilterGroups = filterGroups.Where(x => x.IsValid()).ToList(); - Rows = rows; - Values = values; - WithTotals = withTotals; - RowLimit = rowLimit; - } -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfigExtensions.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfigExtensions.cs deleted file mode 100644 index 33f623d..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/QueryConfigExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ - -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; - -public static class QueryConfigExtensions -{ - /// - /// Gets all column ids referenced by this - /// - /// - /// - 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(); - } -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Row.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Row.cs deleted file mode 100644 index b602d65..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/Row.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; - -public class Row : Field -{ - public SortDirection sortDirection { get; set; } - - public Row() - { - sortDirection = SortDirection.Asc; - } -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/SqlResponse.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/SqlResponse.cs deleted file mode 100644 index e802cac..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/SqlResponse.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; - -public class SqlResponse -{ - public string SqlQuery { get; } - public IEnumerable> Parameters { get; } - - public SqlResponse(string sqlQuery, IEnumerable> parameters) - { - SqlQuery = sqlQuery; - Parameters = parameters; - } -} diff --git a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/ValueFilter.cs b/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/ValueFilter.cs deleted file mode 100644 index 0df4cb6..0000000 --- a/src/Strata.SqlTools.SqlServer/ExpressionFactory/Query/ValueFilter.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Strata.SqlTools.SqlServer.ExpressionFactory.Query; - -public class ValueFilter -{ - public int DataColumnId { get; set; } - - public object? FilterValue { get; set; } -} diff --git a/src/Strata.SqlTools.SqlServer/Strata.SqlTools.SqlServer.csproj b/src/Strata.SqlTools.SqlServer/Strata.SqlTools.SqlServer.csproj index 814ad45..4f4d830 100644 --- a/src/Strata.SqlTools.SqlServer/Strata.SqlTools.SqlServer.csproj +++ b/src/Strata.SqlTools.SqlServer/Strata.SqlTools.SqlServer.csproj @@ -41,6 +41,7 @@ + diff --git a/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionFactoryFilterTests.cs b/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionFactoryFilterTests.cs index 48f271f..eb5d708 100644 --- a/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionFactoryFilterTests.cs +++ b/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionFactoryFilterTests.cs @@ -1,4 +1,4 @@ -using Strata.SqlTools.SqlServer.ExpressionFactory.Query; +using Strata.SqlTools.Query; namespace Strata.SqlTools.SqlBreakdown.Tests.ExpressionTests; diff --git a/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionTestsBase.cs b/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionTestsBase.cs index 0551063..fa1efae 100644 --- a/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionTestsBase.cs +++ b/tests/Strata.SqlTools.SqlBreakdown.Tests/ExpressionTests/ExpressionTestsBase.cs @@ -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;