Files
sql-utilities/src/Strata.SqlTools.SqlBreakdown/Classes/SqlBreakdownBase.cs
T
Thom Lamb 2d9148547f
SonarQube Analysis / sonarqube (pull_request) Successful in 4m42s
fix(serialization): Remove legacy BinaryFormatter support
The `[Serializable]` attribute and corresponding `[OnDeserialized]` methods have been removed from various breakdown classes. This eliminates reliance on `BinaryFormatter`, which is a deprecated and insecure serialization mechanism in modern .NET.

This change also resolves SonarQube rule S5766 warnings by removing the context in which they apply, leading to cleaner and more secure code.
2026-05-20 17:44:21 -05:00

130 lines
4.0 KiB
C#

using System.Collections;
using System.Text;
using Strata.SqlTools.SqlBreakdown.Interfaces;
namespace Strata.SqlTools.SqlBreakdown.Classes;
/// <summary>
/// Base class for SQL query breakdowns that provides common setup/finish clause handling and cloning.
/// </summary>
public abstract class SqlBreakdownBase : ISqlBreakdown
{
/// <summary>
/// Initializes a new instance of the <see cref="SqlBreakdownBase"/> class.
/// </summary>
protected SqlBreakdownBase()
{
SetupClauses = new List<string>();
FinishClauses = new ArrayList();
}
/// <summary>
/// Gets or sets the setup clauses to execute before the main query.
/// </summary>
public List<string> SetupClauses { get; set; }
/// <summary>
/// Gets a value indicating whether setup clauses are being used.
/// </summary>
public bool IsUsingSetupClause => SetupClauses.Count > 0;
/// <summary>
/// Gets or sets the raw/original SQL statement before parsing and breakdown.
/// </summary>
/// <remarks>
/// This property stores the original SQL text that was parsed to create this breakdown.
/// It's useful for auditing, logging, and batch statement retrieval.
/// </remarks>
public string? RawSql { get; set; }
/// <summary>
/// Gets or sets the finish clauses to execute after the main query.
/// </summary>
public ArrayList FinishClauses { get; set; }
/// <summary>
/// Gets a value indicating whether finish clauses are being used.
/// </summary>
public bool IsUsingFinishClause => FinishClauses.Count > 0;
/// <summary>
/// Gets the SQL breakdown as a string. Must be implemented by derived classes.
/// </summary>
/// <returns>The SQL query string.</returns>
protected abstract string GetSqlBreakdown();
/// <summary>
/// Gets a LINQ to SQL query of the specified type based on this breakdown.
/// </summary>
/// <typeparam name="T">The entity type for the query.</typeparam>
/// <returns>An IQueryable of the specified type, or null if the breakdown cannot be converted to a LINQ query.</returns>
/// <remarks>
/// This method allows derived breakdown classes to reconstruct or generate LINQ queries
/// from the analyzed components (SELECT, WHERE, ORDER BY, etc.).
/// The default implementation returns null.
/// </remarks>
public virtual IQueryable<T>? GetQuery<T>() where T : class => null;
/// <summary>
/// Gets the complete SQL query including optional setup and finish clauses.
/// </summary>
/// <param name="includeSetupFinish">Whether to include setup and finish clauses.</param>
/// <returns>The complete SQL query string.</returns>
public string GetSql(bool includeSetupFinish = true)
{
var sb = new StringBuilder();
if (includeSetupFinish)
{
// Write out any setup clauses
sb.AppendLine();
foreach (string setup in SetupClauses)
{
sb.AppendLine(setup);
}
sb.AppendLine();
}
sb.Append(GetSqlBreakdown());
if (includeSetupFinish)
{
// Write out any finish clauses
sb.AppendLine();
sb.AppendLine();
foreach (string finish in FinishClauses)
{
sb.AppendLine(finish);
}
}
return sb.ToString();
}
/// <summary>
/// Returns the SQL query as a string.
/// </summary>
/// <returns>The SQL query string.</returns>
public override string ToString()
=> GetSql();
/// <summary>
/// Creates a deep clone of this object.
/// </summary>
/// <returns>A cloned instance.</returns>
public object Clone()
{
// Create a shallow copy
var clone = (SqlBreakdownBase)MemberwiseClone();
// Deep copy the SetupClauses list
clone.SetupClauses = new List<string>(SetupClauses);
// Deep copy the FinishClauses ArrayList
clone.FinishClauses = new ArrayList(FinishClauses);
return clone;
}
}