Files
sql-utilities/docs/SqlUtilities.Markdown.md
T

14 KiB

Strata.SqlTools.Markdown

SQL Query Visualization with Mermaid Diagrams


Overview

The Strata.SqlTools.Markdown package provides comprehensive visualization tools for SQL queries using Mermaid diagrams. It generates flowcharts, sequence diagrams, entity-relationship diagrams, and specialized visualizations for different SQL dialects.

Supported Dialects

  • SQL Server - T-SQL query visualization
  • PostgreSQL - PostgreSQL query visualization with parameter analysis
  • Snowflake - Snowflake query visualization
  • LINQ to SQL - LINQ expression tree and execution pipeline visualization

Installation

dotnet add package Strata.SqlTools.Markdown

Dependencies:

  • Strata.SqlTools (core)
  • Strata.SqlTools.SqlServer (for SQL Server visualizations)
  • Strata.SqlTools.PostgreSql (for PostgreSQL visualizations)
  • Strata.SqlTools.Snowflake (for Snowflake visualizations)
  • Strata.SqlTools.LinqToSql (for LINQ visualizations)

Quick Start

Basic Query Diagram

using Strata.SqlTools.Breakdowns.SqlServer;
using Strata.SqlTools.Markdown.SqlServer;

var breakdown = new QueryBreakdown(@"
    SELECT id, name, email
    FROM users
    WHERE age > @minAge
    ORDER BY name ASC
");

var generator = new QueryBreakdownGenerator();
string diagram = generator.GenerateMermaidDiagram(breakdown, "User Query");

Console.WriteLine(diagram);

Output:

### User Query

```mermaid
flowchart TD
    Start([Start]) --> Select[SELECT id, name, email]
    Select --> From[FROM users]
    From --> Where[WHERE age > @minAge]
    Where --> OrderBy[ORDER BY name ASC]
    OrderBy --> End([End])
```

SQL Server Visualizations

QueryBreakdownGenerator

Generate flowchart diagrams showing query structure:

using Strata.SqlTools.Markdown.SqlServer;

var generator = new QueryBreakdownGenerator();

// Generate basic flowchart
string diagram = generator.GenerateMermaidDiagram(breakdown, "Query Structure");

// Generate with CTE
var breakdown = new QueryBreakdown("*", "cte_result");
breakdown.AddWithClause("cte_result", subquery);
string cteDiagram = generator.GenerateMermaidDiagram(breakdown, "CTE Query");

SqlStatementGenerator

Generate sequence and ER diagrams:

var stmtGenerator = new SqlStatementGenerator();

// Sequence diagram showing execution flow
string sequence = stmtGenerator.GenerateSequenceDiagram(breakdown, "Execution");

// Entity-relationship diagram
var tables = new[] { "users", "orders", "products" };
string erDiagram = stmtGenerator.GenerateEntityRelationshipDiagram(tables, "Schema");

PostgreSQL Visualizations

QueryBreakdownGenerator

PostgreSQL-specific visualization with parameter tracking:

using Strata.SqlTools.Breakdowns.PostgreSql;
using Strata.SqlTools.Markdown.PostgreSql;

var breakdown = new QueryBreakdown(@"
    SELECT u.id, u.name, o.total
    FROM users u
    JOIN orders o ON u.id = o.user_id
    WHERE u.age > $1
    ORDER BY o.total DESC
");

var generator = new QueryBreakdownGenerator();
string diagram = generator.GenerateMermaidDiagram(breakdown, "User Orders");

QueryBreakdownCollectionGenerator

Visualize collections of queries:

using Strata.SqlTools.Markdown.PostgreSql;

var collection = new QueryBreakdownCollection();
collection.Add(new QueryBreakdown("SELECT * FROM users WHERE age > $1"));
collection.Add(new QueryBreakdown("SELECT * FROM orders WHERE status = $1"));

var collectionGen = new QueryBreakdownCollectionGenerator();

// Generate summary with all diagrams
string summary = collectionGen.GenerateCollectionSummary(collection, "All Queries");

// Generate parameter usage diagram
string paramDiagram = collectionGen.GenerateParameterUsageDiagram(collection);

// Generate table reference diagram
string tableDiagram = collectionGen.GenerateTableReferenceDiagram(collection);

Example Parameter Usage Diagram:

graph LR
    Q1[Query 1] --> P1[$1]
    Q2[Query 2] --> P1
    Q1 --> P2[$2]

    style P1 fill:#e1f5ff
    style P2 fill:#e1f5ff

Snowflake Visualizations

QueryBreakdownGenerator

Snowflake-specific query visualization:

using Strata.SqlTools.Breakdowns.Snowflake;
using Strata.SqlTools.Markdown.Snowflake;

var breakdown = new QueryBreakdown(@"
    SELECT *
    FROM database.schema.table
    WHERE created_at > :start_date
    LIMIT 100
");

var generator = new QueryBreakdownGenerator();
string diagram = generator.GenerateMermaidDiagram(breakdown, "Snowflake Query");

LINQ to SQL Visualizations

LINQ Method Chain Diagrams

Visualize LINQ query method chains:

using Strata.SqlTools.Breakdowns.LinqToSql;
using Strata.SqlTools.Markdown.LinqToSql;

var query = context.Users
    .Where(u => u.Age > 21)
    .OrderBy(u => u.Name)
    .Select(u => new { u.Id, u.Name });

var breakdown = LinqQueryBreakdown.Analyze(query);
var generator = new QueryBreakdownGenerator();

// Generate method chain diagram
string methodChain = generator.GenerateMethodChainDiagram(breakdown, "LINQ Flow");

Output:

flowchart LR
    Start[IQueryable] --> Where[Where]
    Where --> OrderBy[OrderBy]
    OrderBy --> Select[Select]
    Select --> Result[Result]

LINQ Execution Pipeline

Visualize how LINQ translates to SQL:

var sqlGenerator = new SqlStatementGenerator();
string pipeline = sqlGenerator.GenerateLinqPipelineDiagram(breakdown, "Execution Pipeline");

Output:

sequenceDiagram
    participant Client as Client Application
    participant LINQ as LINQ Provider
    participant ET as Expression Tree
    participant SQL as SQL Generator
    participant DB as Database

    Client->>LINQ: LINQ Query
    activate LINQ
    LINQ->>ET: Where Predicate
    activate ET
    LINQ->>ET: Select Projection
    ET->>SQL: Expression Tree
    deactivate ET
    SQL->>DB: Generate SQL
    activate DB
    DB-->>SQL: Result Set
    deactivate DB
    SQL-->>LINQ: Mapped Objects
    LINQ-->>Client: IEnumerable Result
    deactivate LINQ

Combined Diagrams

Show both method chain and SQL structure:

string combined = generator.GenerateCombinedDiagram(breakdown, "Full Analysis");

Advanced Features

Custom Diagram Titles

// With title
string diagram = generator.GenerateMermaidDiagram(breakdown, "My Custom Title");

// Without title
string diagram = generator.GenerateMermaidDiagram(breakdown, null);

Nested CTEs Visualization

var mainQuery = new QueryBreakdown("*", "cte2");
var cte1 = new QueryBreakdown("id, name", "users");
var cte2 = new QueryBreakdown("*", "cte1");

mainQuery.AddWithClause("cte1", cte1);
mainQuery.AddWithClause("cte2", cte2);

var generator = new QueryBreakdownGenerator();
string diagram = generator.GenerateMermaidDiagram(mainQuery, "Nested CTEs");

Collection Statistics

var collectionGen = new QueryBreakdownCollectionGenerator();
var collection = new QueryBreakdownCollection();
// ... add queries ...

// Generate statistics table
string stats = $@"
## Query Statistics

- Total Queries: {collection.Count}
- Total Selected Columns: {collection.GetTotalSelectedColumns()}
- Unique Tables: {string.Join(", ", collection.GetUniqueTableReferences())}

{collectionGen.GenerateCollectionSummary(collection, "Query Details")}
";

Integration with Documentation Tools

Markdown File Generation

public class QueryDocumentationGenerator
{
    public void GenerateDocumentation(string outputPath)
    {
        var sb = new StringBuilder();
        sb.AppendLine("# Database Queries Documentation");
        sb.AppendLine();

        var queries = GetAllQueries(); // Your query collection
        var generator = new QueryBreakdownGenerator();

        foreach (var (name, breakdown) in queries)
        {
            sb.AppendLine($"## {name}");
            sb.AppendLine();
            sb.AppendLine($"**SQL:**");
            sb.AppendLine("```sql");
            sb.AppendLine(breakdown.GetSql());
            sb.AppendLine("```");
            sb.AppendLine();
            sb.AppendLine(generator.GenerateMermaidDiagram(breakdown, $"{name} Flow"));
            sb.AppendLine();
        }

        File.WriteAllText(outputPath, sb.ToString());
    }
}

GitHub Pages / Wikis

The generated Mermaid diagrams work seamlessly with:

  • GitHub - Renders Mermaid in README.md and wiki pages
  • GitLab - Full Mermaid support in markdown
  • Azure DevOps - Mermaid support in wiki
  • Docusaurus - With mermaid plugin
  • MkDocs - With mermaid2 plugin

Diagram Customization

Flowchart Styles

The generators use standard Mermaid syntax. You can customize by modifying the output:

string diagram = generator.GenerateMermaidDiagram(breakdown, "Styled Query");

// Add custom styling
diagram = diagram.Replace("```mermaid", @"```mermaid
%%{init: {'theme':'forest'}}%%");

// Or add classDefs
diagram = diagram.Replace("```", @"
    classDef selectClass fill:#bbf,stroke:#333,stroke-width:2px
    classDef whereClass fill:#fbf,stroke:#333,stroke-width:2px
```");

Sequence Diagram Themes

string sequence = stmtGenerator.GenerateSequenceDiagram(breakdown, "Execution");

// Add theme
sequence = sequence.Replace("sequenceDiagram", @"%%{init: {'theme':'dark'}}%%
sequenceDiagram");

Common Use Cases

1. API Documentation

/// <summary>
/// Gets active users ordered by name.
/// </summary>
/// <remarks>
/// Query Details:
/// <code>
/// var generator = new QueryBreakdownGenerator();
/// var breakdown = new QueryBreakdown("SELECT * FROM users WHERE is_active = 1");
/// Console.WriteLine(generator.GenerateMermaidDiagram(breakdown, "Active Users"));
/// </code>
/// </remarks>
public async Task<List<User>> GetActiveUsers()
{
    // Implementation
}

2. Code Review Documentation

// Generate before/after diagrams for query optimization
var beforeBreakdown = new QueryBreakdown(originalQuery);
var afterBreakdown = new QueryBreakdown(optimizedQuery);

var generator = new QueryBreakdownGenerator();

File.WriteAllText("query-comparison.md", $@"
# Query Optimization Results

## Before
{generator.GenerateMermaidDiagram(beforeBreakdown, "Original Query")}

## After
{generator.GenerateMermaidDiagram(afterBreakdown, "Optimized Query")}

## Improvements
- Reduced number of JOINs
- Added index on filtered column
- Removed SELECT *
");

3. Testing Documentation

[Test]
public void ComplexQuery_GeneratesDiagram()
{
    var breakdown = BuildComplexQuery();
    var generator = new QueryBreakdownGenerator();
    string diagram = generator.GenerateMermaidDiagram(breakdown);

    // Save diagram for test documentation
    TestContext.WriteLine(diagram);

    // Assert query properties
    Assert.That(breakdown.WhereClause, Is.Not.Null);
}

Best Practices

1. Use Descriptive Titles

// Good: Descriptive title
generator.GenerateMermaidDiagram(breakdown, "Active Users by Department");

// Avoid: Generic title
generator.GenerateMermaidDiagram(breakdown, "Query 1");

2. Generate Diagrams for Complex Queries Only

// Generate diagrams for queries with multiple clauses
if (breakdown.GetClauses().Count() > 3)
{
    string diagram = generator.GenerateMermaidDiagram(breakdown, queryName);
    SaveDiagram(diagram);
}

3. Include SQL Alongside Diagrams

## User Query

**SQL:**
```sql
SELECT id, name, email
FROM users
WHERE age > 21
ORDER BY name

Flow: [Mermaid diagram here]


---

## Troubleshooting

### Diagram Not Rendering

**Problem**: Mermaid diagram shows as plain text

**Solution**: Ensure your markdown viewer supports Mermaid:
- GitHub: Native support ✅
- VS Code: Install "Markdown Preview Mermaid Support" extension
- Local rendering: Use `mermaid-cli` or online editors

### Diagram Too Complex

**Problem**: Large queries create cluttered diagrams

**Solution**: Break into smaller sections or use collection generator:

```csharp
// Instead of one large diagram, generate multiple focused diagrams
var generator = new QueryBreakdownGenerator();

// Main query flow
string mainFlow = generator.GenerateMermaidDiagram(mainQuery, "Main Query");

// CTE flows separately
foreach (var cte in mainQuery.WithClauses)
{
    string cteFlow = generator.GenerateMermaidDiagram(cte.Value, $"CTE: {cte.Key}");
}

API Reference

Generator Classes by Dialect

Namespace Generator Classes
Strata.SqlTools.Markdown.SqlServer QueryBreakdownGenerator, SqlStatementGenerator
Strata.SqlTools.Markdown.PostgreSql QueryBreakdownGenerator, SqlStatementGenerator, QueryBreakdownCollectionGenerator
Strata.SqlTools.Markdown.Snowflake QueryBreakdownGenerator, SqlStatementGenerator
Strata.SqlTools.Markdown.LinqToSql QueryBreakdownGenerator, SqlStatementGenerator

Common Methods

All QueryBreakdownGenerator classes provide:

string GenerateMermaidDiagram(breakdown, title?)     // Main flowchart diagram

All SqlStatementGenerator classes provide:

string GenerateSequenceDiagram(breakdown, title?)                    // Execution sequence
string GenerateEntityRelationshipDiagram(tables/breakdown, title?)  // ER diagram


Version: 1.0.0 Last Updated: February 2026 Package: Strata.SqlTools.Markdown