diff --git a/src/Strata.SqlTools.Markdown/Common/CollectionMarkdownGenerator.cs b/src/Strata.SqlTools.Markdown/Common/CollectionMarkdownGenerator.cs
new file mode 100644
index 0000000..977042b
--- /dev/null
+++ b/src/Strata.SqlTools.Markdown/Common/CollectionMarkdownGenerator.cs
@@ -0,0 +1,37 @@
+namespace Strata.SqlTools.Markdown.Common;
+
+///
+/// Shared method bodies for the per-dialect QueryBreakdownCollectionGenerator
+/// classes. Each dialect wraps its QueryBreakdownCollection in an
+/// adapter and supplies a dialect-specific
+/// ; this template handles the rest.
+///
+internal static class CollectionMarkdownGenerator
+{
+ public static string GenerateCollectionReport(ICollectionMarkdownData data, MarkdownDialectFormat format, string? title)
+ => CollectionReportWriter.CollectionReport(title, new[]
+ {
+ GenerateCollectionSummary(data),
+ GenerateParameterAnalysis(data, format),
+ GenerateQueryCompositionReport(data, format)
+ });
+
+ public static string GenerateCollectionSummary(ICollectionMarkdownData data)
+ => CollectionReportWriter.CollectionSummary(
+ data.QueryCount,
+ data.UniqueParameterCount,
+ data.TotalSelectedColumns,
+ data.UniqueTableCount);
+
+ public static string GenerateParameterAnalysis(ICollectionMarkdownData data, MarkdownDialectFormat format)
+ => CollectionReportWriter.ParameterAnalysis(data.ParameterRows.ToList(), data.QueriesForReport, format);
+
+ public static string GenerateParameterDependencyDiagram(ICollectionMarkdownData data, MarkdownDialectFormat format)
+ => CollectionReportWriter.ParameterDependencyDiagram(data.QueriesForReport, format);
+
+ public static string GenerateQueryCompositionReport(ICollectionMarkdownData data, MarkdownDialectFormat format)
+ => CollectionReportWriter.QueryCompositionReport(data.QueriesForReport, format);
+
+ public static string GenerateBatchFlowDiagram(ICollectionMarkdownData data, string? openLabel, string? closeLabel)
+ => CollectionReportWriter.BatchFlowDiagram(data.QueryCount, openLabel, closeLabel);
+}
diff --git a/src/Strata.SqlTools.Markdown/Common/ICollectionMarkdownData.cs b/src/Strata.SqlTools.Markdown/Common/ICollectionMarkdownData.cs
new file mode 100644
index 0000000..0dd70d1
--- /dev/null
+++ b/src/Strata.SqlTools.Markdown/Common/ICollectionMarkdownData.cs
@@ -0,0 +1,30 @@
+using SqlServerBreakdowns = Strata.SqlTools.Breakdowns.SqlServer;
+
+namespace Strata.SqlTools.Markdown.Common;
+
+///
+/// Dialect-neutral view of a QueryBreakdownCollection as seen by the Markdown
+/// generators. Each per-dialect QueryBreakdownCollectionGenerator wraps its
+/// dialect-specific collection in an implementation of this interface so the shared
+/// template can operate uniformly.
+///
+internal interface ICollectionMarkdownData
+{
+ int QueryCount { get; }
+ int UniqueParameterCount { get; }
+ int TotalSelectedColumns { get; }
+ int UniqueTableCount { get; }
+
+ ///
+ /// Queries as the base type. Used
+ /// directly by
+ /// (which needs ) and via covariance by the other
+ /// writer methods that accept .
+ ///
+ IReadOnlyList QueriesForReport { get; }
+
+ ///
+ /// Parameter usage already mapped into the writer's dialect-agnostic row type.
+ ///
+ IEnumerable ParameterRows { get; }
+}
diff --git a/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownCollectionGenerator.cs b/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownCollectionGenerator.cs
index 4fb82fd..1a28895 100644
--- a/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownCollectionGenerator.cs
+++ b/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownCollectionGenerator.cs
@@ -23,79 +23,63 @@ public static class QueryBreakdownCollectionGenerator
///
/// Generates a comprehensive collection report in Markdown format with PostgreSQL-specific information.
///
- /// The QueryBreakdownCollection to document.
- /// Optional title for the report.
- /// A string containing the Markdown documentation.
public static string GenerateCollectionReport(QueryBreakdownCollection collection, string? title = null)
- => CollectionReportWriter.CollectionReport(title, new[]
- {
- GenerateCollectionSummary(collection),
- GenerateParameterAnalysis(collection),
- GenerateQueryCompositionReport(collection)
- });
+ => CollectionMarkdownGenerator.GenerateCollectionReport(Adapt(collection), Format, title);
///
/// Generates a summary section for the collection.
///
- /// The QueryBreakdownCollection to summarize.
- /// Markdown summary section.
public static string GenerateCollectionSummary(QueryBreakdownCollection collection)
- => CollectionReportWriter.CollectionSummary(
- collection.QueryBreakdowns.Count,
- collection.GetAllUniqueParameters().Count(),
- collection.GetTotalSelectedColumns(),
- collection.GetUniqueTableReferences().Count());
+ => CollectionMarkdownGenerator.GenerateCollectionSummary(Adapt(collection));
///
/// Generates a parameter analysis report with PostgreSQL parameter syntax support.
///
- /// The QueryBreakdownCollection to analyze.
- /// Markdown parameter analysis section.
public static string GenerateParameterAnalysis(QueryBreakdownCollection collection)
- => CollectionReportWriter.ParameterAnalysis(MapParameters(collection), collection.QueryBreakdowns, Format);
+ => CollectionMarkdownGenerator.GenerateParameterAnalysis(Adapt(collection), Format);
///
/// Generates a Mermaid diagram showing parameter dependencies across queries.
///
- /// The QueryBreakdownCollection to visualize.
- /// Mermaid diagram markdown.
public static string GenerateParameterDependencyDiagram(QueryBreakdownCollection collection)
- => CollectionReportWriter.ParameterDependencyDiagram(collection.QueryBreakdowns, Format);
+ => CollectionMarkdownGenerator.GenerateParameterDependencyDiagram(Adapt(collection), Format);
///
/// Generates a detailed query composition report.
///
- /// The QueryBreakdownCollection to report on.
- /// Markdown composition report section.
public static string GenerateQueryCompositionReport(QueryBreakdownCollection collection)
- => CollectionReportWriter.QueryCompositionReport(collection.QueryBreakdowns, Format);
+ => CollectionMarkdownGenerator.GenerateQueryCompositionReport(Adapt(collection), Format);
///
/// Generates a batch execution flow diagram for PostgreSQL.
///
- /// The QueryBreakdownCollection to visualize.
- /// Whether to show transaction wrapping.
- /// Mermaid diagram markdown.
public static string GenerateBatchFlowDiagram(QueryBreakdownCollection collection, bool includeTransaction = false)
- => CollectionReportWriter.BatchFlowDiagram(
- collection.QueryBreakdowns.Count,
+ => CollectionMarkdownGenerator.GenerateBatchFlowDiagram(
+ Adapt(collection),
includeTransaction ? "BEGIN" : null,
includeTransaction ? "COMMIT" : null);
- ///
- /// Maps the collection's parameter usage report into the writer's dialect-agnostic rows.
- ///
- private static List MapParameters(QueryBreakdownCollection collection)
- => collection.GetParameterUsageReport()
- .Select(p => new ParameterUsageRow
+ private static ICollectionMarkdownData Adapt(QueryBreakdownCollection collection) => new Adapter(collection);
+
+ private sealed class Adapter : ICollectionMarkdownData
+ {
+ private readonly QueryBreakdownCollection _c;
+ public Adapter(QueryBreakdownCollection c) { _c = c; }
+ public int QueryCount => _c.QueryBreakdowns.Count;
+ public int UniqueParameterCount => _c.GetAllUniqueParameters().Count();
+ public int TotalSelectedColumns => _c.GetTotalSelectedColumns();
+ public int UniqueTableCount => _c.GetUniqueTableReferences().Count();
+ public IReadOnlyList QueriesForReport => _c.QueryBreakdowns;
+ public IEnumerable ParameterRows
+ => _c.GetParameterUsageReport().Select(p => new ParameterUsageRow
{
ParameterName = p.ParameterName,
IsUsedInAllQueries = p.IsUsedInAllQueries,
UsedInQueryCount = p.UsedInQueryCount,
TotalQueries = p.TotalQueries,
Value = p.Value
- })
- .ToList();
+ });
+ }
///
/// Formats a parameter using PostgreSQL syntax: $n for positional, :name for named.
diff --git a/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownCollectionGenerator.cs b/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownCollectionGenerator.cs
index 723907d..07ba541 100644
--- a/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownCollectionGenerator.cs
+++ b/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownCollectionGenerator.cs
@@ -22,79 +22,63 @@ public static class QueryBreakdownCollectionGenerator
///
/// Generates a comprehensive collection report in Markdown format.
///
- /// The QueryBreakdownCollection to document.
- /// Optional title for the report.
- /// A string containing the Markdown documentation.
public static string GenerateCollectionReport(QueryBreakdownCollection collection, string? title = null)
- => CollectionReportWriter.CollectionReport(title, new[]
- {
- GenerateCollectionSummary(collection),
- GenerateParameterAnalysis(collection),
- GenerateQueryCompositionReport(collection)
- });
+ => CollectionMarkdownGenerator.GenerateCollectionReport(Adapt(collection), Format, title);
///
/// Generates a summary section for the collection.
///
- /// The QueryBreakdownCollection to summarize.
- /// Markdown summary section.
public static string GenerateCollectionSummary(QueryBreakdownCollection collection)
- => CollectionReportWriter.CollectionSummary(
- collection.QueryBreakdowns.Count,
- collection.GetAllUniqueParameters().Count(),
- collection.GetTotalSelectedColumns(),
- collection.GetUniqueTableReferences().Count());
+ => CollectionMarkdownGenerator.GenerateCollectionSummary(Adapt(collection));
///
/// Generates a parameter analysis report.
///
- /// The QueryBreakdownCollection to analyze.
- /// Markdown parameter analysis section.
public static string GenerateParameterAnalysis(QueryBreakdownCollection collection)
- => CollectionReportWriter.ParameterAnalysis(MapParameters(collection), collection.QueryBreakdowns, Format);
+ => CollectionMarkdownGenerator.GenerateParameterAnalysis(Adapt(collection), Format);
///
/// Generates a Mermaid diagram showing parameter dependencies across queries.
///
- /// The QueryBreakdownCollection to visualize.
- /// Mermaid diagram markdown.
public static string GenerateParameterDependencyDiagram(QueryBreakdownCollection collection)
- => CollectionReportWriter.ParameterDependencyDiagram(collection.QueryBreakdowns, Format);
+ => CollectionMarkdownGenerator.GenerateParameterDependencyDiagram(Adapt(collection), Format);
///
/// Generates a detailed query composition report.
///
- /// The QueryBreakdownCollection to report on.
- /// Markdown composition report section.
public static string GenerateQueryCompositionReport(QueryBreakdownCollection collection)
- => CollectionReportWriter.QueryCompositionReport(collection.QueryBreakdowns, Format);
+ => CollectionMarkdownGenerator.GenerateQueryCompositionReport(Adapt(collection), Format);
///
/// Generates a batch execution flow diagram.
///
- /// The QueryBreakdownCollection to visualize.
- /// Whether to show transaction wrapping.
- /// Mermaid diagram markdown.
public static string GenerateBatchFlowDiagram(QueryBreakdownCollection collection, bool includeTransaction = false)
- => CollectionReportWriter.BatchFlowDiagram(
- collection.QueryBreakdowns.Count,
+ => CollectionMarkdownGenerator.GenerateBatchFlowDiagram(
+ Adapt(collection),
includeTransaction ? "BEGIN TRANSACTION" : null,
includeTransaction ? "COMMIT TRANSACTION" : null);
- ///
- /// Maps the collection's parameter usage report into the writer's dialect-agnostic rows.
- ///
- private static List MapParameters(QueryBreakdownCollection collection)
- => collection.GetParameterUsageReport()
- .Select(p => new ParameterUsageRow
+ private static ICollectionMarkdownData Adapt(QueryBreakdownCollection collection) => new Adapter(collection);
+
+ private sealed class Adapter : ICollectionMarkdownData
+ {
+ private readonly QueryBreakdownCollection _c;
+ public Adapter(QueryBreakdownCollection c) { _c = c; }
+ public int QueryCount => _c.QueryBreakdowns.Count;
+ public int UniqueParameterCount => _c.GetAllUniqueParameters().Count();
+ public int TotalSelectedColumns => _c.GetTotalSelectedColumns();
+ public int UniqueTableCount => _c.GetUniqueTableReferences().Count();
+ public IReadOnlyList QueriesForReport => _c.QueryBreakdowns;
+ public IEnumerable ParameterRows
+ => _c.GetParameterUsageReport().Select(p => new ParameterUsageRow
{
ParameterName = p.ParameterName,
IsUsedInAllQueries = p.IsUsedInAllQueries,
UsedInQueryCount = p.UsedInQueryCount,
TotalQueries = p.TotalQueries,
Value = p.Value
- })
- .ToList();
+ });
+ }
///
/// Gets the parameter type name from a parameter value.