From 0b342d8d9dcccaa35028275f3833f8f61f976dae Mon Sep 17 00:00:00 2001 From: Paul Welter Date: Wed, 25 Oct 2023 16:02:07 -0500 Subject: [PATCH] improve documentation --- src/FluentCommand/ConcurrencyToken.cs | 28 +++ .../DataFieldConverterAttribute.cs | 3 + src/FluentCommand/DataParameterHandlers.cs | 24 ++ src/FluentCommand/DataQueryLogger.cs | 8 +- src/FluentCommand/DataReaderExtensions.cs | 3 +- src/FluentCommand/Internal/HashCode.cs | 7 +- src/FluentCommand/Query/AggregateFunctions.cs | 8 + src/FluentCommand/Query/DeleteBuilder.cs | 104 ++++++++- .../Query/DeleteEntityBuilder.cs | 72 ++++++ src/FluentCommand/Query/FilterOperators.cs | 15 ++ src/FluentCommand/Query/IQueryBuilder.cs | 15 ++ src/FluentCommand/Query/IQueryStatement.cs | 16 ++ src/FluentCommand/Query/IStatementBuilder.cs | 7 + .../Query/IWhereEntityBuilder.cs | 94 ++++++++ src/FluentCommand/Query/InsertBuilder.cs | 106 ++++++++- .../Query/InsertEntityBuilder.cs | 59 +++++ src/FluentCommand/Query/JoinBuilder.cs | 55 +++++ src/FluentCommand/Query/JoinEntityBuilder.cs | 39 ++++ src/FluentCommand/Query/JoinTypes.cs | 6 + src/FluentCommand/Query/LogicalBuilder.cs | 19 ++ .../Query/LogicalEntityBuilder.cs | 19 ++ src/FluentCommand/Query/LogicalOperators.cs | 5 + src/FluentCommand/Query/OrderBuilder.cs | 73 ++++++ src/FluentCommand/Query/OrderEntityBuilder.cs | 39 ++++ src/FluentCommand/Query/QueryBuilder.cs | 65 +++++- .../Query/QueryBuilderExtensions.cs | 11 + src/FluentCommand/Query/QueryParameter.cs | 27 +++ src/FluentCommand/Query/QueryStatement.cs | 15 +- src/FluentCommand/Query/SelectBuilder.cs | 215 ++++++++++++++++++ .../Query/SelectEntityBuilder.cs | 170 ++++++++++++++ src/FluentCommand/Query/SortDirections.cs | 5 + src/FluentCommand/Query/StatementBuilder.cs | 82 +++++++ src/FluentCommand/Query/UpdateBuilder.cs | 137 ++++++++++- .../Query/UpdateEntityBuilder.cs | 107 +++++++++ src/FluentCommand/Query/WhereBuilder.cs | 134 +++++++++++ src/FluentCommand/Query/WhereEntityBuilder.cs | 21 ++ .../Reflection/MethodAccessor.cs | 11 +- 37 files changed, 1801 insertions(+), 23 deletions(-) diff --git a/src/FluentCommand/ConcurrencyToken.cs b/src/FluentCommand/ConcurrencyToken.cs index ec3ee998..b9c1b4f0 100644 --- a/src/FluentCommand/ConcurrencyToken.cs +++ b/src/FluentCommand/ConcurrencyToken.cs @@ -70,12 +70,40 @@ public override int GetHashCode() return Value.GetHashCode(); } + /// + /// Performs an implicit conversion from to byte array. + /// + /// The concurrency token. + /// + /// The result of the conversion. + /// public static implicit operator byte[](ConcurrencyToken token) => token.Value; + /// + /// Performs an implicit conversion from to . + /// + /// The concurrency token. + /// + /// The result of the conversion. + /// public static implicit operator string(ConcurrencyToken token) => token.ToString(); + /// + /// Performs an implicit conversion from byte array to . + /// + /// The concurrency token. + /// + /// The result of the conversion. + /// public static implicit operator ConcurrencyToken(byte[] token) => new(token); + /// + /// Performs an implicit conversion from to . + /// + /// The concurrency token. + /// + /// The result of the conversion. + /// public static implicit operator ConcurrencyToken(string token) => new(token); diff --git a/src/FluentCommand/DataFieldConverterAttribute.cs b/src/FluentCommand/DataFieldConverterAttribute.cs index be5d32f0..1017e952 100644 --- a/src/FluentCommand/DataFieldConverterAttribute.cs +++ b/src/FluentCommand/DataFieldConverterAttribute.cs @@ -35,6 +35,9 @@ public DataFieldConverterAttribute(Type converterType) [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)] public class DataFieldConverterAttribute : DataFieldConverterAttribute { + /// + /// Initializes a new instance of the class. + /// public DataFieldConverterAttribute() : base(typeof(TConverter)) { } diff --git a/src/FluentCommand/DataParameterHandlers.cs b/src/FluentCommand/DataParameterHandlers.cs index fa997627..0e0ac67d 100644 --- a/src/FluentCommand/DataParameterHandlers.cs +++ b/src/FluentCommand/DataParameterHandlers.cs @@ -6,6 +6,9 @@ namespace FluentCommand; +/// +/// +/// public static class DataParameterHandlers { private static readonly ConcurrentDictionary _dataTypeHandlers; @@ -22,6 +25,10 @@ static DataParameterHandlers() #endif } + /// + /// Adds the data type handler. + /// + /// The type of the handler. public static void AddTypeHandler() where THandler : IDataParameterHandler, new() { @@ -29,18 +36,35 @@ public static void AddTypeHandler() AddTypeHandler(handler); } + /// + /// Adds the data type handler. + /// + /// The type of the handler. + /// The handler. public static void AddTypeHandler(THandler handler) where THandler : IDataParameterHandler { _dataTypeHandlers.TryAdd(handler.ValueType, handler); } + /// + /// Gets the type handler for the specified . + /// + /// The type to get a handler for. + /// The for the specified type; otherwise null if not found public static IDataParameterHandler GetTypeHandler(Type type) { var underlyingType = type.GetUnderlyingType(); return _dataTypeHandlers.TryGetValue(underlyingType, out var handler) ? handler : null; } + + /// + /// Sets the Value and DbType on the specified using the registered type handlers. + /// + /// The parameter to set the value on. + /// The value to set. + /// The data type to use. public static void SetValue(DbParameter parameter, object value, Type type) { var valueType = type.GetUnderlyingType(); diff --git a/src/FluentCommand/DataQueryLogger.cs b/src/FluentCommand/DataQueryLogger.cs index f54eea6e..1195ba81 100644 --- a/src/FluentCommand/DataQueryLogger.cs +++ b/src/FluentCommand/DataQueryLogger.cs @@ -1,13 +1,11 @@ using System.Data; -using FluentCommand.Internal; - using Microsoft.Extensions.Logging; namespace FluentCommand; /// -/// A class to log queries to string delegate +/// A class for logging queries /// /// public partial class DataQueryLogger : IDataQueryLogger @@ -51,8 +49,8 @@ public virtual void LogCommand(IDbCommand command, TimeSpan duration, Exception } [LoggerMessage(0, LogLevel.Debug, "{output}")] - public partial void LogCommand(string output); + private partial void LogCommand(string output); [LoggerMessage(1, LogLevel.Error, "{output}")] - public partial void LogError(string output, Exception exception); + private partial void LogError(string output, Exception exception); } diff --git a/src/FluentCommand/DataReaderExtensions.cs b/src/FluentCommand/DataReaderExtensions.cs index 8057f7ce..666a1f93 100644 --- a/src/FluentCommand/DataReaderExtensions.cs +++ b/src/FluentCommand/DataReaderExtensions.cs @@ -1,4 +1,4 @@ -using System.Data; +using System.Data; using System.Dynamic; using FluentCommand.Reflection; @@ -16,6 +16,7 @@ public static class DataReaderExtensions /// The type of the entity. /// The open to get the object from. /// A TEntity object having property names set that match the field names in the . + [Obsolete("Use generated data reader factory")] public static TEntity EntityFactory(this IDataReader reader) where TEntity : class, new() { diff --git a/src/FluentCommand/Internal/HashCode.cs b/src/FluentCommand/Internal/HashCode.cs index e8f33fc2..19955742 100644 --- a/src/FluentCommand/Internal/HashCode.cs +++ b/src/FluentCommand/Internal/HashCode.cs @@ -225,8 +225,11 @@ public static int HashString(string text) unchecked { - foreach (char c in text) - hash = (hash * Multiplier) + c; + // ReSharper disable once LoopCanBeConvertedToQuery + // ReSharper disable once ForCanBeConvertedToForeach + for (var index = 0; index < text.Length; index++) + hash = (hash * Multiplier) + text[index]; + } return hash; diff --git a/src/FluentCommand/Query/AggregateFunctions.cs b/src/FluentCommand/Query/AggregateFunctions.cs index 938eff55..7d32c5b4 100644 --- a/src/FluentCommand/Query/AggregateFunctions.cs +++ b/src/FluentCommand/Query/AggregateFunctions.cs @@ -1,10 +1,18 @@ namespace FluentCommand.Query; +/// +/// Query aggregate functions +/// public enum AggregateFunctions { + /// Average aggregate function Average, + /// Count aggregate function Count, + /// Max aggregate function Max, + /// Min aggregate function Min, + /// Sum aggregate function Sum, } diff --git a/src/FluentCommand/Query/DeleteBuilder.cs b/src/FluentCommand/Query/DeleteBuilder.cs index 4af5a198..49acde91 100644 --- a/src/FluentCommand/Query/DeleteBuilder.cs +++ b/src/FluentCommand/Query/DeleteBuilder.cs @@ -3,8 +3,17 @@ namespace FluentCommand.Query; +/// +/// Delete query statement builder +/// public class DeleteBuilder : DeleteBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// The logical operator. public DeleteBuilder( IQueryGenerator queryGenerator, List parameters, @@ -14,9 +23,19 @@ public DeleteBuilder( } } +/// +/// Delete query statement builder +/// +/// The type of the builder. public abstract class DeleteBuilder : WhereBuilder where TBuilder : DeleteBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// The logical operator. protected DeleteBuilder( IQueryGenerator queryGenerator, List parameters, @@ -26,15 +45,48 @@ protected DeleteBuilder( } + /// + /// Gets the output expressions. + /// + /// + /// The output expressions. + /// protected HashSet OutputExpressions { get; } = new(); + /// + /// Gets from expressions. + /// + /// + /// From expressions. + /// protected HashSet FromExpressions { get; } = new(); + /// + /// Gets the join expressions. + /// + /// + /// The join expressions. + /// protected HashSet JoinExpressions { get; } = new(); + /// + /// Gets the table expression. + /// + /// + /// The table expression. + /// protected TableExpression TableExpression { get; private set; } + /// + /// Set the target table to delete from. + /// + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Table( string tableName, string tableSchema = null, @@ -46,6 +98,14 @@ public TBuilder Table( } + /// + /// Add an output clause for the specified column names. + /// + /// The column names. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Output( IEnumerable columnNames, string tableAlias = "DELETED") @@ -59,6 +119,15 @@ public TBuilder Output( return (TBuilder)this; } + /// + /// Add an output clause for the specified column name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Output( string columnName, string tableAlias = "DELETED", @@ -71,6 +140,16 @@ public TBuilder Output( return (TBuilder)this; } + /// + /// Conditionally add an output clause for the specified column name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OutputIf( string columnName, string tableAlias = "DELETED", @@ -84,6 +163,15 @@ public TBuilder OutputIf( } + /// + /// Add a from clause to the query. + /// + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public virtual TBuilder From( string tableName, string tableSchema = null, @@ -96,6 +184,13 @@ public virtual TBuilder From( return (TBuilder)this; } + /// + /// Add a raw from clause to the query. + /// + /// From clause. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder FromRaw(string fromClause) { if (fromClause.HasValue()) @@ -104,6 +199,13 @@ public TBuilder FromRaw(string fromClause) return (TBuilder)this; } + /// + /// Add a join clause using the specified builder action + /// + /// The builder. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Join(Action builder) { var innerBuilder = new JoinBuilder(QueryGenerator, Parameters); @@ -114,7 +216,7 @@ public TBuilder Join(Action builder) return (TBuilder)this; } - + /// public override QueryStatement BuildStatement() { var deleteStatement = new DeleteStatement( diff --git a/src/FluentCommand/Query/DeleteEntityBuilder.cs b/src/FluentCommand/Query/DeleteEntityBuilder.cs index 52063c14..722d13d7 100644 --- a/src/FluentCommand/Query/DeleteEntityBuilder.cs +++ b/src/FluentCommand/Query/DeleteEntityBuilder.cs @@ -6,12 +6,23 @@ namespace FluentCommand.Query; + +/// +/// Delete query statement builder +/// +/// The type of the entity. public class DeleteEntityBuilder : DeleteBuilder>, IWhereEntityBuilder> where TEntity : class { private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// The logical operator. public DeleteEntityBuilder( IQueryGenerator queryGenerator, List parameters, @@ -21,6 +32,16 @@ public DeleteEntityBuilder( } + /// + /// Add an output clause for the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public DeleteEntityBuilder Output( Expression> property, string tableAlias = "DELETED", @@ -30,6 +51,17 @@ public DeleteEntityBuilder Output( return Output(propertyAccessor.Column, tableAlias, columnAlias); } + /// + /// Conditionally add an output clause for the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public DeleteEntityBuilder OutputIf( Expression> property, string tableAlias = "DELETED", @@ -40,6 +72,7 @@ public DeleteEntityBuilder OutputIf( return OutputIf(propertyAccessor.Column, tableAlias, columnAlias, condition); } + /// public override DeleteEntityBuilder From( string tableName = null, string tableSchema = null, @@ -51,6 +84,14 @@ public override DeleteEntityBuilder From( tableAlias); } + /// + /// Add a join clause using the specified builder action + /// + /// The right join entity + /// The join builder. + /// + /// The same builder so that multiple calls can be chained. + /// public DeleteEntityBuilder Join(Action> builder) where TRight : class { @@ -62,6 +103,15 @@ public DeleteEntityBuilder Join(Action + /// Add a join clause using the specified builder action + /// + /// The left join entity + /// The right join entity + /// The join builder. + /// + /// The same builder so that multiple calls can be chained. + /// public DeleteEntityBuilder Join(Action> builder) where TLeft : class where TRight : class @@ -75,6 +125,7 @@ public DeleteEntityBuilder Join(Action public DeleteEntityBuilder Where( Expression> property, TValue parameterValue, @@ -83,6 +134,7 @@ public DeleteEntityBuilder Where( return Where(property, parameterValue, null, filterOperator); } + /// public DeleteEntityBuilder Where( Expression> property, TValue parameterValue, @@ -94,6 +146,18 @@ public DeleteEntityBuilder Where( return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator); } + /// + /// Create a where clause with the specified property, value, operator and table alias + /// + /// The type of the model + /// The type of the value. + /// The property. + /// The parameter value. + /// The table alias. + /// The filter operator. + /// + /// The same builder so that multiple calls can be chained. + /// public DeleteEntityBuilder Where( Expression> property, TValue parameterValue, @@ -106,6 +170,7 @@ public DeleteEntityBuilder Where( return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator); } + /// public DeleteEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -115,6 +180,7 @@ public DeleteEntityBuilder WhereIf( return WhereIf(property, parameterValue, null, filterOperator, condition); } + /// public DeleteEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -127,6 +193,7 @@ public DeleteEntityBuilder WhereIf( return WhereIf(propertyAccessor.Column, parameterValue, tableAlias, filterOperator, condition); } + /// public DeleteEntityBuilder WhereIn( Expression> property, IEnumerable parameterValues, @@ -137,6 +204,7 @@ public DeleteEntityBuilder WhereIn( return WhereIn(propertyAccessor?.Column, parameterValues, tableAlias); } + /// public DeleteEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -147,6 +215,7 @@ public DeleteEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, condition); } + /// public DeleteEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -158,6 +227,7 @@ public DeleteEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, tableAlias, condition); } + /// public DeleteEntityBuilder WhereOr(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.Or); @@ -172,6 +242,7 @@ public DeleteEntityBuilder WhereOr(Action return this; } + /// public DeleteEntityBuilder WhereAnd(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.And); @@ -187,6 +258,7 @@ public DeleteEntityBuilder WhereAnd(Action public override QueryStatement BuildStatement() { // add table and schema from attribute if not set diff --git a/src/FluentCommand/Query/FilterOperators.cs b/src/FluentCommand/Query/FilterOperators.cs index 75fb1160..53f81cce 100644 --- a/src/FluentCommand/Query/FilterOperators.cs +++ b/src/FluentCommand/Query/FilterOperators.cs @@ -1,17 +1,32 @@ namespace FluentCommand.Query; +/// +/// Query filter operators +/// public enum FilterOperators { + /// Starts with query operator StartsWith, + /// Ends with query operator EndsWith, + /// Contains query operator Contains, + /// Equal query operator Equal, + /// Not equal query operator NotEqual, + /// Less than query operator LessThan, + /// Less than or equal query operator LessThanOrEqual, + /// Greater than query operator GreaterThan, + /// Greater than or equal query operator GreaterThanOrEqual, + /// Is null query operator IsNull, + /// Is not null query operator IsNotNull, + /// In query operator In } diff --git a/src/FluentCommand/Query/IQueryBuilder.cs b/src/FluentCommand/Query/IQueryBuilder.cs index f3266af7..b77ba21b 100644 --- a/src/FluentCommand/Query/IQueryBuilder.cs +++ b/src/FluentCommand/Query/IQueryBuilder.cs @@ -2,9 +2,24 @@ namespace FluentCommand.Query; +/// +/// Interface for query building +/// public interface IQueryBuilder { + /// + /// Gets the query generator. + /// + /// + /// The query generator. + /// IQueryGenerator QueryGenerator { get; } + /// + /// Gets the query parameters. + /// + /// + /// The query parameters. + /// List Parameters { get; } } diff --git a/src/FluentCommand/Query/IQueryStatement.cs b/src/FluentCommand/Query/IQueryStatement.cs index 52e5b476..f418e5ac 100644 --- a/src/FluentCommand/Query/IQueryStatement.cs +++ b/src/FluentCommand/Query/IQueryStatement.cs @@ -1,7 +1,23 @@ namespace FluentCommand.Query; +/// +/// interface for defining a sql query +/// public interface IQueryStatement { + /// + /// Gets the parameters for the query. + /// + /// + /// The parameters for the query. + /// IReadOnlyCollection Parameters { get; } + + /// + /// Gets the sql statement. + /// + /// + /// The sql statement. + /// string Statement { get; } } diff --git a/src/FluentCommand/Query/IStatementBuilder.cs b/src/FluentCommand/Query/IStatementBuilder.cs index a29bea39..c0dee88f 100644 --- a/src/FluentCommand/Query/IStatementBuilder.cs +++ b/src/FluentCommand/Query/IStatementBuilder.cs @@ -1,6 +1,13 @@ namespace FluentCommand.Query; +/// +/// interface defining sql statement builder +/// public interface IStatementBuilder { + /// + /// Builds the sql statement from this builder. + /// + /// The sql query statement QueryStatement BuildStatement(); } diff --git a/src/FluentCommand/Query/IWhereEntityBuilder.cs b/src/FluentCommand/Query/IWhereEntityBuilder.cs index fc9f0edb..0545429d 100644 --- a/src/FluentCommand/Query/IWhereEntityBuilder.cs +++ b/src/FluentCommand/Query/IWhereEntityBuilder.cs @@ -2,42 +2,122 @@ namespace FluentCommand.Query; +/// +/// interface for where clause builder +/// +/// The type of the entity. +/// The type of the builder. public interface IWhereEntityBuilder where TEntity : class { + /// + /// Create a where clause with the specified property, value and operator + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// The filter operator. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder Where( Expression> property, TValue parameterValue, FilterOperators filterOperator = FilterOperators.Equal); + /// + /// Create a where clause with the specified property, value, operator and table alias + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// The table alias. + /// The filter operator. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder Where( Expression> property, TValue parameterValue, string tableAlias, FilterOperators filterOperator = FilterOperators.Equal); + /// + /// Create a where in clause with the specified property, values and table alias + /// + /// The type of the value. + /// The property. + /// The parameter values. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder WhereIn( Expression> property, IEnumerable parameterValues, string tableAlias); + /// + /// Conditionally create a where in clause with the specified property and values + /// + /// The type of the value. + /// The property. + /// The parameter values. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder WhereInIf( Expression> property, IEnumerable parameterValues, Func, bool> condition = null); + /// + /// Conditionally create a where in clause with the specified property, values and table alias + /// + /// The type of the value. + /// The property. + /// The parameter values. + /// The table alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder WhereInIf( Expression> property, IEnumerable parameterValues, string tableAlias, Func, bool> condition = null); + /// + /// Conditionally create a where clause with the specified property, value and operator + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// The filter operator. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder WhereIf( Expression> property, TValue parameterValue, FilterOperators filterOperator = FilterOperators.Equal, Func condition = null); + /// + /// Conditionally create a where clause with the specified property, value, operator and table alias + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// The table alias. + /// The filter operator. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder WhereIf( Expression> property, TValue parameterValue, @@ -45,7 +125,21 @@ TBuilder WhereIf( FilterOperators filterOperator = FilterOperators.Equal, Func condition = null); + /// + /// Create a logical AND where clause group + /// + /// The logical AND where clause builder. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder WhereAnd(Action> builder); + /// + /// Create a logical OR where clause group + /// + /// The logical OR where clause builder. + /// + /// The same builder so that multiple calls can be chained. + /// TBuilder WhereOr(Action> builder); } diff --git a/src/FluentCommand/Query/InsertBuilder.cs b/src/FluentCommand/Query/InsertBuilder.cs index 68afed5f..418c2247 100644 --- a/src/FluentCommand/Query/InsertBuilder.cs +++ b/src/FluentCommand/Query/InsertBuilder.cs @@ -2,8 +2,16 @@ namespace FluentCommand.Query; +/// +/// Insert query statement builder +/// public class InsertBuilder : InsertBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. public InsertBuilder( IQueryGenerator queryGenerator, List parameters) @@ -11,9 +19,18 @@ public InsertBuilder( { } } +/// +/// Insert query statement builder +/// +/// The type of the builder. public abstract class InsertBuilder : StatementBuilder where TBuilder : InsertBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. protected InsertBuilder( IQueryGenerator queryGenerator, List parameters) @@ -21,15 +38,48 @@ protected InsertBuilder( { } + /// + /// Gets the column expressions. + /// + /// + /// The column expressions. + /// protected HashSet ColumnExpressions { get; } = new(); + /// + /// Gets the output expressions. + /// + /// + /// The output expressions. + /// protected HashSet OutputExpressions { get; } = new(); + /// + /// Gets the value expressions. + /// + /// + /// The value expressions. + /// protected HashSet ValueExpressions { get; } = new(); + /// + /// Gets the table expression. + /// + /// + /// The table expression. + /// protected TableExpression TableExpression { get; private set; } + /// + /// Set the target table to insert into. + /// + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Into( string tableName, string tableSchema = null, @@ -40,13 +90,28 @@ public TBuilder Into( return (TBuilder)this; } - public TBuilder Value( + /// + /// Adds a value with specified column name and value. + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. +c public TBuilder Value( string columnName, TValue parameterValue) { return Value(columnName, parameterValue, typeof(TValue)); } + /// + /// Adds a value with specified column name and value. + /// + /// Name of the column. + /// The parameter value. + /// Type of the parameter. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Value( string columnName, object parameterValue, @@ -70,6 +135,16 @@ public TBuilder Value( return (TBuilder)this; } + /// + /// Conditionally adds a value with specified column name and value. + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder ValueIf( string columnName, TValue parameterValue, @@ -82,6 +157,14 @@ public TBuilder ValueIf( } + /// + /// Add an output clause for the specified column names. + /// + /// The column names. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Output( IEnumerable columnNames, string tableAlias = "INSERTED") @@ -95,6 +178,15 @@ public TBuilder Output( return (TBuilder)this; } + /// + /// Add an output clause for the specified column name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Output( string columnName, string tableAlias = "INSERTED", @@ -107,6 +199,16 @@ public TBuilder Output( return (TBuilder)this; } + /// + /// Conditionally add an output clause for the specified column name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OutputIf( string columnName, string tableAlias = "INSERTED", @@ -120,6 +222,7 @@ public TBuilder OutputIf( } + /// public override QueryStatement BuildStatement() { var insertStatement = new InsertStatement( @@ -133,5 +236,4 @@ public override QueryStatement BuildStatement() return new QueryStatement(statement, Parameters); } - } diff --git a/src/FluentCommand/Query/InsertEntityBuilder.cs b/src/FluentCommand/Query/InsertEntityBuilder.cs index f1857161..d72d8c3b 100644 --- a/src/FluentCommand/Query/InsertEntityBuilder.cs +++ b/src/FluentCommand/Query/InsertEntityBuilder.cs @@ -5,11 +5,20 @@ namespace FluentCommand.Query; +/// +/// Insert query statement builder +/// +/// The type of the entity. public class InsertEntityBuilder : InsertBuilder> where TEntity : class { private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. public InsertEntityBuilder( IQueryGenerator queryGenerator, List parameters) @@ -17,6 +26,15 @@ public InsertEntityBuilder( { } + /// + /// Adds a value with specified property and value. + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// + /// The same builder so that multiple calls can be chained. + /// public InsertEntityBuilder Value( Expression> property, TValue parameterValue) @@ -25,6 +43,16 @@ public InsertEntityBuilder Value( return Value(propertyAccessor.Column, parameterValue); } + /// + /// Conditionally adds a value with specified property and value. + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public InsertEntityBuilder ValueIf( Expression> property, TValue parameterValue, @@ -34,6 +62,15 @@ public InsertEntityBuilder ValueIf( return ValueIf(propertyAccessor.Column, parameterValue, condition); } + /// + /// Adds a values from the specified entity. If column names are passed in, + /// only those that match an entity property name will be included. + /// + /// The entity to insert. + /// The column names to include. + /// + /// The same builder so that multiple calls can be chained. + /// public InsertEntityBuilder Values( TEntity entity, IEnumerable columnNames = null) @@ -59,6 +96,16 @@ public InsertEntityBuilder Values( return this; } + /// + /// Add an output clause for the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public InsertEntityBuilder Output( Expression> property, string tableAlias = "INSERTED", @@ -68,6 +115,17 @@ public InsertEntityBuilder Output( return Output(propertyAccessor.Column, tableAlias, columnAlias); } + /// + /// Conditionally add an output clause for the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public InsertEntityBuilder OutputIf( Expression> property, string tableAlias = "INSERTED", @@ -78,6 +136,7 @@ public InsertEntityBuilder OutputIf( return OutputIf(propertyAccessor.Column, tableAlias, columnAlias, condition); } + /// public override QueryStatement BuildStatement() { // add table and schema from attribute if not set diff --git a/src/FluentCommand/Query/JoinBuilder.cs b/src/FluentCommand/Query/JoinBuilder.cs index 199919a4..cebc5caa 100644 --- a/src/FluentCommand/Query/JoinBuilder.cs +++ b/src/FluentCommand/Query/JoinBuilder.cs @@ -2,24 +2,55 @@ namespace FluentCommand.Query; +/// +/// Join clause builder +/// public class JoinBuilder : JoinBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. public JoinBuilder(IQueryGenerator queryGenerator, List parameters) : base(queryGenerator, parameters) { } } +/// +/// +/// +/// The type of the builder. public class JoinBuilder : StatementBuilder where TBuilder : JoinBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. public JoinBuilder(IQueryGenerator queryGenerator, List parameters) : base(queryGenerator, parameters) { } + /// + /// Gets or sets the join expression. + /// + /// + /// The join expression. + /// protected JoinExpression JoinExpression { get; set; } = new(); + /// + /// The left column to join on. + /// + /// Name of the column. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Left( string columnName, string tableAlias) @@ -33,6 +64,16 @@ public TBuilder Left( return (TBuilder)this; } + /// + /// The right column to join on. + /// + /// Name of the column. + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Right( string columnName, string tableName, @@ -50,6 +91,13 @@ public TBuilder Right( return (TBuilder)this; } + /// + /// Specify the join type. + /// + /// Type of the join. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Type(JoinTypes joinType) { JoinExpression = JoinExpression with @@ -60,11 +108,18 @@ public TBuilder Type(JoinTypes joinType) return (TBuilder)this; } + /// + /// Builds the join expression. + /// + /// + /// The same builder so that multiple calls can be chained. + /// public virtual JoinExpression BuildExpression() { return JoinExpression; } + /// public override QueryStatement BuildStatement() { var joinClause = QueryGenerator.JoinExpression(JoinExpression); diff --git a/src/FluentCommand/Query/JoinEntityBuilder.cs b/src/FluentCommand/Query/JoinEntityBuilder.cs index 640b6ec6..cb4d2d4b 100644 --- a/src/FluentCommand/Query/JoinEntityBuilder.cs +++ b/src/FluentCommand/Query/JoinEntityBuilder.cs @@ -5,6 +5,11 @@ namespace FluentCommand.Query; +/// +/// Join clause builder +/// +/// The entity type of the left join. +/// The entity type of the right join. public class JoinEntityBuilder : JoinBuilder> where TLeft : class where TRight : class @@ -12,11 +17,25 @@ public class JoinEntityBuilder : JoinBuilder(); private static readonly TypeAccessor _rightAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. public JoinEntityBuilder(IQueryGenerator queryGenerator, List parameters) : base(queryGenerator, parameters) { } + /// + /// The left property to join on. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public JoinEntityBuilder Left( Expression> property, string tableAlias) @@ -27,6 +46,15 @@ public JoinEntityBuilder Left( return Left(propertyAccessor.Column, tableAlias); } + /// + /// The right property to join on. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public JoinEntityBuilder Right( Expression> property, string tableAlias) @@ -38,6 +66,17 @@ public JoinEntityBuilder Right( tableAlias); } + /// + /// The right property to join on. + /// + /// The type of the value. + /// The property. + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public JoinEntityBuilder Right( Expression> property, string tableName, diff --git a/src/FluentCommand/Query/JoinTypes.cs b/src/FluentCommand/Query/JoinTypes.cs index 6d6d65aa..4e25e8b7 100644 --- a/src/FluentCommand/Query/JoinTypes.cs +++ b/src/FluentCommand/Query/JoinTypes.cs @@ -1,8 +1,14 @@ namespace FluentCommand.Query; +/// +/// Query join types +/// public enum JoinTypes { + /// The inner join tables Inner, + /// The left outer join tables Left, + /// The right outer join tables Right } diff --git a/src/FluentCommand/Query/LogicalBuilder.cs b/src/FluentCommand/Query/LogicalBuilder.cs index 63ccc26f..3d6d2c7f 100644 --- a/src/FluentCommand/Query/LogicalBuilder.cs +++ b/src/FluentCommand/Query/LogicalBuilder.cs @@ -2,8 +2,17 @@ namespace FluentCommand.Query; +/// +/// A logical query expression builder +/// public class LogicalBuilder : LogicalBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The query logical operator. public LogicalBuilder( IQueryGenerator queryGenerator, List parameters, @@ -13,9 +22,18 @@ public LogicalBuilder( } } +/// +/// A logical query expression builder +/// public abstract class LogicalBuilder : WhereBuilder where TBuilder : LogicalBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The query logical operator. protected LogicalBuilder( IQueryGenerator queryGenerator, List parameters, @@ -24,6 +42,7 @@ protected LogicalBuilder( { } + /// public override QueryStatement BuildStatement() { if (WhereExpressions.Count == 0) diff --git a/src/FluentCommand/Query/LogicalEntityBuilder.cs b/src/FluentCommand/Query/LogicalEntityBuilder.cs index 929c9b8d..60e713cb 100644 --- a/src/FluentCommand/Query/LogicalEntityBuilder.cs +++ b/src/FluentCommand/Query/LogicalEntityBuilder.cs @@ -6,12 +6,22 @@ namespace FluentCommand.Query; +/// +/// A logical query expression builder +/// +/// The type of the entity. public class LogicalEntityBuilder : LogicalBuilder>, IWhereEntityBuilder> where TEntity : class { private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The query logical operator. public LogicalEntityBuilder( IQueryGenerator queryGenerator, List parameters, @@ -20,6 +30,7 @@ public LogicalEntityBuilder( { } + /// public LogicalEntityBuilder Where( Expression> property, TValue parameterValue, @@ -28,6 +39,7 @@ public LogicalEntityBuilder Where( return Where(property, parameterValue, null, filterOperator); } + /// public LogicalEntityBuilder Where( Expression> property, TValue parameterValue, @@ -39,6 +51,7 @@ public LogicalEntityBuilder Where( return Where(propertyAccessor.Column, parameterValue, tableAlias, whereOperator); } + /// public LogicalEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -48,6 +61,7 @@ public LogicalEntityBuilder WhereIf( return WhereIf(property, parameterValue, null, filterOperator, condition); } + /// public LogicalEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -60,6 +74,7 @@ public LogicalEntityBuilder WhereIf( return WhereIf(propertyAccessor.Column, parameterValue, tableAlias, filterOperator, condition); } + /// public LogicalEntityBuilder WhereIn( Expression> property, IEnumerable parameterValues, @@ -70,6 +85,7 @@ public LogicalEntityBuilder WhereIn( return WhereIn(propertyAccessor?.Column, parameterValues, tableAlias); } + /// public LogicalEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -80,6 +96,7 @@ public LogicalEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, condition); } + /// public LogicalEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -91,6 +108,7 @@ public LogicalEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, tableAlias, condition); } + /// public LogicalEntityBuilder WhereOr(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.Or); @@ -105,6 +123,7 @@ public LogicalEntityBuilder WhereOr(Action public LogicalEntityBuilder WhereAnd(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.And); diff --git a/src/FluentCommand/Query/LogicalOperators.cs b/src/FluentCommand/Query/LogicalOperators.cs index 5e897740..f3d16376 100644 --- a/src/FluentCommand/Query/LogicalOperators.cs +++ b/src/FluentCommand/Query/LogicalOperators.cs @@ -1,7 +1,12 @@ namespace FluentCommand.Query; +/// +/// Query logical operators +/// public enum LogicalOperators { + /// true if all Boolean expressions are true And, + /// true if any Boolean expressions are true Or } diff --git a/src/FluentCommand/Query/OrderBuilder.cs b/src/FluentCommand/Query/OrderBuilder.cs index 2cc3f545..ddb3f606 100644 --- a/src/FluentCommand/Query/OrderBuilder.cs +++ b/src/FluentCommand/Query/OrderBuilder.cs @@ -3,25 +3,56 @@ namespace FluentCommand.Query; +/// +/// Query order by builder +/// public class OrderBuilder : OrderBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. public OrderBuilder(IQueryGenerator queryGenerator, List parameters) : base(queryGenerator, parameters) { } } +/// +/// Query order by builder +/// +/// The type of the builder. public abstract class OrderBuilder : StatementBuilder where TBuilder : OrderBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. protected OrderBuilder(IQueryGenerator queryGenerator, List parameters) : base(queryGenerator, parameters) { } + /// + /// Gets the sort expressions. + /// + /// + /// The sort expressions. + /// protected HashSet SortExpressions { get; } = new(); + /// + /// Add an order by clause with the specified column name and sort direction. + /// + /// Name of the column. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderBy( string columnName, SortDirections sortDirection = SortDirections.Ascending) @@ -29,6 +60,15 @@ public TBuilder OrderBy( return OrderBy(columnName, null, sortDirection); } + /// + /// Add an order by clause with the specified column name, sort direction and table alias. + /// + /// Name of the column. + /// The table alias. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderBy( string columnName, string tableAlias, @@ -41,6 +81,16 @@ public TBuilder OrderBy( return (TBuilder)this; } + /// + /// Conditionally add an order by clause with the specified column name, sort direction and table alias. + /// + /// Name of the column. + /// The table alias. + /// The sort direction. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByIf( string columnName, string tableAlias = null, @@ -53,6 +103,13 @@ public TBuilder OrderByIf( return OrderBy(columnName, tableAlias, sortDirection); } + /// + /// Add a raw order by clause to the query. + /// + /// The order by clause. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByRaw(string sortExpression) { if (sortExpression.HasValue()) @@ -61,6 +118,14 @@ public TBuilder OrderByRaw(string sortExpression) return (TBuilder)this; } + /// + /// Conditionally add a raw order by clause to the query. + /// + /// The order by clause. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByRawIf(string sortExpression, Func condition = null) { if (condition != null && !condition(sortExpression)) @@ -69,6 +134,13 @@ public TBuilder OrderByRawIf(string sortExpression, Func condition return OrderByRaw(sortExpression); } + /// + /// Add multiple raw order by clauses to the query. + /// + /// The order by clauses. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByRaw(IEnumerable sortExpressions) { if (sortExpressions is null) @@ -80,6 +152,7 @@ public TBuilder OrderByRaw(IEnumerable sortExpressions) return (TBuilder)this; } + /// public override QueryStatement BuildStatement() { if (SortExpressions == null || SortExpressions.Count == 0) diff --git a/src/FluentCommand/Query/OrderEntityBuilder.cs b/src/FluentCommand/Query/OrderEntityBuilder.cs index 3b17331b..cbbecdc9 100644 --- a/src/FluentCommand/Query/OrderEntityBuilder.cs +++ b/src/FluentCommand/Query/OrderEntityBuilder.cs @@ -5,16 +5,34 @@ namespace FluentCommand.Query; +/// +/// Query order by builder +/// +/// The type of the entity. public class OrderEntityBuilder : OrderBuilder> where TEntity : class { private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. public OrderEntityBuilder(IQueryGenerator queryGenerator, List parameters) : base(queryGenerator, parameters) { } + /// + /// Add an order by clause with the specified property and sort direction. + /// + /// The type of the value. + /// The property. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public OrderEntityBuilder OrderBy( Expression> property, SortDirections sortDirection = SortDirections.Ascending) @@ -24,6 +42,16 @@ public OrderEntityBuilder OrderBy( return OrderBy(propertyAccessor.Column, null, sortDirection); } + /// + /// Add an order by clause with the specified property, sort direction and table alias. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public OrderEntityBuilder OrderBy( Expression> property, string tableAlias, @@ -34,6 +62,17 @@ public OrderEntityBuilder OrderBy( return OrderBy(propertyAccessor.Column, tableAlias, sortDirection); } + /// + /// Conditionally add an order by clause with the specified property, sort direction and table alias. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The sort direction. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public OrderEntityBuilder OrderByIf( Expression> property, string tableAlias = null, diff --git a/src/FluentCommand/Query/QueryBuilder.cs b/src/FluentCommand/Query/QueryBuilder.cs index d5edc1d9..f8b20049 100644 --- a/src/FluentCommand/Query/QueryBuilder.cs +++ b/src/FluentCommand/Query/QueryBuilder.cs @@ -4,22 +4,47 @@ namespace FluentCommand.Query; - +/// +/// High level query builder +/// +/// public class QueryBuilder : IStatementBuilder { private readonly Queue _builderQueue = new(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// queryGenerator or parameters public QueryBuilder(IQueryGenerator queryGenerator, List parameters) { QueryGenerator = queryGenerator ?? throw new ArgumentNullException(nameof(queryGenerator)); Parameters = parameters ?? throw new ArgumentNullException(nameof(parameters)); } + /// + /// Gets the query generator. + /// + /// + /// The query generator. + /// protected IQueryGenerator QueryGenerator { get; } + /// + /// Gets the query parameters. + /// + /// + /// The query parameters. + /// protected List Parameters { get; } + /// + /// Starts a statement builder + /// + /// A new statement builder public StatementBuilder Statement() { var builder = new StatementBuilder(QueryGenerator, Parameters); @@ -29,6 +54,11 @@ public StatementBuilder Statement() return builder; } + /// + /// Starts a select statement builder + /// + /// The type of the entity. + /// A new select statement builder public SelectEntityBuilder Select() where TEntity : class { @@ -39,6 +69,10 @@ public SelectEntityBuilder Select() return builder; } + /// + /// Starts a select statement builder + /// + /// A new select statement builder public SelectBuilder Select() { var builder = new SelectBuilder(QueryGenerator, Parameters); @@ -49,6 +83,11 @@ public SelectBuilder Select() } + /// + /// Starts an insert statement builder + /// + /// The type of the entity. + /// A new insert statement builder public InsertEntityBuilder Insert() where TEntity : class { @@ -59,6 +98,10 @@ public InsertEntityBuilder Insert() return builder; } + /// + /// Starts an insert statement builder + /// + /// A new insert statement builder public InsertBuilder Insert() { var builder = new InsertBuilder(QueryGenerator, Parameters); @@ -69,6 +112,11 @@ public InsertBuilder Insert() } + /// + /// Starts an update statement builder + /// + /// The type of the entity. + /// A new update statement builder public UpdateEntityBuilder Update() where TEntity : class { @@ -80,6 +128,10 @@ public UpdateEntityBuilder Update() } + /// + /// Starts an update statement builder + /// + /// A new update statement builder public UpdateBuilder Update() { var builder = new UpdateBuilder(QueryGenerator, Parameters); @@ -89,6 +141,11 @@ public UpdateBuilder Update() return builder; } + /// + /// Starts a delete statement builder + /// + /// The type of the entity. + /// A new delete statement builder public DeleteEntityBuilder Delete() where TEntity : class { @@ -100,6 +157,10 @@ public DeleteEntityBuilder Delete() } + /// + /// Starts a delete statement builder + /// + /// A new insert statement builder public DeleteBuilder Delete() { var builder = new DeleteBuilder(QueryGenerator, Parameters); @@ -109,7 +170,7 @@ public DeleteBuilder Delete() return builder; } - + /// public QueryStatement BuildStatement() { // optimize for when only 1 builder diff --git a/src/FluentCommand/Query/QueryBuilderExtensions.cs b/src/FluentCommand/Query/QueryBuilderExtensions.cs index d7074ca9..638e265e 100644 --- a/src/FluentCommand/Query/QueryBuilderExtensions.cs +++ b/src/FluentCommand/Query/QueryBuilderExtensions.cs @@ -1,7 +1,18 @@ namespace FluentCommand.Query; +/// +/// Extension methods for building a query for the data session +/// public static class QueryBuilderExtensions { + /// + /// Set the data command statement using the builder action. + /// + /// The data session. + /// The query builder action. + /// + /// A fluent to a data command. + /// public static IDataCommand Sql(this IDataSession dataSession, Action builder) { var queryParameters = new List(); diff --git a/src/FluentCommand/Query/QueryParameter.cs b/src/FluentCommand/Query/QueryParameter.cs index de8abd05..8a504548 100644 --- a/src/FluentCommand/Query/QueryParameter.cs +++ b/src/FluentCommand/Query/QueryParameter.cs @@ -2,8 +2,17 @@ namespace FluentCommand.Query; +/// +/// A query parameter +/// public class QueryParameter { + /// + /// Initializes a new instance of the class. + /// + /// The parameter name. + /// The parameter value. + /// The parameter type. public QueryParameter(string name, object value, Type type) { Name = name; @@ -11,9 +20,27 @@ public QueryParameter(string name, object value, Type type) Type = type; } + /// + /// Gets the parameter name. + /// + /// + /// The parameter name. + /// public string Name { get; } + /// + /// Gets the parameter value. + /// + /// + /// The parameter value. + /// public object Value { get; } + /// + /// Gets the parameter type. + /// + /// + /// The parameter type. + /// public Type Type { get; } } diff --git a/src/FluentCommand/Query/QueryStatement.cs b/src/FluentCommand/Query/QueryStatement.cs index 4d5953e3..40ce8c23 100644 --- a/src/FluentCommand/Query/QueryStatement.cs +++ b/src/FluentCommand/Query/QueryStatement.cs @@ -1,20 +1,33 @@ namespace FluentCommand.Query; +/// +/// class defining a sql query +/// +/// public class QueryStatement : IQueryStatement { + /// + /// Initializes a new instance of the class. + /// + /// The sql statement. + /// The query parameters. + /// statement cannot be null or whitespace. - statement + /// parameters cannot be null public QueryStatement(string statement, IReadOnlyCollection parameters) { if (string.IsNullOrWhiteSpace(statement)) throw new ArgumentException($"'{nameof(statement)}' cannot be null or whitespace.", nameof(statement)); - if (parameters == null) + if (parameters is null) throw new ArgumentNullException(nameof(parameters)); Statement = statement; Parameters = parameters; } + /// public string Statement { get; } + /// public IReadOnlyCollection Parameters { get; } } diff --git a/src/FluentCommand/Query/SelectBuilder.cs b/src/FluentCommand/Query/SelectBuilder.cs index 36a28dc8..ac424ad6 100644 --- a/src/FluentCommand/Query/SelectBuilder.cs +++ b/src/FluentCommand/Query/SelectBuilder.cs @@ -4,8 +4,17 @@ namespace FluentCommand.Query; +/// +/// Select query builder +/// public class SelectBuilder : SelectBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The logical operator. public SelectBuilder( IQueryGenerator queryGenerator, List parameters, @@ -15,9 +24,18 @@ public SelectBuilder( } } +/// +/// Select query builder +/// public abstract class SelectBuilder : WhereBuilder where TBuilder : SelectBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The logical operator. protected SelectBuilder( IQueryGenerator queryGenerator, List parameters, @@ -26,19 +44,64 @@ protected SelectBuilder( { } + /// + /// Gets the select expressions. + /// + /// + /// The select expressions. + /// protected HashSet SelectExpressions { get; } = new(); + /// + /// Gets from expressions. + /// + /// + /// From expressions. + /// protected HashSet FromExpressions { get; } = new(); + /// + /// Gets the sort expressions. + /// + /// + /// The sort expressions. + /// protected HashSet SortExpressions { get; } = new(); + /// + /// Gets the group expressions. + /// + /// + /// The group expressions. + /// protected HashSet GroupExpressions { get; } = new(); + /// + /// Gets the join expressions. + /// + /// + /// The join expressions. + /// protected HashSet JoinExpressions { get; } = new(); + /// + /// Gets the limit expressions. + /// + /// + /// The limit expressions. + /// protected HashSet LimitExpressions { get; } = new(); + /// + /// Adds a column expression with the specified name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Column( string columnName, string tableAlias = null, @@ -51,6 +114,16 @@ public TBuilder Column( return (TBuilder)this; } + /// + /// Conditionally adds a column expression with the specified name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder ColumnIf( string columnName, string tableAlias = null, @@ -63,6 +136,15 @@ public TBuilder ColumnIf( return Column(columnName, tableAlias, columnAlias); } + /// + /// Adds a column expression for each of specified names. + /// + /// The column names. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// + /// columnNames public virtual TBuilder Columns( IEnumerable columnNames, string tableAlias = null) @@ -77,6 +159,15 @@ public virtual TBuilder Columns( } + /// + /// Adds a count expression using the specified column name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Count( string columnName = "*", string tableAlias = null, @@ -89,6 +180,16 @@ public TBuilder Count( return (TBuilder)this; } + /// + /// Adds an aggregate expression using the specified function and column name. + /// + /// The aggregate function. + /// Name of the column. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Aggregate( AggregateFunctions function, string columnName, @@ -103,6 +204,15 @@ public TBuilder Aggregate( } + /// + /// Add a from clause to the query. + /// + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public virtual TBuilder From( string tableName, string tableSchema = null, @@ -115,6 +225,14 @@ public virtual TBuilder From( return (TBuilder)this; } + /// + /// Add a from clause to the query. + /// + /// The type of the entity. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder From( string tableAlias = null) { @@ -128,6 +246,13 @@ public TBuilder From( } + /// + /// Add a raw from clause to the query. + /// + /// From clause. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder FromRaw(string fromClause) { if (fromClause.HasValue()) @@ -137,6 +262,13 @@ public TBuilder FromRaw(string fromClause) } + /// + /// Add a join clause using the specified builder action + /// + /// The builder. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Join(Action builder) { var innerBuilder = new JoinBuilder(QueryGenerator, Parameters); @@ -148,6 +280,14 @@ public TBuilder Join(Action builder) } + /// + /// Add an order by clause with the specified column name and sort direction. + /// + /// Name of the column. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderBy( string columnName, SortDirections sortDirection = SortDirections.Ascending) @@ -155,6 +295,15 @@ public TBuilder OrderBy( return OrderBy(columnName, null, sortDirection); } + /// + /// Add an order by clause with the specified column name, sort direction and table alias. + /// + /// Name of the column. + /// The table alias. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderBy( string columnName, string tableAlias, @@ -167,6 +316,15 @@ public TBuilder OrderBy( return (TBuilder)this; } + /// + /// Conditionally add an order by clause with the specified column name and sort direction. + /// + /// Name of the column. + /// The sort direction. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByIf( string columnName, SortDirections sortDirection = SortDirections.Ascending, @@ -175,6 +333,16 @@ public TBuilder OrderByIf( return OrderByIf(columnName, null, sortDirection, condition); } + /// + /// Conditionally add an order by clause with the specified column name, sort direction and table alias. + /// + /// Name of the column. + /// The table alias. + /// The sort direction. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByIf( string columnName, string tableAlias, @@ -187,6 +355,13 @@ public TBuilder OrderByIf( return OrderBy(columnName, tableAlias, sortDirection); } + /// + /// Add a raw order by clause to the query. + /// + /// The order by clause. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByRaw(string sortExpression) { if (sortExpression.HasValue()) @@ -195,6 +370,14 @@ public TBuilder OrderByRaw(string sortExpression) return (TBuilder)this; } + /// + /// Conditionally add a raw order by clause to the query. + /// + /// The order by clause. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByRawIf( string sortExpression, Func condition = null) @@ -205,6 +388,13 @@ public TBuilder OrderByRawIf( return OrderByRaw(sortExpression); } + /// + /// Add multiple raw order by clauses to the query. + /// + /// The order by clauses. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OrderByRaw(IEnumerable sortExpressions) { if (sortExpressions is null) @@ -217,6 +407,14 @@ public TBuilder OrderByRaw(IEnumerable sortExpressions) } + /// + /// Adds a group by clause with the specified column name + /// + /// Name of the column. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder GroupBy( string columnName, string tableAlias = null) @@ -229,6 +427,14 @@ public TBuilder GroupBy( } + /// + /// Adds a limit expression with specified offset and size. + /// + /// The offset. + /// The size. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Limit(int offset = 0, int size = 0) { // no paging @@ -241,6 +447,14 @@ public TBuilder Limit(int offset = 0, int size = 0) return (TBuilder)this; } + /// + /// Adds a page limit expression with specified page and page size. + /// + /// The page number. + /// Size of the page. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Page(int page = 0, int pageSize = 0) { // no paging @@ -255,6 +469,7 @@ public TBuilder Page(int page = 0, int pageSize = 0) return (TBuilder)this; } + /// public override QueryStatement BuildStatement() { var selectStatement = new SelectStatement( diff --git a/src/FluentCommand/Query/SelectEntityBuilder.cs b/src/FluentCommand/Query/SelectEntityBuilder.cs index 8a18da79..5288db49 100644 --- a/src/FluentCommand/Query/SelectEntityBuilder.cs +++ b/src/FluentCommand/Query/SelectEntityBuilder.cs @@ -6,17 +6,34 @@ namespace FluentCommand.Query; +/// +/// Select query builder +/// +/// The type of the entity. public class SelectEntityBuilder : SelectBuilder>, IWhereEntityBuilder> where TEntity : class { private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The logical operator. public SelectEntityBuilder(IQueryGenerator queryGenerator, List parameters, LogicalOperators logicalOperator = LogicalOperators.And) : base(queryGenerator, parameters, logicalOperator) { } + /// + /// Adds a column expression with the specified property. + /// + /// The property. + /// The table alias. + /// The column alias. + /// public SelectEntityBuilder Column( Expression> property, string tableAlias = null, @@ -32,6 +49,14 @@ public SelectEntityBuilder Column( } + /// + /// Adds a column expression with the specified property. + /// + /// The type of the model. + /// The property. + /// The table alias. + /// The column alias. + /// public SelectEntityBuilder Column( Expression> property, string tableAlias = null, @@ -48,6 +73,15 @@ public SelectEntityBuilder Column( } + /// + /// Conditionally adds a column expression with the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// The condition. + /// public SelectEntityBuilder ColumnIf( Expression> property, string tableAlias = null, @@ -63,6 +97,15 @@ public SelectEntityBuilder ColumnIf( return ColumnIf(propertyAccessor.Column, tableAlias, columnAlias ?? propertyAccessor.Name, condition); } + /// + /// Adds a column expression for each of specified names. + /// + /// The column names. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// + /// columnNames public override SelectEntityBuilder Columns( IEnumerable columnNames, string tableAlias = null) @@ -86,6 +129,14 @@ public override SelectEntityBuilder Columns( return this; } + /// + /// Adds a column expression for each property in . + /// + /// The table alias. + /// An optional filter to include properties. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder Columns( string tableAlias = null, Func filter = null) @@ -110,6 +161,15 @@ public SelectEntityBuilder Columns( return this; } + /// + /// Adds a column expression for each property in . + /// + /// The type of the model. + /// The table alias. + /// An optional filter to include properties. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder Columns( string tableAlias = null, Func filter = null) @@ -135,6 +195,16 @@ public SelectEntityBuilder Columns( return this; } + /// + /// Adds a count expression using the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder Count( Expression> property, string tableAlias = null, @@ -145,6 +215,17 @@ public SelectEntityBuilder Count( return Count(propertyAccessor.Column, tableAlias, columnAlias); } + /// + /// Adds an aggregate expression using the specified function and property. + /// + /// The type of the value. + /// The property. + /// The aggregate function. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder Aggregate( Expression> property, AggregateFunctions function, @@ -156,6 +237,7 @@ public SelectEntityBuilder Aggregate( return Aggregate(function, propertyAccessor.Column, tableAlias, columnAlias); } + /// public override SelectEntityBuilder From( string tableName = null, string tableSchema = null, @@ -167,6 +249,14 @@ public override SelectEntityBuilder From( tableAlias); } + /// + /// Add a join clause using the specified builder action + /// + /// The right join entity + /// The join builder. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder Join(Action> builder) where TRight : class { @@ -178,6 +268,15 @@ public SelectEntityBuilder Join(Action + /// Add a join clause using the specified builder action + /// + /// The left join entity + /// The right join entity + /// The join builder. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder Join(Action> builder) where TLeft : class where TRight : class @@ -190,6 +289,7 @@ public SelectEntityBuilder Join(Action public SelectEntityBuilder Where( Expression> property, TValue parameterValue, @@ -198,6 +298,7 @@ public SelectEntityBuilder Where( return Where(property, parameterValue, null, filterOperator); } + /// public SelectEntityBuilder Where( Expression> property, TValue parameterValue, @@ -209,6 +310,18 @@ public SelectEntityBuilder Where( return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator); } + /// + /// Create a where clause with the specified property, value, operator and table alias + /// + /// The type of the model + /// The type of the value. + /// The property. + /// The parameter value. + /// The table alias. + /// The filter operator. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder Where( Expression> property, TValue parameterValue, @@ -221,6 +334,7 @@ public SelectEntityBuilder Where( return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator); } + /// public SelectEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -230,6 +344,7 @@ public SelectEntityBuilder WhereIf( return WhereIf(property, parameterValue, null, filterOperator, condition); } + /// public SelectEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -242,6 +357,7 @@ public SelectEntityBuilder WhereIf( return WhereIf(propertyAccessor.Column, parameterValue, tableAlias, filterOperator, condition); } + /// public SelectEntityBuilder WhereIn( Expression> property, IEnumerable parameterValues, @@ -252,6 +368,7 @@ public SelectEntityBuilder WhereIn( return WhereIn(propertyAccessor?.Column, parameterValues, tableAlias); } + /// public SelectEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -262,6 +379,7 @@ public SelectEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, condition); } + /// public SelectEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -273,6 +391,7 @@ public SelectEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, tableAlias, condition); } + /// public SelectEntityBuilder WhereOr(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.Or); @@ -287,6 +406,7 @@ public SelectEntityBuilder WhereOr(Action return this; } + /// public SelectEntityBuilder WhereAnd(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.And); @@ -302,6 +422,15 @@ public SelectEntityBuilder WhereAnd(Action + /// Add an order by clause with the specified property and sort direction. + /// + /// The type of the value. + /// The property. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder OrderBy( Expression> property, SortDirections sortDirection = SortDirections.Ascending) @@ -311,6 +440,16 @@ public SelectEntityBuilder OrderBy( return OrderBy(propertyAccessor.Column, null, sortDirection); } + /// + /// Add an order by clause with the specified property, sort direction and table alias. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The sort direction. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder OrderBy( Expression> property, string tableAlias, @@ -321,6 +460,16 @@ public SelectEntityBuilder OrderBy( return OrderBy(propertyAccessor.Column, tableAlias, sortDirection); } + /// + /// Conditionally add an order by clause with the specified property and sort direction. + /// + /// The type of the value. + /// The property. + /// The sort direction. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder OrderByIf( Expression> property, SortDirections sortDirection = SortDirections.Ascending, @@ -331,6 +480,17 @@ public SelectEntityBuilder OrderByIf( return OrderByIf(propertyAccessor.Column, null, sortDirection, condition); } + /// + /// Conditionally add an order by clause with the specified property, sort direction and table alias. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The sort direction. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder OrderByIf( Expression> property, string tableAlias, @@ -342,6 +502,15 @@ public SelectEntityBuilder OrderByIf( return OrderByIf(propertyAccessor.Column, tableAlias, sortDirection, condition); } + /// + /// Add a group by clause with the specified property and table alias. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public SelectEntityBuilder GroupBy( Expression> property, string tableAlias = null) @@ -351,6 +520,7 @@ public SelectEntityBuilder GroupBy( return GroupBy(propertyAccessor.Column, tableAlias); } + /// public override QueryStatement BuildStatement() { // add table and schema from attribute if not set diff --git a/src/FluentCommand/Query/SortDirections.cs b/src/FluentCommand/Query/SortDirections.cs index d01a5bf0..020487b6 100644 --- a/src/FluentCommand/Query/SortDirections.cs +++ b/src/FluentCommand/Query/SortDirections.cs @@ -1,7 +1,12 @@ namespace FluentCommand.Query; +/// +/// Query sort directions +/// public enum SortDirections { + /// Sort ascending direction Ascending, + /// Sort descending direction Descending } diff --git a/src/FluentCommand/Query/StatementBuilder.cs b/src/FluentCommand/Query/StatementBuilder.cs index 179cbe16..355329cd 100644 --- a/src/FluentCommand/Query/StatementBuilder.cs +++ b/src/FluentCommand/Query/StatementBuilder.cs @@ -5,21 +5,51 @@ namespace FluentCommand.Query; +/// +/// Query statement builder +/// public class StatementBuilder : StatementBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. public StatementBuilder(IQueryGenerator queryGenerator, List parameters) : base(queryGenerator, parameters) { } + /// + /// Gets or sets the query sql statement. + /// + /// + /// The query sql statement. + /// protected string Statement { get; set; } + /// + /// Sets the query statement. + /// + /// The query statement. + /// + /// The same builder so that multiple calls can be chained. + /// public StatementBuilder Query(string queryStatement) { Statement = queryStatement; return this; } + /// + /// Adds a query parameter the specified name and value. + /// + /// The type of the value. + /// The parameter name. + /// The parameter value. + /// + /// The same builder so that multiple calls can be chained. + /// public StatementBuilder Parameter(string name, TValue value) { var queryParam = new QueryParameter(name, value, typeof(TValue)); @@ -28,15 +58,26 @@ public StatementBuilder Parameter(string name, TValue value) return this; } + /// public override QueryStatement BuildStatement() { return new QueryStatement(Statement, Parameters); } } +/// +/// Base class for query statement +/// +/// The type of the builder. public abstract class StatementBuilder : IStatementBuilder, IQueryBuilder where TBuilder : StatementBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// queryGenerator or parameters is null protected StatementBuilder(IQueryGenerator queryGenerator, List parameters) { QueryGenerator = queryGenerator ?? throw new ArgumentNullException(nameof(queryGenerator)); @@ -44,13 +85,39 @@ protected StatementBuilder(IQueryGenerator queryGenerator, List } + /// + /// Gets the query generator. + /// + /// + /// The query generator. + /// protected IQueryGenerator QueryGenerator { get; } + /// + /// Gets the query parameters. + /// + /// + /// The query parameters. + /// protected List Parameters { get; } + /// + /// Gets or sets the query comment expressions. + /// + /// + /// The query comment expressions. + /// protected List CommentExpressions { get; set; } = new(); + /// + /// Tags the query with specified comment, caller name, file and line number. + /// + /// The query comment. + /// The caller member name. + /// The caller source file path. + /// The caller source line number. + /// public TBuilder Tag( string comment = "Caller", [CallerMemberName] string memberName = "", @@ -68,6 +135,13 @@ public TBuilder Tag( return (TBuilder)this; } + /// + /// Adds the specified comment to the query. + /// + /// The query comment. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Comment(string comment) { if (comment.IsNullOrWhiteSpace()) @@ -80,12 +154,20 @@ public TBuilder Comment(string comment) return (TBuilder)this; } + + /// public abstract QueryStatement BuildStatement(); + /// + /// Gets the next unique parameter name. + /// + /// The next unique parameter name protected string NextParameter() => $"@p{Parameters.Count:0000}"; + /// IQueryGenerator IQueryBuilder.QueryGenerator => QueryGenerator; + /// List IQueryBuilder.Parameters => Parameters; } diff --git a/src/FluentCommand/Query/UpdateBuilder.cs b/src/FluentCommand/Query/UpdateBuilder.cs index e200c628..6cac66fe 100644 --- a/src/FluentCommand/Query/UpdateBuilder.cs +++ b/src/FluentCommand/Query/UpdateBuilder.cs @@ -3,8 +3,17 @@ namespace FluentCommand.Query; +/// +/// Update query statement builder +/// public class UpdateBuilder : UpdateBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// The logical operator. public UpdateBuilder( IQueryGenerator queryGenerator, List parameters, @@ -14,9 +23,18 @@ public UpdateBuilder( } } +/// +/// Insert query statement builder +/// public abstract class UpdateBuilder : WhereBuilder where TBuilder : UpdateBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// The logical operator. protected UpdateBuilder( IQueryGenerator queryGenerator, List parameters, @@ -26,17 +44,56 @@ protected UpdateBuilder( } + /// + /// Gets the update expressions. + /// + /// + /// The update expressions. + /// protected HashSet UpdateExpressions { get; } = new(); + /// + /// Gets the output expressions. + /// + /// + /// The output expressions. + /// protected HashSet OutputExpressions { get; } = new(); + /// + /// Gets from expressions. + /// + /// + /// From expressions. + /// protected HashSet FromExpressions { get; } = new(); + /// + /// Gets the join expressions. + /// + /// + /// The join expressions. + /// protected HashSet JoinExpressions { get; } = new(); + /// + /// Gets the table expression. + /// + /// + /// The table expression. + /// protected TableExpression TableExpression { get; private set; } + /// + /// Set the target table to update. + /// + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Table( string tableName, string tableSchema = null, @@ -48,6 +105,15 @@ public TBuilder Table( } + /// + /// Adds a value with specified column name and value. + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Value( string columnName, TValue parameterValue) @@ -55,6 +121,15 @@ public TBuilder Value( return Value(columnName, parameterValue, typeof(TValue)); } + /// + /// Adds a value with specified column name and value. + /// + /// Name of the column. + /// The parameter value. + /// Type of the parameter. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Value( string columnName, object parameterValue, @@ -72,6 +147,16 @@ public TBuilder Value( return (TBuilder)this; } + /// + /// Conditionally adds a value with specified column name and value. + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder ValueIf( string columnName, TValue parameterValue, @@ -84,6 +169,14 @@ public TBuilder ValueIf( } + /// + /// Add an output clause for the specified column names. + /// + /// The column names. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Output( IEnumerable columnNames, string tableAlias = "INSERTED") @@ -97,6 +190,15 @@ public TBuilder Output( return (TBuilder)this; } + /// + /// Add an output clause for the specified column name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Output( string columnName, string tableAlias = "INSERTED", @@ -109,6 +211,16 @@ public TBuilder Output( return (TBuilder)this; } + /// + /// Conditionally add an output clause for the specified column name. + /// + /// Name of the column. + /// The table alias. + /// The column alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder OutputIf( string columnName, string tableAlias = "INSERTED", @@ -122,6 +234,15 @@ public TBuilder OutputIf( } + /// + /// Add a from clause to the query. + /// + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public virtual TBuilder From( string tableName, string tableSchema = null, @@ -134,6 +255,13 @@ public virtual TBuilder From( return (TBuilder)this; } + /// + /// Add a raw from clause to the query. + /// + /// From clause. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder FromRaw(string fromClause) { if (fromClause.HasValue()) @@ -142,6 +270,13 @@ public TBuilder FromRaw(string fromClause) return (TBuilder)this; } + /// + /// Add a join clause using the specified builder action + /// + /// The builder. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Join(Action builder) { var innerBuilder = new JoinBuilder(QueryGenerator, Parameters); @@ -152,7 +287,7 @@ public TBuilder Join(Action builder) return (TBuilder)this; } - + /// public override QueryStatement BuildStatement() { var updateStatement = new UpdateStatement( diff --git a/src/FluentCommand/Query/UpdateEntityBuilder.cs b/src/FluentCommand/Query/UpdateEntityBuilder.cs index db7432a3..e33257a1 100644 --- a/src/FluentCommand/Query/UpdateEntityBuilder.cs +++ b/src/FluentCommand/Query/UpdateEntityBuilder.cs @@ -6,12 +6,22 @@ namespace FluentCommand.Query; +/// +/// Update query statement builder +/// +/// The type of the entity. public class UpdateEntityBuilder : UpdateBuilder>, IWhereEntityBuilder> where TEntity : class { private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// The logical operator. public UpdateEntityBuilder( IQueryGenerator queryGenerator, List parameters, @@ -20,6 +30,15 @@ public UpdateEntityBuilder( { } + /// + /// Adds a value with specified property and value. + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder Value( Expression> property, TValue parameterValue) @@ -28,6 +47,16 @@ public UpdateEntityBuilder Value( return Value(propertyAccessor?.Column, parameterValue); } + /// + /// Conditionally adds a value with specified property and value. + /// + /// The type of the value. + /// The property. + /// The parameter value. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder ValueIf( Expression> property, TValue parameterValue, @@ -37,6 +66,15 @@ public UpdateEntityBuilder ValueIf( return ValueIf(propertyAccessor?.Column, parameterValue, condition); } + /// + /// Adds a values from the specified entity. If column names are passed in, + /// only those that match an entity property name will be included. + /// + /// The entity to update. + /// The column names to include. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder Values( TEntity entity, IEnumerable columnNames = null) @@ -63,6 +101,16 @@ public UpdateEntityBuilder Values( } + /// + /// Add an output clause for the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder Output( Expression> property, string tableAlias = "INSERTED", @@ -72,6 +120,17 @@ public UpdateEntityBuilder Output( return Output(propertyAccessor?.Column, tableAlias, columnAlias); } + /// + /// Conditionally add an output clause for the specified property. + /// + /// The type of the value. + /// The property. + /// The table alias. + /// The column alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder OutputIf( Expression> property, string tableAlias = "INSERTED", @@ -82,6 +141,15 @@ public UpdateEntityBuilder OutputIf( return OutputIf(propertyAccessor?.Column, tableAlias, columnAlias, condition); } + /// + /// Add a from clause to the query. + /// + /// Name of the table. + /// The table schema. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public override UpdateEntityBuilder From( string tableName = null, string tableSchema = null, @@ -93,6 +161,14 @@ public override UpdateEntityBuilder From( tableAlias); } + /// + /// Add a join clause using the specified builder action + /// + /// The right join entity + /// The join builder. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder Join(Action> builder) where TRight : class { @@ -104,6 +180,15 @@ public UpdateEntityBuilder Join(Action + /// Add a join clause using the specified builder action + /// + /// The left join entity + /// The right join entity + /// The join builder. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder Join(Action> builder) where TLeft : class where TRight : class @@ -117,6 +202,7 @@ public UpdateEntityBuilder Join(Action public UpdateEntityBuilder Where( Expression> property, TValue parameterValue, @@ -125,6 +211,7 @@ public UpdateEntityBuilder Where( return Where(property, parameterValue, null, filterOperator); } + /// public UpdateEntityBuilder Where( Expression> property, TValue parameterValue, @@ -136,6 +223,18 @@ public UpdateEntityBuilder Where( return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator); } + /// + /// Create a where clause with the specified property, value, operator and table alias + /// + /// The type of the model + /// The type of the value. + /// The property. + /// The parameter value. + /// The table alias. + /// The filter operator. + /// + /// The same builder so that multiple calls can be chained. + /// public UpdateEntityBuilder Where( Expression> property, TValue parameterValue, @@ -148,6 +247,7 @@ public UpdateEntityBuilder Where( return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator); } + /// public UpdateEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -157,6 +257,7 @@ public UpdateEntityBuilder WhereIf( return WhereIf(property, parameterValue, null, filterOperator, condition); } + /// public UpdateEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -169,6 +270,7 @@ public UpdateEntityBuilder WhereIf( return WhereIf(propertyAccessor.Column, parameterValue, tableAlias, filterOperator, condition); } + /// public UpdateEntityBuilder WhereIn( Expression> property, IEnumerable parameterValues, @@ -179,6 +281,7 @@ public UpdateEntityBuilder WhereIn( return WhereIn(propertyAccessor?.Column, parameterValues, tableAlias); } + /// public UpdateEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -189,6 +292,7 @@ public UpdateEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, condition); } + /// public UpdateEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -200,6 +304,7 @@ public UpdateEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, tableAlias, condition); } + /// public UpdateEntityBuilder WhereOr(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.Or); @@ -214,6 +319,7 @@ public UpdateEntityBuilder WhereOr(Action return this; } + /// public UpdateEntityBuilder WhereAnd(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.And); @@ -229,6 +335,7 @@ public UpdateEntityBuilder WhereAnd(Action public override QueryStatement BuildStatement() { // add table and schema from attribute if not set diff --git a/src/FluentCommand/Query/WhereBuilder.cs b/src/FluentCommand/Query/WhereBuilder.cs index 03ec86e1..32eabd04 100644 --- a/src/FluentCommand/Query/WhereBuilder.cs +++ b/src/FluentCommand/Query/WhereBuilder.cs @@ -3,8 +3,17 @@ namespace FluentCommand.Query; +/// +/// Where clause builder +/// public class WhereBuilder : WhereBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The parameters. + /// The logical operator. public WhereBuilder( IQueryGenerator queryGenerator, List parameters, @@ -13,6 +22,7 @@ public WhereBuilder( { } + /// public override QueryStatement BuildStatement() { var statement = QueryGenerator.BuildWhere( @@ -23,20 +33,52 @@ public override QueryStatement BuildStatement() } } +/// +/// Where clause builder +/// +/// The type of the builder. public abstract class WhereBuilder : StatementBuilder where TBuilder : WhereBuilder { + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The logical operator. protected WhereBuilder(IQueryGenerator queryGenerator, List parameters, LogicalOperators logicalOperator = LogicalOperators.And) : base(queryGenerator, parameters) { LogicalOperator = logicalOperator; } + /// + /// Gets the where expressions. + /// + /// + /// The where expressions. + /// protected HashSet WhereExpressions { get; } = new(); + /// + /// Gets the logical operator. + /// + /// + /// The logical operator. + /// protected LogicalOperators LogicalOperator { get; } + /// + /// Create a where clause with the specified column, value and operator + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. + /// The filter operator. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Where( string columnName, TValue parameterValue, @@ -45,6 +87,17 @@ public TBuilder Where( return Where(columnName, parameterValue, null, filterOperator); } + /// + /// Create a where clause with the specified column, value, operator and table alias + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. + /// The table alias. + /// The filter operator. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder Where( string columnName, TValue parameterValue, @@ -60,6 +113,16 @@ public TBuilder Where( } + /// + /// Create a where in clause with the specified column, values and table alias + /// + /// The type of the value. + /// Name of the column. + /// The parameter values. + /// The table alias. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder WhereIn( string columnName, IEnumerable parameterValues, @@ -82,6 +145,16 @@ public TBuilder WhereIn( return (TBuilder)this; } + /// + /// Conditionally create a where in clause with the specified column and values + /// + /// The type of the value. + /// Name of the column. + /// The parameter values. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder WhereInIf( string columnName, IEnumerable parameterValues, @@ -93,6 +166,17 @@ public TBuilder WhereInIf( return WhereIn(columnName, parameterValues); } + /// + /// Conditionally create a where in clause with the specified column, values and table alias + /// + /// The type of the value. + /// Name of the column. + /// The parameter values. + /// The table alias. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder WhereInIf( string columnName, IEnumerable parameterValues, @@ -105,6 +189,17 @@ public TBuilder WhereInIf( return WhereIn(columnName, parameterValues, tableAlias); } + /// + /// Conditionally create a where clause with the specified column, value and operator + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. + /// The filter operator. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder WhereIf( string columnName, TValue parameterValue, @@ -114,6 +209,18 @@ public TBuilder WhereIf( return WhereIf(columnName, parameterValue, null, filterOperator, condition); } + /// + /// Conditionally create a where clause with the specified property, value, operator and table alias + /// + /// The type of the value. + /// Name of the column. + /// The parameter value. + /// The table alias. + /// The filter operator. + /// The condition. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder WhereIf( string columnName, TValue parameterValue, @@ -127,6 +234,12 @@ public TBuilder WhereIf( return Where(columnName, parameterValue, tableAlias, filterOperator); } + /// + /// Create a where clause with the specified raw query + /// + /// The where clause. + /// The parameters. + /// public TBuilder WhereRaw( string whereClause, IEnumerable parameters = null) @@ -142,6 +255,13 @@ public TBuilder WhereRaw( return (TBuilder)this; } + /// + /// Conditionally create a where clause with the specified raw query + /// + /// The where clause. + /// The parameters. + /// The condition. + /// public TBuilder WhereRawIf( string whereClause, IEnumerable parameters = null, @@ -153,6 +273,13 @@ public TBuilder WhereRawIf( return WhereRaw(whereClause, parameters); } + /// + /// Create a logical AND where clause group + /// + /// The logical AND where clause builder. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder WhereOr(Action builder) { var innerBuilder = new LogicalBuilder(QueryGenerator, Parameters, LogicalOperators.Or); @@ -166,6 +293,13 @@ public TBuilder WhereOr(Action builder) return (TBuilder)this; } + /// + /// Create a logical OR where clause group + /// + /// The logical OR where clause builder. + /// + /// The same builder so that multiple calls can be chained. + /// public TBuilder WhereAnd(Action builder) { var innerBuilder = new LogicalBuilder(QueryGenerator, Parameters, LogicalOperators.And); diff --git a/src/FluentCommand/Query/WhereEntityBuilder.cs b/src/FluentCommand/Query/WhereEntityBuilder.cs index 7ba89648..f214a0b2 100644 --- a/src/FluentCommand/Query/WhereEntityBuilder.cs +++ b/src/FluentCommand/Query/WhereEntityBuilder.cs @@ -6,12 +6,22 @@ namespace FluentCommand.Query; +/// +/// Where clause builder +/// +/// The type of the entity. public class WhereEntityBuilder : WhereBuilder>, IWhereEntityBuilder> where TEntity : class { private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor(); + /// + /// Initializes a new instance of the class. + /// + /// The query generator. + /// The query parameters. + /// The logical operator. public WhereEntityBuilder( IQueryGenerator queryGenerator, List parameters, @@ -20,6 +30,8 @@ public WhereEntityBuilder( { } + + /// public WhereEntityBuilder Where( Expression> property, TValue parameterValue, @@ -28,6 +40,7 @@ public WhereEntityBuilder Where( return Where(property, parameterValue, null, filterOperator); } + /// public WhereEntityBuilder Where( Expression> property, TValue parameterValue, @@ -39,6 +52,7 @@ public WhereEntityBuilder Where( return Where(propertyAccessor?.Column, parameterValue, tableAlias, filterOperator); } + /// public WhereEntityBuilder WhereIn( Expression> property, IEnumerable parameterValues, @@ -49,6 +63,7 @@ public WhereEntityBuilder WhereIn( return WhereIn(propertyAccessor?.Column, parameterValues, tableAlias); } + /// public WhereEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -59,6 +74,7 @@ public WhereEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, condition); } + /// public WhereEntityBuilder WhereInIf( Expression> property, IEnumerable parameterValues, @@ -70,6 +86,7 @@ public WhereEntityBuilder WhereInIf( return WhereInIf(propertyAccessor?.Column, parameterValues, tableAlias, condition); } + /// public WhereEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -79,6 +96,7 @@ public WhereEntityBuilder WhereIf( return WhereIf(property, parameterValue, null, filterOperator, condition); } + /// public WhereEntityBuilder WhereIf( Expression> property, TValue parameterValue, @@ -91,6 +109,7 @@ public WhereEntityBuilder WhereIf( return WhereIf(propertyAccessor?.Column, parameterValue, tableAlias, filterOperator, condition); } + /// public WhereEntityBuilder WhereOr(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.Or); @@ -105,6 +124,7 @@ public WhereEntityBuilder WhereOr(Action> return this; } + /// public WhereEntityBuilder WhereAnd(Action> builder) { var innerBuilder = new LogicalEntityBuilder(QueryGenerator, Parameters, LogicalOperators.And); @@ -119,6 +139,7 @@ public WhereEntityBuilder WhereAnd(Action return this; } + /// public override QueryStatement BuildStatement() { if (WhereExpressions == null || WhereExpressions.Count == 0) diff --git a/src/FluentCommand/Reflection/MethodAccessor.cs b/src/FluentCommand/Reflection/MethodAccessor.cs index 00d67dd7..b5ea26d4 100644 --- a/src/FluentCommand/Reflection/MethodAccessor.cs +++ b/src/FluentCommand/Reflection/MethodAccessor.cs @@ -59,13 +59,8 @@ public object Invoke(object instance, params object[] arguments) /// The method key internal static int GetKey(string name, IEnumerable parameterTypes) { - unchecked - { - int result = name?.GetHashCode() ?? 0; - result = parameterTypes.Aggregate(result, - (r, p) => (r * 397) ^ (p?.GetHashCode() ?? 0)); - - return result; - } + return Internal.HashCode.Seed + .Combine(name) + .CombineAll(parameterTypes); } }