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(); } }