using Strata.SqlTools.Breakdowns.LinqToSql;
namespace Strata.SqlTools.Builders.LinqToSql;
///
/// Fluent builder for constructing LinqQueryBreakdown instances programmatically.
/// Useful for scenarios where you don't have a live IQueryable to analyze.
///
public class LinqQueryBreakdownBuilder
{
private readonly LinqQueryBreakdown _breakdown;
private readonly List _selectColumns = new();
private string? _fromTable;
private string? _whereClause;
private string? _groupByClause;
private string? _havingClause;
private string? _orderByClause;
///
/// Initializes a new instance of the class.
///
public LinqQueryBreakdownBuilder()
{
_breakdown = new LinqQueryBreakdown();
}
///
/// Sets the SELECT columns for the query.
///
/// Column names to select.
/// This builder for method chaining.
public LinqQueryBreakdownBuilder SelectColumns(params string[] columns)
{
if (columns.Length == 0)
{
_selectColumns.Add("*");
}
else
{
_selectColumns.AddRange(columns);
}
return this;
}
///
/// Sets the SELECT to all columns (*).
///
/// This builder for method chaining.
public LinqQueryBreakdownBuilder SelectAll()
{
_selectColumns.Clear();
_selectColumns.Add("*");
return this;
}
///
/// Sets the FROM table for the query.
///
/// The table name.
/// This builder for method chaining.
public LinqQueryBreakdownBuilder FromTable(string tableName)
{
if (string.IsNullOrWhiteSpace(tableName))
{
throw new ArgumentException("Table name cannot be null or empty.", nameof(tableName));
}
_fromTable = tableName;
return this;
}
///
/// Sets the WHERE clause for the query.
///
/// The WHERE condition.
/// This builder for method chaining.
public LinqQueryBreakdownBuilder Where(string condition)
{
if (!string.IsNullOrWhiteSpace(condition))
{
_whereClause = condition;
}
return this;
}
///
/// Sets the GROUP BY clause for the query.
///
/// The columns to group by.
/// This builder for method chaining.
public LinqQueryBreakdownBuilder GroupBy(params string[] columns)
{
if (columns.Length > 0)
{
_groupByClause = string.Join(", ", columns);
}
return this;
}
///
/// Sets the HAVING clause for the query.
///
/// The HAVING condition.
/// This builder for method chaining.
public LinqQueryBreakdownBuilder Having(string condition)
{
if (!string.IsNullOrWhiteSpace(condition))
{
_havingClause = condition;
}
return this;
}
///
/// Sets the ORDER BY clause for the query.
///
/// The ORDER BY specification (e.g., "Name ASC, Age DESC").
/// This builder for method chaining.
public LinqQueryBreakdownBuilder OrderBy(string orderSpecification)
{
if (!string.IsNullOrWhiteSpace(orderSpecification))
{
_orderByClause = orderSpecification;
}
return this;
}
///
/// Adds an ORDER BY clause in ascending order.
///
/// The column to order by.
/// This builder for method chaining.
public LinqQueryBreakdownBuilder OrderByAscending(string column)
{
if (string.IsNullOrWhiteSpace(column))
{
throw new ArgumentException("Column name cannot be null or empty.", nameof(column));
}
_orderByClause = $"{column} ASC";
return this;
}
///
/// Adds an ORDER BY clause in descending order.
///
/// The column to order by.
/// This builder for method chaining.
public LinqQueryBreakdownBuilder OrderByDescending(string column)
{
if (string.IsNullOrWhiteSpace(column))
{
throw new ArgumentException("Column name cannot be null or empty.", nameof(column));
}
_orderByClause = $"{column} DESC";
return this;
}
///
/// Builds and returns the LinqQueryBreakdown instance.
///
/// A new LinqQueryBreakdown with the configured clauses.
/// Thrown when required clauses are missing.
public LinqQueryBreakdown Build()
{
if (_selectColumns.Count == 0)
{
throw new InvalidOperationException("At least one SELECT column must be specified.");
}
if (string.IsNullOrWhiteSpace(_fromTable))
{
throw new InvalidOperationException("FROM table must be specified.");
}
var breakdown = new LinqQueryBreakdown(
string.Join(", ", _selectColumns),
_fromTable,
_whereClause ?? string.Empty
);
if (!string.IsNullOrWhiteSpace(_groupByClause))
{
breakdown.GroupByClause.Clause = _groupByClause;
}
if (!string.IsNullOrWhiteSpace(_havingClause))
{
breakdown.HavingClause.Clause = _havingClause;
}
if (!string.IsNullOrWhiteSpace(_orderByClause))
{
breakdown.OrderByClause.Clause = _orderByClause;
}
return breakdown;
}
///
/// Gets a SQL Server formatted preview of the query being built.
///
/// Preview SQL statement.
public string PreviewSql()
{
try
{
return Build().ToSqlServerSql();
}
catch (InvalidOperationException)
{
return "-- Incomplete query (missing required clauses)";
}
}
///
/// Creates a new builder with the default state.
///
/// A new LinqQueryBreakdownBuilder instance.
public static LinqQueryBreakdownBuilder Create()
{
return new LinqQueryBreakdownBuilder();
}
///
/// Creates a builder with a table already specified.
///
/// The table to select from.
/// A new builder with the table set.
public static LinqQueryBreakdownBuilder CreateForTable(string tableName)
{
return new LinqQueryBreakdownBuilder().FromTable(tableName);
}
}