using Strata.SqlTools.SqlBreakdown.Interfaces;
using Strata.SqlTools.SqlBreakdown.Interfaces.QueryEngine;
namespace Strata.SqlTools.Markdown.LinqToSql;
///
/// Generates Mermaid diagrams for LINQ to SQL statements, including sequence diagrams
/// for statement execution flow and entity-relationship diagrams.
///
public class SqlStatementGenerator
{
private readonly SqlServer.SqlStatementGenerator _baseGenerator;
///
/// Initializes a new instance of the SqlStatementGenerator class.
///
public SqlStatementGenerator()
{
_baseGenerator = new SqlServer.SqlStatementGenerator();
}
///
/// Generates a Mermaid sequence diagram showing LINQ to SQL statement execution flow.
///
/// The LINQ to SQL breakdown object.
/// Optional title for the diagram.
/// A string containing the Mermaid sequence diagram markdown.
public string GenerateSequenceDiagram(ISqlBreakdown sqlBreakdown, string? title = null)
{
return _baseGenerator.GenerateSequenceDiagram(sqlBreakdown, title);
}
///
/// Generates a Mermaid entity-relationship diagram from a SQL breakdown.
///
/// The SQL breakdown containing query information.
/// Optional title for the diagram.
/// A string containing the Mermaid ER diagram markdown.
public string GenerateEntityRelationshipDiagram(ISqlBreakdown sqlBreakdown, string? title = null)
{
//Extract table names from breakdown - just use FROM clause for now
var queryBreakdown = sqlBreakdown as IQueryBreakdown;
var tableNames = new List();
var fromClauseText = queryBreakdown?.FromClause?.ToString();
if (!string.IsNullOrWhiteSpace(fromClauseText))
{
tableNames.Add(fromClauseText);
}
return _baseGenerator.GenerateEntityRelationshipDiagram(tableNames, title);
}
///
/// Generates a diagram showing LINQ execution pipeline from a SQL breakdown.
///
/// The query breakdown containing query information.
/// Optional title for the diagram.
/// A string containing the Mermaid diagram markdown.
public static string GenerateLinqPipelineDiagram(IQueryBreakdown queryBreakdown, string? title = null)
{
var sb = new System.Text.StringBuilder();
if (!string.IsNullOrWhiteSpace(title))
{
sb.AppendLine($"### {title}");
sb.AppendLine();
}
sb.AppendLine("```mermaid");
sb.AppendLine("sequenceDiagram");
sb.AppendLine(" participant Client as Client Application");
sb.AppendLine(" participant LINQ as LINQ Provider");
sb.AppendLine(" participant ET as Expression Tree");
sb.AppendLine(" participant SQL as SQL Generator");
sb.AppendLine(" participant DB as Database");
sb.AppendLine();
sb.AppendLine(" Client->>LINQ: LINQ Query");
sb.AppendLine(" activate LINQ");
// Check if there's a WHERE clause
var whereClause = queryBreakdown.WhereClause?.Clause;
if (!string.IsNullOrWhiteSpace(whereClause))
{
sb.AppendLine(" LINQ->>ET: Where Predicate");
sb.AppendLine(" activate ET");
}
// Check if there's a custom SELECT
var selectClause = queryBreakdown.SelectClause?.Clause;
if (!string.IsNullOrWhiteSpace(selectClause) && selectClause.Trim() != "*")
{
sb.AppendLine(" LINQ->>ET: Select Projection");
if (string.IsNullOrWhiteSpace(whereClause))
{
sb.AppendLine(" activate ET");
}
}
sb.AppendLine(" ET->>SQL: Expression Tree");
sb.AppendLine(" deactivate ET");
sb.AppendLine(" SQL->>DB: Generate SQL");
sb.AppendLine(" activate DB");
sb.AppendLine(" DB-->>SQL: Result Set");
sb.AppendLine(" deactivate DB");
sb.AppendLine(" SQL-->>LINQ: Mapped Objects");
sb.AppendLine(" LINQ-->>Client: IEnumerable Result");
sb.AppendLine(" deactivate LINQ");
sb.AppendLine("```");
sb.AppendLine();
return sb.ToString();
}
}