232 lines
7.0 KiB
C#
232 lines
7.0 KiB
C#
using Strata.SqlTools.Breakdowns.LinqToSql;
|
|
|
|
namespace Strata.SqlTools.Builders.LinqToSql;
|
|
|
|
/// <summary>
|
|
/// Fluent builder for constructing LinqQueryBreakdown instances programmatically.
|
|
/// Useful for scenarios where you don't have a live IQueryable to analyze.
|
|
/// </summary>
|
|
public class LinqQueryBreakdownBuilder
|
|
{
|
|
private readonly LinqQueryBreakdown _breakdown;
|
|
private readonly List<string> _selectColumns = new();
|
|
private string? _fromTable;
|
|
private string? _whereClause;
|
|
private string? _groupByClause;
|
|
private string? _havingClause;
|
|
private string? _orderByClause;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="LinqQueryBreakdownBuilder"/> class.
|
|
/// </summary>
|
|
public LinqQueryBreakdownBuilder()
|
|
{
|
|
_breakdown = new LinqQueryBreakdown();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the SELECT columns for the query.
|
|
/// </summary>
|
|
/// <param name="columns">Column names to select.</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
public LinqQueryBreakdownBuilder SelectColumns(params string[] columns)
|
|
{
|
|
if (columns.Length == 0)
|
|
{
|
|
_selectColumns.Add("*");
|
|
}
|
|
else
|
|
{
|
|
_selectColumns.AddRange(columns);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the SELECT to all columns (*).
|
|
/// </summary>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
public LinqQueryBreakdownBuilder SelectAll()
|
|
{
|
|
_selectColumns.Clear();
|
|
_selectColumns.Add("*");
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the FROM table for the query.
|
|
/// </summary>
|
|
/// <param name="tableName">The table name.</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the WHERE clause for the query.
|
|
/// </summary>
|
|
/// <param name="condition">The WHERE condition.</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
public LinqQueryBreakdownBuilder Where(string condition)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(condition))
|
|
{
|
|
_whereClause = condition;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the GROUP BY clause for the query.
|
|
/// </summary>
|
|
/// <param name="columns">The columns to group by.</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
public LinqQueryBreakdownBuilder GroupBy(params string[] columns)
|
|
{
|
|
if (columns.Length > 0)
|
|
{
|
|
_groupByClause = string.Join(", ", columns);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the HAVING clause for the query.
|
|
/// </summary>
|
|
/// <param name="condition">The HAVING condition.</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
public LinqQueryBreakdownBuilder Having(string condition)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(condition))
|
|
{
|
|
_havingClause = condition;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the ORDER BY clause for the query.
|
|
/// </summary>
|
|
/// <param name="orderSpecification">The ORDER BY specification (e.g., "Name ASC, Age DESC").</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
public LinqQueryBreakdownBuilder OrderBy(string orderSpecification)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(orderSpecification))
|
|
{
|
|
_orderByClause = orderSpecification;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds an ORDER BY clause in ascending order.
|
|
/// </summary>
|
|
/// <param name="column">The column to order by.</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds an ORDER BY clause in descending order.
|
|
/// </summary>
|
|
/// <param name="column">The column to order by.</param>
|
|
/// <returns>This builder for method chaining.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds and returns the LinqQueryBreakdown instance.
|
|
/// </summary>
|
|
/// <returns>A new LinqQueryBreakdown with the configured clauses.</returns>
|
|
/// <exception cref="InvalidOperationException">Thrown when required clauses are missing.</exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a SQL Server formatted preview of the query being built.
|
|
/// </summary>
|
|
/// <returns>Preview SQL statement.</returns>
|
|
public string PreviewSql()
|
|
{
|
|
try
|
|
{
|
|
return Build().ToSqlServerSql();
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
return "-- Incomplete query (missing required clauses)";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new builder with the default state.
|
|
/// </summary>
|
|
/// <returns>A new LinqQueryBreakdownBuilder instance.</returns>
|
|
public static LinqQueryBreakdownBuilder Create()
|
|
{
|
|
return new LinqQueryBreakdownBuilder();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a builder with a table already specified.
|
|
/// </summary>
|
|
/// <param name="tableName">The table to select from.</param>
|
|
/// <returns>A new builder with the table set.</returns>
|
|
public static LinqQueryBreakdownBuilder CreateForTable(string tableName)
|
|
{
|
|
return new LinqQueryBreakdownBuilder().FromTable(tableName);
|
|
}
|
|
}
|