Commit Graph
6 Commits
Author SHA1 Message Date
Thom LambandClaude Opus 4.7 4b5348c53a refactor(dedup): share TruncateText across Markdown generators
`TruncateText` was copy-pasted verbatim in three Markdown generators
(`SqlServer.QueryBreakdownGenerator`, `SqlServer.SqlStatementGenerator`,
`Expressions.ExpressionGenerator`). Pulled out to a new
`Strata.SqlTools.Markdown.Internal.MarkdownTextHelpers` static class
(internal — no public-API change).

Each call site keeps its own one-line private wrapper for source
readability so existing `TruncateText(...)` calls in the generators
need no edits.

Deliberately *not* unified across the same three files:
- `EscapeMermaidText` (QueryBreakdownGenerator) vs `EscapeMermaidText`
  (SqlStatementGenerator) — the QBG version intentionally escapes
  `[]{}()` for Mermaid node syntax; the SSG version only escapes
  quotes/newlines because it writes into `Note right of DB: ...`
  contexts where brackets render fine.
- `EscapeMarkdown` (ExpressionGenerator) — a different escape set
  again, targeting Markdown rather than Mermaid.

Also deliberately *not* refactored: `SqlServer.UpdateBreakdown.TryParse`
≡ `SqlServer.ProcedureBreakdown.TryParse` prelude (empty-check +
parser + prefix regex + extract setup/finish clauses). The 30-line
duplication is real, but every extraction shape (tuple return,
`out`-flavored helper, context type) is measurably worse than the
duplicated original. Leaving it.

All 1180 tests stay green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 16:24:51 -05:00
Thom LambandClaude Opus 4.7 d4b66838b5 refactor(dedup): extract self-duplicated helpers in three src/ files
Tackles the in-file copy-paste duplications SonarQube flagged on
`sql-utilities`, narrowing the dedup target to the cases where the
extraction is a clear readability win.

- `LinqToSql.Converters.ReverseConverterExtensions`: the three
  `ToLinqQueryBreakdown` overloads (SqlServer / PostgreSql / Snowflake)
  had identical 26-line bodies. Routes all three through a single
  `BuildLinqBreakdownFrom(QueryBreakdown)` private helper — works
  because Snowflake/PostgreSql `QueryBreakdown` derive from the
  SqlServer one, so the parameter type accepts all three. Public API
  preserved.

- `Markdown.Expressions.ExpressionGenerator`: `VisitInExpression` and
  `VisitNotInExpression` had identical 18-line bodies differing only in
  the "IN"/"NOT IN" label. Both now delegate to a new private
  `RenderInList(label, searchExpression, values)`.

- `PostgreSql.Statements.StatementExpressionParser`: the qualified-
  column-name building loop and the column-id switch were duplicated
  across `HandleStringToken` (qualified-column branch) and
  `GrabColumnExpression`. Extracted to a shared
  `BuildQualifiedColumnExpression(seededBuilder, reader)` private helper.

Deliberately *not* refactored: `PostgreSql.Statements.StatementReader`'s
`<` / `>` operator handlers, which Sonar also flags as duplicate. The
shared pattern there is a structural sequence of "MovePosition;
character check; emit Token; return" repeated across single-/two-char
operator variants; folding it into a helper would replace four short,
self-explanatory inline checks with `TryMatchTwoCharOperator('=', ...)`
indirection that obscures what each branch actually emits. The dedup
isn't worth the readability tax.

All 1180 tests stay green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 16:22:45 -05:00
Thom LambandClaude Opus 4.7 3c602a4625 chore(sonar): mark private helpers static (CA1822)
Two private methods that don't touch instance state get the `static`
keyword:

- `LinqExpressionVisitor.ExtractMemberName`
- `Markdown.Expressions.ExpressionGenerator.GenerateMermaidDiagram(Expression)`

Both have only intra-class callers, so this is a non-breaking change —
the call sites continue to work unchanged under C# method-resolution.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 14:19:26 -05:00
Thom LambandClaude Opus 4.7 84b06557e5 chore(sonar)!: mark instance-data-free members static (CA1822)
Applied via `dotnet format analyzers --diagnostics CA1822 --severity info`.
12 files touched. The fixer also updated internal callers in tests to use
the type-name form (e.g. `gen.Method(x)` -> `Generator.Method(x)`); build
and full test suite remain green.

BREAKING CHANGE: two public methods become static and therefore can no
longer be invoked through an instance reference by external consumers:
- Strata.SqlTools.Markdown.LinqToSql.QueryBreakdownGenerator.GenerateMethodChainDiagram
- Strata.SqlTools.Markdown.LinqToSql.SqlStatementGenerator.GenerateLinqPipelineDiagram

Both are stateless utility methods on Generator classes — the static form
is the correct shape; the only callers in this repo already used the
type-name form. External code should change `gen.GenerateMethodChainDiagram(...)`
to `QueryBreakdownGenerator.GenerateMethodChainDiagram(...)`.

All other CA1822 hits in this commit are on private/protected members
(no public-surface impact).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 15:41:46 -05:00
Thom LambandClaude Opus 4.7 2c2a8b1193 chore(sonar): bulk-fix mechanical CA/IDE analyzer warnings
Applied via `dotnet format analyzers --diagnostics IDE0028 CA1825 CA1834
CA1845 CA1847 CA1860 CA1866 CA1853 CA1830 CA1846 CA1806 CA1869 CA2249
--severity info`. 19 files touched, all mechanical syntactic rewrites:

- CA1847: string.Contains("x") -> string.Contains('x')
- CA2249: s.IndexOf(c) == -1 -> !s.Contains(c)
- CA1830: sb.Append(sb.ToString()) -> sb.Append(sb)
- CA1834: StringBuilder.Append("x") -> Append('x')
- CA1825, CA1860, CA1866, CA1853, IDE0028, CA1845: corresponding fixers

Three rules in the batch had no batch fixer available (CA1846 ×4,
CA1806 ×1, CA1869 ×1) and stay open for separate manual handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 15:38:54 -05:00
Thom Lamb 5e467bcc9c chore: initial git load of code space 2026-05-12 08:52:33 -05:00