diff --git a/PetaPoco/Attributes/ColumnAttribute.cs b/PetaPoco/Attributes/ColumnAttribute.cs index 0bce297c..9273cb69 100644 --- a/PetaPoco/Attributes/ColumnAttribute.cs +++ b/PetaPoco/Attributes/ColumnAttribute.cs @@ -48,8 +48,8 @@ public class ColumnAttribute : Attribute /// /// When set, this template is used for generating the INSERT portion of the SQL statement instead of the default ///
String.Format("{0}{1}", paramPrefix, index). - /// Setting this allows database-related interactions, such as: - ///
String.Format("CAST({0}{1} AS JSON)", paramPrefix, index). + /// Setting this allows database-related interactions, such as: + ///
String.Format("CAST({0}{1} AS JSON)", paramPrefix, index).
///
public string InsertTemplate { get; set; } @@ -59,8 +59,8 @@ public class ColumnAttribute : Attribute /// /// When set, this template is used for generating the UPDATE portion of the SQL statement instead of the default ///
String.Format("{0} = {1}{2}", colName, paramPrefix, index). - /// Setting this allows database-related interactions, such as: - ///
String.Format("{0} = CAST({1}{2} AS JSON)", colName, paramPrefix, index) + /// Setting this allows database-related interactions, such as: + ///
String.Format("{0} = CAST({1}{2} AS JSON)", colName, paramPrefix, index)
///
public string UpdateTemplate { get; set; } diff --git a/PetaPoco/Attributes/IgnoreAttribute.cs b/PetaPoco/Attributes/IgnoreAttribute.cs index 55745170..c4204df9 100644 --- a/PetaPoco/Attributes/IgnoreAttribute.cs +++ b/PetaPoco/Attributes/IgnoreAttribute.cs @@ -7,7 +7,7 @@ namespace PetaPoco /// /// /// Properties decorated with this attribute are completely ignored by PetaPoco, and do not participate in any database-related operations. - /// If you find yourself using this attribute excessively, consider instead decorating your POCO class with the , and then marking the properties you want mapped with their appropriate column attribute. + /// If you find yourself using this attribute excessively, consider instead decorating your POCO class with the , and then marking the properties you want mapped with their appropriate column attribute. /// /// [AttributeUsage(AttributeTargets.Property)] diff --git a/PetaPoco/Attributes/PrimaryKeyAttribute.cs b/PetaPoco/Attributes/PrimaryKeyAttribute.cs index 78ed66de..3f1e66e0 100644 --- a/PetaPoco/Attributes/PrimaryKeyAttribute.cs +++ b/PetaPoco/Attributes/PrimaryKeyAttribute.cs @@ -12,7 +12,7 @@ namespace PetaPoco public class PrimaryKeyAttribute : Attribute { /// - /// Gets the column name. + /// Gets the column name in the database. /// public string Value { get; } @@ -22,9 +22,9 @@ public class PrimaryKeyAttribute : Attribute public string SequenceName { get; set; } /// - /// Gets or sets whether the primary key column represented by this property is auto-incrementing in the database. + /// Gets or sets whether the primary key column represented by this property in the database is auto-incrementing. + /// Default is . /// - /// Default value is (auto-incrementing). public bool AutoIncrement { get; set; } = true; /// diff --git a/PetaPoco/Attributes/ResultColumnAttribute.cs b/PetaPoco/Attributes/ResultColumnAttribute.cs index 0758b510..5f368cbb 100644 --- a/PetaPoco/Attributes/ResultColumnAttribute.cs +++ b/PetaPoco/Attributes/ResultColumnAttribute.cs @@ -23,7 +23,7 @@ public enum IncludeInAutoSelect /// /// /// This attribute marks properties that are mapped to a column, but should not be involved in any mutating operations on the database. The property value is updated by queries from the database, but the database column it maps to will not be changed to reflect changes in this property. - /// Use the property to dictate whether the decorated property is included in operations using PetaPoco's AutoSelect feature (default is ). AutoSelect queries are operations made using the "short form" syntax, without specifying the SELECT [cols] FROM [table] portion of the SQL statement. The inferred portion of the SQL statement is then automatically generated by PetaPoco based on generics or the called method's parameters. + /// Use the property to dictate whether the decorated property is included in operations using PetaPoco's AutoSelect feature (default is ). AutoSelect queries are operations made using the "short form" syntax, without specifying the SELECT [cols] FROM [table] portion of the SQL statement. The inferred portion of the SQL statement is then automatically generated by PetaPoco based on generics or the called method's parameters. /// [AttributeUsage(AttributeTargets.Property)] public class ResultColumnAttribute : ColumnAttribute diff --git a/PetaPoco/Attributes/ValueConverterAttribute.cs b/PetaPoco/Attributes/ValueConverterAttribute.cs index 342dce58..3b5dd0d2 100644 --- a/PetaPoco/Attributes/ValueConverterAttribute.cs +++ b/PetaPoco/Attributes/ValueConverterAttribute.cs @@ -7,7 +7,7 @@ namespace PetaPoco /// /// /// ValueConverters are used to implement custom two-way conversions between your POCO property data type, and the mapped database column's data type. They are ideal for implementing a custom conversion without requiring any changes to the mapper. - /// To provide a custom ValueConverter for a property, inherit from this class, and supply definitions for both conversion methods for your data type. Decorate the appropriate properties that require your ValueConverter with your derived class. + /// To provide a custom ValueConverter for a property, inherit from this class, and supply definitions for both conversion methods for your data type. Decorate the appropriate properties that require your ValueConverter with your derived class. /// [AttributeUsage(AttributeTargets.Property)] public abstract class ValueConverterAttribute : Attribute diff --git a/PetaPoco/Core/ColumnInfo.cs b/PetaPoco/Core/ColumnInfo.cs index afa7d6f0..1f7890e3 100644 --- a/PetaPoco/Core/ColumnInfo.cs +++ b/PetaPoco/Core/ColumnInfo.cs @@ -22,14 +22,14 @@ public class ColumnInfo public string ColumnName { get; set; } /// - /// Gets or sets whether this column represents a property that should be updated in queries that include a user-supplied SELECT statement, but ignored in queries generated by AutoSelect. Result columns are always ignored in UPDATE and INSERT operations. + /// Gets or sets whether this column represents a property that should be updated in queries that include a user-supplied SELECT statement, but ignored in queries generated by AutoSelect. Result columns are always ignored in UPDATE and INSERT operations. /// - /// If , this property will be updated in SQL query operations containing a user-supplied SELECT statement, and ignored for all other database operations. + /// If , this property will be updated in SQL query operations containing a user-supplied SELECT statement, and ignored for all other database operations. /// public bool ResultColumn { get; set; } /// - /// Gets or sets whether this serves as a ResultColumn that is included with AutoSelect queries as well as queries containing user-supplied SELECT statements. + /// Gets or sets whether this serves as a ResultColumn that is included with AutoSelect queries as well as queries containing user-supplied SELECT statements. /// /// If , this property will be updated in all SQL queries, but ignored for all other database operations such as INSERT and UPDATE. /// @@ -69,25 +69,25 @@ public class ColumnInfo public bool ForceToUtc { get; set; } /// - /// Gets or sets the template used for INSERT operations. + /// Gets or sets the template used for INSERT operations. /// /// - /// When set, this template is used for generating the INSERT portion of the SQL statement instead of the default + /// When set, this template is used for generating the INSERT portion of the SQL statement instead of the default ///
String.Format("{0}{1}", paramPrefix, index). - /// Setting this allows database-related interactions, such as: - ///
String.Format("CAST({0}{1} AS JSON)", paramPrefix, index). + /// Setting this allows database-related interactions, such as: + ///
String.Format("CAST({0}{1} AS JSON)", paramPrefix, index).
///
/// public string InsertTemplate { get; set; } /// - /// Gets or sets the template used for UPDATE operations. + /// Gets or sets the template used for UPDATE operations. /// /// - /// When set, this template is used for generating the UPDATE portion of the SQL statement instead of the default + /// When set, this template is used for generating the UPDATE portion of the SQL statement instead of the default ///
String.Format("{0} = {1}{2}", colName, paramPrefix, index). - /// Setting this allows database-related interactions, such as: - ///
String.Format("{0} = CAST({1}{2} AS JSON)", colName, paramPrefix, index) + /// Setting this allows database-related interactions, such as: + ///
String.Format("{0} = CAST({1}{2} AS JSON)", colName, paramPrefix, index)
///
/// public string UpdateTemplate { get; set; } diff --git a/PetaPoco/Core/ConventionMapper.cs b/PetaPoco/Core/ConventionMapper.cs index be87057f..6233c91f 100644 --- a/PetaPoco/Core/ConventionMapper.cs +++ b/PetaPoco/Core/ConventionMapper.cs @@ -14,12 +14,12 @@ namespace PetaPoco public class ConventionMapper : IMapper { /// - /// Gets or sets the get sequence name logic. + /// Gets or sets the sequence name logic (for Oracle). /// public Func GetSequenceName { get; set; } /// - /// Gets or sets the inflect column name logic. + /// Gets or sets the inflected column name logic. /// public Func InflectColumnName { get; set; } diff --git a/PetaPoco/Core/DatabaseProvider.cs b/PetaPoco/Core/DatabaseProvider.cs index 0da386c5..98ef4921 100644 --- a/PetaPoco/Core/DatabaseProvider.cs +++ b/PetaPoco/Core/DatabaseProvider.cs @@ -65,27 +65,27 @@ public virtual string BuildPageQuery(long skip, long take, SQLParts parts, ref o public virtual string GetInsertOutputClause(string primaryKeyName) => string.Empty; /// - public virtual object ExecuteInsert(Database database, IDbCommand cmd, string primaryKeyName) + public virtual object ExecuteInsert(Database db, IDbCommand cmd, string primaryKeyName) { cmd.CommandText += ";\nSELECT @@IDENTITY AS NewID;"; - return ExecuteScalarHelper(database, cmd); + return ExecuteScalarHelper(db, cmd); } #if ASYNC /// - public virtual Task ExecuteInsertAsync(CancellationToken cancellationToken, Database database, IDbCommand cmd, string primaryKeyName) + public virtual Task ExecuteInsertAsync(CancellationToken cancellationToken, Database db, IDbCommand cmd, string primaryKeyName) { cmd.CommandText += ";\nSELECT @@IDENTITY AS NewID;"; - return ExecuteScalarHelperAsync(cancellationToken, database, cmd); + return ExecuteScalarHelperAsync(cancellationToken, db, cmd); } #endif /// - /// Returns the DbProviderFactory. + /// Returns the provider factory from one or more specified assembly qualified names. /// - /// The assembly qualified name of the provider factory. - /// The DbProviderFactory factory. - /// Thrown when does not match a type. + /// One or more assembly qualified names of the provider factory. + /// The provider factory. + /// None of the match a type. protected DbProviderFactory GetFactory(params string[] assemblyQualifiedNames) { Type ft = null; @@ -107,7 +107,7 @@ protected DbProviderFactory GetFactory(params string[] assemblyQualifiedNames) /// /// Type of IProvider to be registered. /// String to be matched against the beginning of the provider name. - /// Thrown when is null, empty, or consists only of white space. + /// is null, empty, or consists of only white space. public static void RegisterCustomProvider(string initialString) where T : IProvider, new() { if (String.IsNullOrWhiteSpace(initialString)) @@ -129,26 +129,26 @@ private static IProvider GetCustomProvider(string name) internal static void ClearCustomProviders() => customProviders.Clear(); /// - /// Instantiates a suitable IProvider instance based on the type and provider name. + /// Instantiates a suitable IProvider instance based on the specified provider's type. /// - /// The type name. - /// A flag that when set allows the default to be returned if not match is found. + /// The provider's type name. + /// A flag specifiying if the default should be returned if no match is found. /// The connection string. - /// The database provider. - /// Thrown when the name cannot be matched to a provider. - internal static IProvider Resolve(Type type, bool allowDefault, string connectionString) + /// The resolved database provider. + /// The name cannot be matched to a provider. + internal static IProvider Resolve(Type providerType, bool allowDefault, string connectionString) { - var typeName = type.Name; + var typeName = providerType.Name; // Try using type name first (more reliable) var custom = GetCustomProvider(typeName); if (custom != null) return custom; - if (type.Namespace != null) + if (providerType.Namespace != null) { - if (typeName.Equals("SqlConnection") && type.Namespace.StartsWith("Microsoft.Data") || - type.Namespace.StartsWith("Microsoft.Data") && typeName.Equals("SqlClientFactory")) + if (typeName.Equals("SqlConnection") && providerType.Namespace.StartsWith("Microsoft.Data") || + providerType.Namespace.StartsWith("Microsoft.Data") && typeName.Equals("SqlClientFactory")) return Singleton.Instance; } @@ -187,19 +187,19 @@ internal static IProvider Resolve(Type type, bool allowDefault, string connectio } if (!allowDefault) - throw new ArgumentException($"Could not match `{type.FullName}` to a provider.", nameof(type)); + throw new ArgumentException($"Could not match `{providerType.FullName}` to a provider.", nameof(providerType)); // Assume SQL Server return Singleton.Instance; } /// - /// Instantiates a suitable IProvider instance based on the type and provider name. + /// Instantiates a suitable IProvider instance based on the specified provider name. /// /// The provider name. - /// A flag that when set allows the default to be returned if not match is found. + /// A flag specifiying if the default should be returned if no match is found. /// The connection string. - /// The database type. + /// The resolved database provider. internal static IProvider Resolve(string providerName, bool allowDefault, string connectionString) { // Try again with provider name @@ -255,10 +255,10 @@ internal static IProvider Resolve(string providerName, bool allowDefault, string } /// - /// Unwraps a wrapped . + /// Unwraps the specified wrapped provider factory/>. /// /// The factory to unwrap. - /// The unwrapped factory or the original factory if no wrapping occurred. + /// The unwrapped factory, or the original factory if no wrapping occurred. internal static DbProviderFactory Unwrap(DbProviderFactory factory) { if (!(factory is IServiceProvider sp)) @@ -274,14 +274,39 @@ internal static DbProviderFactory Unwrap(DbProviderFactory factory) } } + /// + /// Executes a non-query command. + /// + /// The database instance on which to execute the command. + /// The SQL command to execute. protected void ExecuteNonQueryHelper(Database db, IDbCommand cmd) => db.ExecuteNonQueryHelper(cmd); + /// + /// Executes a query command and returns the first column of the first row in the result set. + /// + /// The database instance on which to execute the command. + /// The SQL command to execute. + /// The first column of the first row in the result set. protected object ExecuteScalarHelper(Database db, IDbCommand cmd) => db.ExecuteScalarHelper(cmd); #if ASYNC + /// + /// Asynchronously executes a non-query command. + /// + /// A cancellation token that can be used to cancel the operation. + /// The database instance on which to execute the command. + /// The SQL command to execute. + /// A task that represents the asynchronous operation. protected Task ExecuteNonQueryHelperAsync(CancellationToken cancellationToken, Database db, IDbCommand cmd) => db.ExecuteNonQueryHelperAsync(cancellationToken, cmd); + /// + /// Asynchronously executes a query command and returns the first column of the first row in the result set. + /// + /// A cancellation token that can be used to cancel the operation. + /// The database instance on which to execute the command. + /// The SQL command to execute. + /// A task that represents the asynchronous operation. The task result is the first column of the first row in the result set. protected Task ExecuteScalarHelperAsync(CancellationToken cancellationToken, Database db, IDbCommand cmd) => db.ExecuteScalarHelperAsync(cancellationToken, cmd); #endif diff --git a/PetaPoco/Core/DateTime2.cs b/PetaPoco/Core/DateTime2.cs index 411811a7..67682d58 100644 --- a/PetaPoco/Core/DateTime2.cs +++ b/PetaPoco/Core/DateTime2.cs @@ -7,7 +7,7 @@ namespace PetaPoco /// /// /// Using this type for a column-mapped POCO property is equivalent to decorating a DateTime property with . - /// DbType.DateTime2 is a data type used by SQL DBs with a larger date range and fractional second precision than DbType.DateTime. + /// DbType.DateTime2 is a data type used by SQL DBs with a larger date range and fractional second precision than DbType.DateTime. /// public class DateTime2 { diff --git a/PetaPoco/Core/GridReader.cs b/PetaPoco/Core/GridReader.cs index 17c5122d..5ca8a536 100644 --- a/PetaPoco/Core/GridReader.cs +++ b/PetaPoco/Core/GridReader.cs @@ -32,71 +32,59 @@ internal GridReader(Database database, IDbCommand command, IDataReader reader, I _defaultMapper = defaultMapper; } -#region public Read methods + #region Public Read methods /// public IEnumerable Read() - { - return SinglePocoFromIDataReader(_gridIndex); - } + => SinglePocoFromIDataReader(_gridIndex); /// public IEnumerable Read() - { - return MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2) }, null); - } + => MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2) }, null); /// public IEnumerable Read() - { - return MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3) }, null); - } + => MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3) }, null); /// public IEnumerable Read() - { - return MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null); - } + => MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null); /// - public IEnumerable Read(Func cb) - { - return MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2) }, cb); - } + public IEnumerable Read(Func projector) + => MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2) }, projector); /// - public IEnumerable Read(Func cb) - { - return MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3) }, cb); - } + public IEnumerable Read(Func projector) + => MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3) }, projector); /// - public IEnumerable Read(Func cb) - { - return MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, cb); - } + public IEnumerable Read(Func projector) + => MultiPocoFromIDataReader(_gridIndex, new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, projector); -#endregion + #endregion -#region PocoFromIDataReader + #region PocoFromIDataReader /// /// Reads data to a single POCO. /// - /// The type representing a row in the result set. - /// The row to be read from the underlying . - /// A POCO. - /// - /// + /// The POCO type representing a single result record. + /// The zero-based row index to be read from the underlying . + /// A POCO of type . + /// Called after the data reader has been disposed. + /// Result records are consumed in the incorrect order, or more than once. private IEnumerable SinglePocoFromIDataReader(int index) { if (_reader == null) throw new ObjectDisposedException(GetType().FullName, "The data reader has been disposed"); if (_consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); + _consumed = true; var pd = PocoData.ForType(typeof(T), _defaultMapper); + try { while (index == _gridIndex) @@ -123,7 +111,7 @@ private IEnumerable SinglePocoFromIDataReader(int index) } } } - finally // finally so that First etc progresses things even when multiple rows + finally // Ensure that calls to .First() etc progresses the data reader when there are multiple rows { if (index == _gridIndex) { @@ -135,39 +123,43 @@ private IEnumerable SinglePocoFromIDataReader(int index) /// /// Reads data to multiple POCOs. /// - /// The type of objects in the returned . - /// The row to be read from the underlying . + /// The POCO type representing a single result record. + /// The zero-based row index to be read from the underlying . /// An array of types representing the POCO types in the returned result set. - /// A callback function to connect the POCO instances, or to let PetaPoco automatically deduce the relationships. - /// A collection of POCOs as an IEnumerable. - /// - /// - private IEnumerable MultiPocoFromIDataReader(int index, Type[] types, object cb) + /// A callback function to connect the POCO instances, or to let PetaPoco automatically deduce the relationships. + /// A composite POCO of type . + /// Called after the data reader has been disposed. + /// Result records are consumed in the incorrect order, or more than once. + private IEnumerable MultiPocoFromIDataReader(int index, Type[] types, object transformer) { if (_reader == null) throw new ObjectDisposedException(GetType().FullName, "The data reader has been disposed"); if (_consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); + _consumed = true; try { var cmd = _command; - var r = _reader; + var rdr = _reader; + + var factory = MultiPocoFactory.GetFactory(types, cmd.Connection.ConnectionString, cmd.CommandText, rdr, _defaultMapper); + + // if no projector function provided by caller, figure out the split points and connect them ourself + if (transformer == null) + transformer = MultiPocoFactory.GetAutoMapper(types.ToArray()); - var factory = MultiPocoFactory.GetFactory(types, cmd.Connection.ConnectionString, cmd.CommandText, r, _defaultMapper); - if (cb == null) - cb = MultiPocoFactory.GetAutoMapper(types.ToArray()); bool bNeedTerminator = false; while (true) { - TRet poco; + T poco; try { - if (!r.Read()) + if (!rdr.Read()) break; - poco = factory(r, cb); + poco = factory(rdr, transformer); } catch (Exception x) { @@ -184,7 +176,7 @@ private IEnumerable MultiPocoFromIDataReader(int index, Type[] types if (bNeedTerminator) { - var poco = (TRet) (cb as Delegate).DynamicInvoke(new object[types.Length]); + var poco = (T)(transformer as Delegate).DynamicInvoke(new object[types.Length]); if (poco != null) yield return poco; else @@ -200,9 +192,9 @@ private IEnumerable MultiPocoFromIDataReader(int index, Type[] types } } -#endregion + #endregion -#region DataReader Management + #region DataReader Management private int _gridIndex; private bool _consumed; @@ -219,7 +211,7 @@ private void NextResult() } /// - /// Disposes the GridReader, closing and disposing the underlying reader, command, and shared connection. + /// Disposes the GridReader, closing and releasing the underlying , , and shared . /// public void Dispose() { @@ -240,6 +232,6 @@ public void Dispose() _db.CloseSharedConnection(); } -#endregion + #endregion } } diff --git a/PetaPoco/Core/IGridReader.cs b/PetaPoco/Core/IGridReader.cs index 1681dec3..6fe1f84e 100644 --- a/PetaPoco/Core/IGridReader.cs +++ b/PetaPoco/Core/IGridReader.cs @@ -4,22 +4,22 @@ namespace PetaPoco { /// - /// Specifies a set of methods for reading a result set from a database query into an enumerable collection of single or multi-POCO objects. + /// Specifies a set of methods for reading a result set from a database query into a sequence of single or multi-POCO objects. /// public interface IGridReader : IDisposable { - #region ReadSinglePoco + #region Read : Single-POCO /// - /// Performs a read, returning the results as an collection. + /// Reads a sequence of results from a data reader. /// - /// The POCO type representing a row in the result set. - /// An enumerable collection of POCOs containing the result records. + /// The POCO type representing a single result record. + /// An enumerable sequence of results of type . IEnumerable Read(); #endregion - #region ReadMultiPoco : auto-mapping + #region Read with Default Mapping : Multi-POCO /// IEnumerable Read(); @@ -28,36 +28,42 @@ public interface IGridReader : IDisposable IEnumerable Read(); /// - /// Performs a multi-poco read, returning the results as an collection. + /// Reads a sequence of results from a data reader and projects them into a new form of type using a default mapping function. /// - /// The first POCO type. + /// + /// PetaPoco will automatically attempt to determine the split points and auto-map any additional POCO types into . + /// + /// The first POCO type, and the projected POCO type representing a single composite result record. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. - /// An enumerable collection of POCOs containing the result records. + /// An enumerable sequence of results of type . IEnumerable Read(); #endregion - #region ReadMultiPoco : custom-mapping + #region Read with Custom Mapping : Multi-POCO - /// - IEnumerable Read(Func func); + /// + IEnumerable Read(Func projector); - /// - IEnumerable Read(Func func); + /// + IEnumerable Read(Func projector); /// - /// Performs a multi-poco query, returning the results as an collection. + /// Reads a sequence of results from a data reader and projects them into a new form of type using the provided mapping function. /// + /// + /// If is , PetaPoco will automatically attempt to determine the split points and auto-map each POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. - /// The result POCO type. - /// A callback function to used to connect the POCO instances, or to let PetaPoco automatically deduce the relationships. - /// An enumerable collection of POCOs containing the result records. - IEnumerable Read(Func func); + /// The projected POCO type representing a single result record. + /// A function that transforms each of the given types into a . + /// An enumerable sequence of results of type . + IEnumerable Read(Func projector); #endregion } diff --git a/PetaPoco/Core/IProvider.cs b/PetaPoco/Core/IProvider.cs index 9cb47c18..0da45d05 100644 --- a/PetaPoco/Core/IProvider.cs +++ b/PetaPoco/Core/IProvider.cs @@ -69,22 +69,22 @@ public interface IProvider /// /// Performs an Insert operation. /// - /// The calling Database object. + /// The calling Database object. /// The insert command to be executed. /// The primary key of the table being inserted into. /// The ID of the newly inserted record. - object ExecuteInsert(Database database, IDbCommand cmd, string primaryKeyName); + object ExecuteInsert(Database db, IDbCommand cmd, string primaryKeyName); #if ASYNC /// /// Performs an Insert operation asynchronously. /// /// The cancellation token. - /// The calling Database object. + /// The calling Database object. /// The insert command to be executed. /// The primary key of the table being inserted into. /// A task that represents the asynchronous operation. The task result contains the ID of the newly inserted record. - Task ExecuteInsertAsync(CancellationToken cancellationToken, Database database, IDbCommand cmd, string primaryKeyName); + Task ExecuteInsertAsync(CancellationToken cancellationToken, Database db, IDbCommand cmd, string primaryKeyName); #endif /// diff --git a/PetaPoco/Core/ITransaction.cs b/PetaPoco/Core/ITransaction.cs index 838c323d..5cd8b9a3 100644 --- a/PetaPoco/Core/ITransaction.cs +++ b/PetaPoco/Core/ITransaction.cs @@ -6,12 +6,12 @@ namespace PetaPoco /// Represents the contract for the transaction. /// /// - /// A PetaPoco helper to support transactions using the using syntax. + /// A PetaPoco helper to support transactions inside the using block syntax. /// public interface ITransaction : IDisposable, IHideObjectMethods { /// - /// Completes the transaction. Not calling complete will cause the transaction to rollback on . + /// Completes the transaction. /// void Complete(); } diff --git a/PetaPoco/Core/Inflection/IInflector.cs b/PetaPoco/Core/Inflection/IInflector.cs index f07023bd..c8dad772 100644 --- a/PetaPoco/Core/Inflection/IInflector.cs +++ b/PetaPoco/Core/Inflection/IInflector.cs @@ -64,7 +64,7 @@ public interface IInflector string Titleise(string word); /// - /// Humanises the word using "Sentence case" transformation. + /// Humanises the word using "Sentence case" transformation. /// /// /// the_brown_fox => The brown fox diff --git a/PetaPoco/Core/Inflection/Inflector.cs b/PetaPoco/Core/Inflection/Inflector.cs index 38c849bf..71336f89 100644 --- a/PetaPoco/Core/Inflection/Inflector.cs +++ b/PetaPoco/Core/Inflection/Inflector.cs @@ -8,13 +8,14 @@ public static class Inflector private static IInflector _inflector; /// - /// Gets or sets the instance. + /// Gets or sets the instance. + /// Default is . /// /// - /// Set to to restore the default . + /// Set to to restore the default . /// - /// The currently set instance. - /// + /// The currently set instance. + /// public static IInflector Instance { get { return _inflector; } diff --git a/PetaPoco/Core/MultiPocoFactory.cs b/PetaPoco/Core/MultiPocoFactory.cs index cce77042..9052cccc 100644 --- a/PetaPoco/Core/MultiPocoFactory.cs +++ b/PetaPoco/Core/MultiPocoFactory.cs @@ -11,9 +11,11 @@ namespace PetaPoco.Internal internal class MultiPocoFactory { // Various cached stuff - private static readonly Cache, string, string, int>, object> MultiPocoFactories = new Cache, string, string, int>, object>(); + private static readonly Cache, string, string, int>, object> MultiPocoFactories + = new Cache, string, string, int>, object>(); - private static readonly Cache, object> AutoMappers = new Cache, object>(); + private static readonly Cache, object> AutoMappers + = new Cache, object>(); // Instance data used by the Multipoco factory delegate - essentially a list of the nested poco factories to call private List _delegates; @@ -130,7 +132,7 @@ private static Func CreateMultiPocoFactory(Type il.Emit(OpCodes.Callvirt, tDelInvoke); // Poco left on stack } - // By now we should have the callback and the N pocos all on the stack. Call the callback and we're done + // By now we should have the callback and the N pocos all on the stack. Call the callback and we're done il.Emit(OpCodes.Callvirt, Expression.GetFuncType(types.Concat(new[] { typeof(TRet) }).ToArray()).GetMethod("Invoke")); il.Emit(OpCodes.Ret); diff --git a/PetaPoco/Core/Page.cs b/PetaPoco/Core/Page.cs index abbe6157..be33aaf1 100644 --- a/PetaPoco/Core/Page.cs +++ b/PetaPoco/Core/Page.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace PetaPoco { @@ -8,7 +8,7 @@ namespace PetaPoco /// /// Represents a paged result set, both providing access to the items on the current page and maintaining state information about the pagination for additional queries. /// - /// The type of POCO objects in the returned result set. + /// The POCO type representing a single result record. public class Page { /// diff --git a/PetaPoco/Core/PocoData.cs b/PetaPoco/Core/PocoData.cs index a9e9ac31..53137439 100644 --- a/PetaPoco/Core/PocoData.cs +++ b/PetaPoco/Core/PocoData.cs @@ -9,34 +9,66 @@ namespace PetaPoco.Core { + /// + /// Represents the core data structure for PetaPoco's database operations. + /// public class PocoData { + private static readonly object _converterLock = new object(); + private static Cache _pocoDatas = new Cache(); private static List> _converters = new List>(); - private static object _converterLock = new object(); private static MethodInfo fnGetValue = typeof(IDataRecord).GetMethod("GetValue", new Type[] { typeof(int) }); private static MethodInfo fnIsDBNull = typeof(IDataRecord).GetMethod("IsDBNull"); private static FieldInfo fldConverters = typeof(PocoData).GetField("_converters", BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic); private static MethodInfo fnListGetItem = typeof(List>).GetProperty("Item").GetGetMethod(); private static MethodInfo fnInvoke = typeof(Func).GetMethod("Invoke"); private Cache, Delegate> PocoFactories = new Cache, Delegate>(); - public Type Type; - public string[] QueryColumns { get; private set; } - public string[] UpdateColumns - { - // No need to cache as it's not used by PetaPoco internally - get { return (from c in Columns where !c.Value.ResultColumn && c.Value.ColumnName != TableInfo.PrimaryKey select c.Key).ToArray(); } - } + /// + /// Gets or sets the type of the POCO class represented by the PocoData instance. + /// + public Type Type { get; set; } + + /// + /// Gets the array of all queryable database column names used by AutoSelect for query operations when is enabled. + /// + /// + /// Column names are returned unescaped. Escaping should be applied based on the configured if accessing this list to construct an SQL query. To access all + /// Excluded columns include: columns decorated with the , unannotated columns in a POCO marked with the , and any that has opted out of AutoSelect by setting to or through the property. + /// + public string[] QueryColumns { get; private set; } + /// + /// Gets the array of column names used for update operations, excluding result columns and the primary key. + /// + public string[] UpdateColumns // No need to cache as it's not used by PetaPoco internally + => (from c in Columns + where !c.Value.ResultColumn && c.Value.ColumnName != TableInfo.PrimaryKey + select c.Key).ToArray(); + + /// + /// Gets the metadata about the database table associated with the POCO class. + /// public TableInfo TableInfo { get; private set; } + /// + /// Gets the dictionary of Poco Column objects, containing column metadata for the database table mapped to the POCO class. + /// public Dictionary Columns { get; private set; } + /// + /// Initializes a new instance of the PocoData class with default values. + /// public PocoData() { } + /// + /// Initializes a new instance of the PocoData class with the specified type and mapper. + /// + /// The type of the POCO class. + /// The default mapper to use for the POCO class. public PocoData(Type type, IMapper defaultMapper) { Type = type; @@ -70,10 +102,19 @@ public PocoData(Type type, IMapper defaultMapper) Columns.Add(pc.ColumnName, pc); } - // Build column list for automatic select - QueryColumns = (from c in Columns where !c.Value.ResultColumn || c.Value.AutoSelectedResultColumn select c.Key).ToArray(); + // Build column list for AutoSelect queries + QueryColumns = (from c in Columns + where !c.Value.ResultColumn || c.Value.AutoSelectedResultColumn + select c.Key).ToArray(); } + /// + /// Creates a new PocoData instance for the specified class type and mapper. + /// + /// The type to create a PocoData instance for. + /// The default mapper to use for the type. + /// A new PocoData instance for the specified type. + /// Trying to use dynamic types with this method. public static PocoData ForType(Type type, IMapper defaultMapper) { if (type == typeof(System.Dynamic.ExpandoObject)) @@ -82,6 +123,13 @@ public static PocoData ForType(Type type, IMapper defaultMapper) return _pocoDatas.GetOrAdd(type, () => new PocoData(type, defaultMapper)); } + /// + /// Creates a new PocoData instance for the specified object, specifically a . + /// + /// The object to create a PocoData instance for. + /// The name of the primary key for the object. + /// The default mapper to use for the object. + /// A new PocoData instance for the specified object. public static PocoData ForObject(object obj, string primaryKeyName, IMapper defaultMapper) { var t = obj.GetType(); @@ -105,22 +153,33 @@ public static PocoData ForObject(object obj, string primaryKeyName, IMapper defa return ForType(t, defaultMapper); } - // Create factory function that can convert a IDataReader record into a POCO + /// + /// Creates a factory function to generate and cache a POCO from a data reader record at runtime. Subsequent reads attempt to locate the object in the for performance gains. + /// + /// The SQL statement used to generate the record. + /// The connection string used to connect to the database. + /// The index of the first column in the record. + /// The number of columns in the record. + /// The data reader instance containing the record. + /// The default mapper to use for the POCO. + /// A delegate that can convert an record into a POCO. + /// The POCO type is a value type, or the POCO type has no default constructor, or the POCO type is an interface or abstract class. public Delegate GetFactory(string sql, string connectionString, int firstColumn, int countColumns, IDataReader reader, IMapper defaultMapper) { - // Check cache - var key = Tuple.Create(sql, connectionString, firstColumn, countColumns); + // Create key for cache lookup + var key = Tuple.Create(sql, connectionString, firstColumn, countColumns); + // Check cache return PocoFactories.GetOrAdd(key, () => { // Create the method - var m = new DynamicMethod("petapoco_factory_" + PocoFactories.Count.ToString(), Type, new Type[] { typeof(IDataReader) }, true); + var m = new DynamicMethod("petapoco_factory_" + PocoFactories.Count.ToString(), returnType: Type, new Type[] { typeof(IDataReader) }, true); var il = m.GetILGenerator(); var mapper = Mappers.GetMapper(Type, defaultMapper); if (Type == typeof(object)) { - // var poco=new T() + // var poco = new T() il.Emit(OpCodes.Newobj, typeof(System.Dynamic.ExpandoObject).GetConstructor(Type.EmptyTypes)); // obj MethodInfo fnAdd = typeof(IDictionary).GetMethod("Add"); @@ -134,12 +193,10 @@ public Delegate GetFactory(string sql, string connectionString, int firstColumn, il.Emit(OpCodes.Ldstr, reader.GetName(i)); // obj, obj, fieldname // Get the converter - Func converter = mapper.GetFromDbConverter((PropertyInfo) null, srcType); + Func converter = mapper.GetFromDbConverter((PropertyInfo)null, srcType); - /* - if (ForceDateTimesToUtc && converter == null && srcType == typeof(DateTime)) - converter = delegate(object src) { return new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc); }; - */ + // if (ForceDateTimesToUtc && converter == null && srcType == typeof(DateTime)) + // converter = delegate(object src) { return new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc); }; // Setup stack for call to converter AddConverterToStack(il, converter); @@ -208,14 +265,14 @@ public Delegate GetFactory(string sql, string connectionString, int firstColumn, } else { - // var poco=new T() + // var poco = new T() var ctor = Type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null); if (ctor == null) throw new InvalidOperationException("Type [" + Type.FullName + "] should have default public or non-public constructor"); il.Emit(OpCodes.Newobj, ctor); - // Enumerate all fields generating a set assignment for the column + // Enumerate all fields generating a `Set` assignment for the column for (int i = firstColumn; i < firstColumn + countColumns; i++) { // Get the PocoColumn for this db column, ignore if not known @@ -340,7 +397,7 @@ private static Func GetConverter(IMapper mapper, PocoColumn pc, // Standard DateTime->Utc mapper if (pc != null && pc.ForceToUtc && srcType == typeof(DateTime) && (dstType == typeof(DateTime) || dstType == typeof(DateTime?))) { - return delegate(object src) { return new DateTime(((DateTime) src).Ticks, DateTimeKind.Utc); }; + return delegate (object src) { return new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc); }; } // unwrap nullable types @@ -357,31 +414,31 @@ private static Func GetConverter(IMapper mapper, PocoColumn pc, if (underlyingDstType != null) { // if dstType is Nullable, convert to enum value - return delegate(object src) { return Enum.ToObject(dstType, src); }; + return delegate (object src) { return Enum.ToObject(dstType, src); }; } else if (srcType != backingDstType) { - return delegate(object src) { return Convert.ChangeType(src, backingDstType, null); }; + return delegate (object src) { return Convert.ChangeType(src, backingDstType, null); }; } } else if (!dstType.IsAssignableFrom(srcType)) { if (dstType.IsEnum && srcType == typeof(string)) { - return delegate(object src) { return EnumMapper.EnumFromString(dstType, (string) src); }; + return delegate (object src) { return EnumMapper.EnumFromString(dstType, (string)src); }; } if (dstType == typeof(Guid) && srcType == typeof(string)) { - return delegate(object src) { return Guid.Parse((string) src); }; + return delegate (object src) { return Guid.Parse((string)src); }; } if (dstType == typeof(string) && srcType == typeof(Guid)) { - return delegate(object src) { return Convert.ToString(src); }; + return delegate (object src) { return Convert.ToString(src); }; } - return delegate(object src) { return Convert.ChangeType(src, dstType, null); }; + return delegate (object src) { return Convert.ChangeType(src, dstType, null); }; } return null; @@ -406,12 +463,22 @@ private static T RecurseInheritedTypes(Type t, Func cb) return default(T); } + /// + /// Clears all cached PocoData instances. + /// + /// + /// Call if you have modified a POCO class and need to reset the PetaPoco's internal cache. + /// public static void FlushCaches() => _pocoDatas.Flush(); + /// + /// Gets the column name that is mapped to the given property name using a string comparison. + /// + /// The name of the property. + /// The column name that maps to the given property name. + /// No mapped column exists for . public string GetColumnName(string propertyName) - { - return Columns.Values.First(c => c.PropertyInfo.Name.Equals(propertyName)).ColumnName; - } + => Columns.Values.First(c => c.PropertyInfo.Name.Equals(propertyName)).ColumnName; } } diff --git a/PetaPoco/Core/Sql.cs b/PetaPoco/Core/Sql.cs index 05c0f5d0..af6cc9bd 100644 --- a/PetaPoco/Core/Sql.cs +++ b/PetaPoco/Core/Sql.cs @@ -9,6 +9,9 @@ namespace PetaPoco /// /// A simple helper class for building SQL statements. /// + /// + /// In the current form, this Sql builder is not immutable; appending to an instance will result in mutations to the object's internal state, which can result in UEB if reusing a cached instance (#639). + /// public class Sql { private object[] _args; @@ -19,10 +22,11 @@ public class Sql private string _sqlFinal; /// - /// Instantiates a new SQL Builder object. + /// Initializes a new instance of the builder class. /// /// - /// Weirdly implemented as a property, but makes for more elegant and readable fluent-style construction of SQL Statements, eg: db.Query(Sql.Builder.Append(/*...*/));. + /// Weirdly implemented as a property, but makes for more elegant and readable fluent-style construction of SQL Statements: + ///
db.Query(Sql.Builder.Append(/*...*/));. ///
public static Sql Builder { @@ -30,7 +34,7 @@ public static Sql Builder } /// - /// Returns the final SQL statement stored in this this builder. + /// Gets the final SQL statement stored in this builder. /// public string SQL { @@ -54,7 +58,7 @@ public object[] Arguments } /// - /// Initializes a new default builder. + /// Initializes a new instance of the builder class with default values. /// public Sql() { @@ -63,8 +67,8 @@ public Sql() /// /// Construct an SQL statement from the given SQL string and arguments. /// - /// The SQL statement or fragment. - /// Arguments to any parameters embedded in string. + /// The SQL statement or fragment string. + /// The parameters to pass to the SQL string. public Sql(string sql, params object[] args) { _sql = sql; @@ -86,9 +90,9 @@ private void Build() } /// - /// Append another SQL builder instance to the right-hand-side of this SQL builder. + /// Appends another Sql builder instance to the right-hand-side of this Sql builder. /// - /// A reference to another SQL builder instance. + /// A reference to another Sql builder instance. /// A reference to this builder, allowing for fluent style concatenation. public Sql Append(Sql sql) { @@ -102,10 +106,10 @@ public Sql Append(Sql sql) } /// - /// Append an SQL fragment to the right-hand-side of this SQL builder instance. + /// Appends an SQL fragment to the right-hand-side of this Sql builder instance. /// - /// The SQL statement or fragment. - /// Arguments to any parameters embedded in the SQL. + /// The SQL statement or fragment string. + /// The parameters to pass to the SQL string. /// A reference to this builder, allowing for fluent style concatenation. public Sql Append(string sql, params object[] args) { @@ -146,10 +150,10 @@ private void Build(StringBuilder sb, List args, Sql lhs) } /// - /// Appends an SQL SET clause to this SQL builder. + /// Appends a SET clause to this Sql builder. /// /// The SET clause: {field} = {value}. - /// Arguments to any parameters embedded in the supplied SQL. + /// The parameters to pass to the SQL string. /// A reference to this builder, allowing for fluent style concatenation. public Sql Set(string sql, params object[] args) { @@ -157,10 +161,10 @@ public Sql Set(string sql, params object[] args) } /// - /// Appends an SQL WHERE clause to this SQL builder. + /// Appends a WHERE clause to this Sql builder. /// - /// The condition of the WHERE clause. - /// Arguments to any parameters embedded in the supplied SQL. + /// The SQL condition string of the WHERE clause. + /// The parameters to pass to the SQL string. /// A reference to this builder, allowing for fluent style concatenation. public Sql Where(string sql, params object[] args) { @@ -168,7 +172,7 @@ public Sql Where(string sql, params object[] args) } /// - /// Appends an SQL ORDER BY clause to this SQL builder. + /// Appends an ORDER BY clause to this Sql builder. /// /// A collection of SQL column names to order by. /// A reference to this builder, allowing for fluent style concatenation. @@ -178,9 +182,9 @@ public Sql OrderBy(params object[] columns) } /// - /// Appends an SQL SELECT clause to this SQL builder. + /// Appends a SELECT clause to this Sql builder. /// - /// A collection of SQL column names to select. + /// A collection of SQL column names to include in the SELECT clause. /// A reference to this builder, allowing for fluent style concatenation. public Sql Select(params object[] columns) { @@ -188,9 +192,9 @@ public Sql Select(params object[] columns) } /// - /// Appends an SQL FROM clause to this SQL builder. + /// Appends a FROM clause to this Sql builder. /// - /// A collection of table names to be used in the FROM clause. + /// A collection of table names to include in the FROM clause. /// A reference to this builder, allowing for fluent style concatenation. public Sql From(params object[] tables) { @@ -198,7 +202,7 @@ public Sql From(params object[] tables) } /// - /// Appends an SQL GROUP BY clause to this SQL builder. + /// Appends a GROUP BY clause to this Sql builder. /// /// A collection of column names to be grouped by. /// A reference to this builder, allowing for fluent style concatenation. @@ -213,20 +217,20 @@ private SqlJoinClause Join(string joinType, string table) } /// - /// Appends an SQL INNER JOIN clause to this SQL builder. + /// Appends an INNER JOIN clause to this Sql builder. /// /// The name of the table to join. - /// A reference an SqlJoinClause through which the join condition can be specified. + /// A reference an SqlJoinClause through which the JOIN condition can be specified. public SqlJoinClause InnerJoin(string table) { return Join("INNER JOIN ", table); } /// - /// Appends an SQL LEFT JOIN clause to this SQL builder. + /// Appends a LEFT JOIN clause to this Sql builder. /// /// The name of the table to join. - /// A reference an SqlJoinClause through which the join condition can be specified. + /// A reference an SqlJoinClause through which the JOIN condition can be specified. public SqlJoinClause LeftJoin(string table) { return Join("LEFT JOIN ", table); @@ -244,23 +248,27 @@ public override string ToString() } /// - /// The SqlJoinClause is a simple helper class used in the construction of SQL JOIN statements with the SQL builder. + /// The SqlJoinClause is a simple helper class used in the construction of JOIN statements with the Sql builder. /// public class SqlJoinClause { private readonly Sql _sql; + /// + /// Constructs a JOIN statement from the given builder. + /// + /// The builder. public SqlJoinClause(Sql sql) { _sql = sql; } /// - /// Appends an SQL ON clause after a JOIN statement. + /// Appends an ON clause after a JOIN statement. /// /// The ON clause to be appended. - /// Arguments to any parameters embedded in the supplied SQL. - /// A reference to the parent SQL builder, allowing for fluent style concatenation. + /// The parameters to pass to the SQL string. + /// A reference to the parent Sql builder, allowing for fluent style concatenation. public Sql On(string onClause, params object[] args) { return _sql.Append("ON " + onClause, args); diff --git a/PetaPoco/Core/TableInfo.cs b/PetaPoco/Core/TableInfo.cs index 93386d83..99ad8958 100644 --- a/PetaPoco/Core/TableInfo.cs +++ b/PetaPoco/Core/TableInfo.cs @@ -15,12 +15,12 @@ public class TableInfo public string TableName { get; set; } /// - /// Gets or sets the name of the primary key column of the table. + /// Gets or sets the name of the table's primary key column. /// public string PrimaryKey { get; set; } /// - /// Gets or sets whether the primary key column is an auto-incrementing. + /// Gets or sets whether the primary key column is auto-incrementing. /// public bool AutoIncrement { get; set; } @@ -30,7 +30,7 @@ public class TableInfo public string SequenceName { get; set; } /// - /// Constructs and initializes a TableInfo instance from the attributes of a POCO. + /// Constructs and initializes a TableInfo instance from the attributes of the specified POCO type. /// /// The POCO type. /// The TableInfo instance. diff --git a/PetaPoco/Database.cs b/PetaPoco/Database.cs index 40c2870e..c149f3af 100644 --- a/PetaPoco/Database.cs +++ b/PetaPoco/Database.cs @@ -853,7 +853,7 @@ protected virtual async Task ExecuteScalarInternalAsync(CancellationToken #endregion - #region Query, QueryAsync : Single-Poco + #region Query, QueryAsync : Single-POCO /// public IEnumerable Query() @@ -1139,7 +1139,7 @@ protected virtual async Task ExecuteReaderAsync(Action action, Cancellatio #endregion - #region Query : Multi-Poco + #region Query : Multi-POCO /// public IEnumerable Query(Sql sql) @@ -1303,7 +1303,7 @@ public IGridReader QueryMultiple(string sql, params object[] args) #endregion - #region Fetch, FetchAsync : Single-Poco + #region Fetch, FetchAsync : Single-POCO /// public List Fetch() @@ -1374,7 +1374,7 @@ public async Task> FetchAsync(CancellationToken cancellationToken, Co #endregion - #region Fetch : Multi-Poco + #region Fetch : Multi-POCO /// public List Fetch(Sql sql) diff --git a/PetaPoco/DatabaseConfigurationExtensions.cs b/PetaPoco/DatabaseConfigurationExtensions.cs index 5fa286ea..b84c7bce 100644 --- a/PetaPoco/DatabaseConfigurationExtensions.cs +++ b/PetaPoco/DatabaseConfigurationExtensions.cs @@ -34,18 +34,18 @@ public static class DatabaseConfigurationExtensions private static void SetSetting(this IDatabaseBuildConfiguration source, string key, object value) { - ((IBuildConfigurationSettings) source).SetSetting(key, value); + ((IBuildConfigurationSettings)source).SetSetting(key, value); } #region Timeout Settings /// - /// Adds a command timeout - see . + /// Sets to the specified value. /// /// The configuration source. /// The timeout in seconds. /// The original configuration, to form a fluent interface. - /// Thrown when seconds is less than 1. + /// is less than 1. public static IDatabaseBuildConfiguration UsingCommandTimeout(this IDatabaseBuildConfiguration source, int seconds) { if (seconds < 1) @@ -59,7 +59,7 @@ public static IDatabaseBuildConfiguration UsingCommandTimeout(this IDatabaseBuil #region AutoSelect Settings /// - /// Enables auto select . + /// Enables AutoSelect, equivalent to setting to . /// /// The configuration source. /// The original configuration, to form a fluent interface. @@ -70,7 +70,7 @@ public static IDatabaseBuildConfiguration WithAutoSelect(this IDatabaseBuildConf } /// - /// Disables auto select - see . + /// Disables AutoSelect, equivalent to setting to . /// /// The configuration source. /// The original configuration, to form a fluent interface. @@ -85,7 +85,7 @@ public static IDatabaseBuildConfiguration WithoutAutoSelect(this IDatabaseBuildC #region NamedParams Settings /// - /// Enables named params - see . + /// Enables NamedParams, equivalent to setting to . /// /// The configuration source. /// The original configuration, to form a fluent interface. @@ -96,7 +96,7 @@ public static IDatabaseBuildConfiguration WithNamedParams(this IDatabaseBuildCon } /// - /// Disables named params - see . + /// Disables NamedParams, equivalent to setting to . /// /// The configuration source. /// The original configuration, to form a fluent interface. @@ -112,12 +112,15 @@ public static IDatabaseBuildConfiguration WithoutNamedParams(this IDatabaseBuild #if !NETSTANDARD /// - /// Adds a connection string name. + /// Specifies a connection string name to be used to locate a connection string. The and will be read from the app or web configuration file. /// + /// + /// PetaPoco will automatically close and dispose of any connections it creates. + /// /// The configuration source. - /// The connection string name. + /// The name of the connection. /// The original configuration, to form a fluent interface. - /// Thrown when is null or empty. + /// is null or empty. public static IDatabaseBuildConfiguration UsingConnectionStringName(this IDatabaseBuildConfiguration source, string connectionStringName) { if (string.IsNullOrEmpty(connectionStringName)) @@ -128,12 +131,15 @@ public static IDatabaseBuildConfiguration UsingConnectionStringName(this IDataba #endif /// - /// Adds a connection string - see . + /// Specifies the to use. /// + /// + /// PetaPoco will automatically close and dispose of any connections it creates. + /// /// The configuration source. /// The connection string. /// The original configuration, to form a fluent interface. - /// Thrown when is null or empty. + /// is null or empty. public static IDatabaseBuildConfiguration UsingConnectionString(this IDatabaseBuildConfiguration source, string connectionString) { if (string.IsNullOrEmpty(connectionString)) @@ -143,16 +149,19 @@ public static IDatabaseBuildConfiguration UsingConnectionString(this IDatabaseBu } /// - /// Specifies an to use. + /// Specifies an to use. /// + /// + /// The supplied IDbConnection will not be closed and disposed of by PetaPoco - that remains the responsibility of the caller. + /// /// The configuration source. /// The connection to use. /// The original configuration, to form a fluent interface. + /// is . public static IDatabaseBuildConfiguration UsingConnection(this IDatabaseBuildConfiguration source, IDbConnection connection) { if (connection == null) throw new ArgumentNullException(nameof(connection)); - source.SetSetting(Connection, connection); return source; } @@ -162,12 +171,12 @@ public static IDatabaseBuildConfiguration UsingConnection(this IDatabaseBuildCon #region Provider Settings /// - /// Adds a provider name string - see . + /// Specifies a provider name to be used when resolving the . /// /// The configuration source. /// The provider name. /// The original configuration, to form a fluent interface. - /// Thrown when is null or empty. + /// is null or empty. public static IDatabaseBuildConfiguration UsingProviderName(this IDatabaseBuildConfiguration source, string providerName) { if (string.IsNullOrEmpty(providerName)) @@ -177,43 +186,56 @@ public static IDatabaseBuildConfiguration UsingProviderName(this IDatabaseBuildC } /// - /// Specifies the provider to be used. - see . This takes precedence over . + /// Specifies the to be used. /// - /// The provider type. + /// + /// This takes precedence over . + /// + /// The provider type. /// The configuration source. /// The original configuration, to form a fluent interface. - public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source) where T : class, IProvider, new() + public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source) + where TProvider : class, IProvider, new() { - source.SetSetting(Provider, new T()); + source.SetSetting(Provider, new TProvider()); return source; } /// - /// Specifies the to use, with an accompanying configuration provider custom callback. + /// Specifies the to use, with an accompanying configuration provider callback action. /// - /// The provider type, constrained to a class deriving from . + /// + /// This takes precedence over . + /// + /// The provider type, constrained to a class deriving from . /// The configuration source. - /// The configure provider callback. + /// The configure provider callback. /// The original configuration, to form a fluent interface. - /// Thrown when is null. - public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source, Action configure) where T : class, IProvider, new() + /// is . + public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source, Action configurer) + where TProvider : class, IProvider, new() { - if (configure == null) - throw new ArgumentNullException(nameof(configure)); - var provider = new T(); - configure(provider); + if (configurer == null) + throw new ArgumentNullException(nameof(configurer)); + var provider = new TProvider(); + configurer(provider); source.SetSetting(Provider, provider); return source; } /// - /// Specifies the provider to be used. - see . This takes precedence over . + /// Specifies the to be used. /// + /// + /// This takes precedence over . + /// + /// The provider type. /// The configuration source. /// The provider to use. /// The original configuration, to form a fluent interface. - /// Thrown when is null. - public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source, T provider) where T : class, IProvider + /// is . + public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source, TProvider provider) + where TProvider : class, IProvider { if (provider == null) throw new ArgumentNullException(nameof(provider)); @@ -222,22 +244,25 @@ public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildCo } /// - /// Specifies the provider to be used. - see . This takes precedence over . + /// Specifies the to use, with an accompanying configuration provider callback action. /// - /// The provider type. + /// + /// This takes precedence over . + /// + /// The provider type. /// The configuration source. - /// The configure provider callback. + /// The configure provider callback action. /// The provider to use. /// The original configuration, to form a fluent interface. - /// Thrown when is null. - /// Thrown when is null. - public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source, T provider, Action configure) where T : class, IProvider + /// or is . + public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildConfiguration source, TProvider provider, Action configurer) + where TProvider : class, IProvider { if (provider == null) throw new ArgumentNullException(nameof(provider)); - if (configure == null) - throw new ArgumentNullException(nameof(configure)); - configure(provider); + if (configurer == null) + throw new ArgumentNullException(nameof(configurer)); + configurer(provider); source.SetSetting(Provider, provider); return source; } @@ -247,43 +272,47 @@ public static IDatabaseBuildConfiguration UsingProvider(this IDatabaseBuildCo #region Mapper Settings /// - /// Specifies the default mapper to use when no specific mapper has been registered. + /// Specifies the to use when no specific mapper has been registered. /// - /// The mapper type. + /// The mapper type. /// The configuration source. /// The original configuration, to form a fluent interface. - public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source) where T : class, IMapper, new() + public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source) + where TMapper : class, IMapper, new() { - source.SetSetting(DefaultMapper, new T()); + source.SetSetting(DefaultMapper, new TMapper()); return source; } /// - /// Specifies the default mapper to use when no specific mapper has been registered. + /// Specifies the to use when no specific mapper has been registered, with an accompanying configuration mapper callback action. /// - /// The type of the mapper. This type must be a class that implements the interface. + /// The type of the mapper. This type must be a class that implements the interface. /// The configuration source. - /// A callback function to configure the mapper. + /// A callback function to configure the mapper. /// The original configuration, to form a fluent interface. - /// Thrown if the callback function is null. - public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source, Action configure) where T : class, IMapper, new() + /// If the callback action is . + public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source, Action configurer) + where TMapper : class, IMapper, new() { - if (configure == null) - throw new ArgumentNullException(nameof(configure)); - var mapper = new T(); - configure(mapper); + if (configurer == null) + throw new ArgumentNullException(nameof(configurer)); + var mapper = new TMapper(); + configurer(mapper); source.SetSetting(DefaultMapper, mapper); return source; } /// - /// Specifies the default mapper to use when no specific mapper has been registered. + /// Specifies the to use when no specific mapper has been registered. /// + /// The type of the mapper. This type must be a class that implements the interface. /// The configuration source. /// The mapper to use as the default. /// The original configuration, to form a fluent interface. - /// Thrown when is null. - public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source, T mapper) where T : class, IMapper + /// is . + public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source, TMapper mapper) + where TMapper : class, IMapper { if (mapper == null) throw new ArgumentNullException(nameof(mapper)); @@ -292,21 +321,22 @@ public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBu } /// - /// Specifies the default mapper to use when no specific mapper has been registered. + /// Specifies the to use when no specific mapper has been registered, with an accompanying configuration mapper callback action. /// + /// The type of the mapper. This type must be a class that implements the interface. /// The configuration source. /// The mapper to use as the default. - /// The configure mapper callback. + /// The configure mapper callback. /// The original configuration, to form a fluent interface. - /// Thrown when is null. - /// Thrown when is null. - public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source, T mapper, Action configure) where T : class, IMapper + /// or is . + public static IDatabaseBuildConfiguration UsingDefaultMapper(this IDatabaseBuildConfiguration source, TMapper mapper, Action configurer) + where TMapper : class, IMapper { if (mapper == null) throw new ArgumentNullException(nameof(mapper)); - if (configure == null) - throw new ArgumentNullException(nameof(configure)); - configure(mapper); + if (configurer == null) + throw new ArgumentNullException(nameof(configurer)); + configurer(mapper); source.SetSetting(DefaultMapper, mapper); return source; } @@ -380,7 +410,7 @@ public static IDatabaseBuildConfiguration UsingCommandExecuted(this IDatabaseBui } /// - /// Specifies an event handler to use before a connection is opened. + /// Specifies an event handler to use when a connection is about to be opened. /// /// The configuration source. /// A callback function for handling events. diff --git a/PetaPoco/IAlterPoco.cs b/PetaPoco/IAlterPoco.cs index 30240182..83789970 100644 --- a/PetaPoco/IAlterPoco.cs +++ b/PetaPoco/IAlterPoco.cs @@ -2,48 +2,42 @@ namespace PetaPoco { + /// + /// Specifies a set of methods for performing SQL operations on POCOs such as Insert, Update, Delete, and Save. + /// public interface IAlterPoco { #region Insert /// - /// Performs an SQL Insert. + /// Inserts a new record and returns the primary key of the newly inserted record. /// - /// - /// The name of the table, its primary key and whether it's an auto-allocated primary key are retrieved from the POCO's attributes - /// - /// A POCO object containing the column values to be inserted. - /// The auto allocated primary key of the new record, or for non-auto-increment tables. + /// object Insert(object poco); - /// - /// Performs an SQL Insert. - /// - /// The name of the table to insert into. - /// A POCO object containing the column values to be inserted. - /// The auto allocated primary key of the new record, or for non-auto-increment tables. + /// + /// If a mapped primary key column is auto-incrementing and is , the primary key property of the POCO will be updated with the new record's auto-incremented ID. + /// + /// object Insert(string tableName, object poco); - /// - /// Performs an SQL Insert. - /// - /// The name of the table to insert into. - /// The name of the primary key column of the table. - /// A POCO object containing the column values to be inserted. - /// The auto allocated primary key of the new record, or for non-auto-increment tables. + /// + /// If represents an auto-incrementing column and is , the primary key property of the POCO will be updated with the new record's auto-incremented ID. + /// + /// object Insert(string tableName, string primaryKeyName, object poco); /// - /// Performs an SQL Insert. + /// Inserts a new record into the specified table and returns the primary key of the newly inserted record. /// /// - /// Inserts a POCO into a table. If the POCO has a property with the same name as the primary key, the id of the new record is assigned to it. Either way, the new id is returned. + /// If is , the primary key property of the POCO will be updated with the new record's auto-incremented ID. /// - /// The name of the table to insert into. - /// The name of the primary key column of the table. - /// if the primary key is automatically allocated by the DB. - /// A POCO object containing the column values to be inserted. - /// The auto allocated primary key of the new record, or for non-auto-increment tables. + /// The name of the table where the record will be inserted. + /// The name of the primary key column in the table. + /// Indicates whether the primary key column in the database is auto-incrementing. + /// The POCO instance to insert. + /// The primary key of the new record if the table has a primary key column; otherwise, . object Insert(string tableName, string primaryKeyName, bool autoIncrement, object poco); #endregion @@ -51,92 +45,73 @@ public interface IAlterPoco #region Update /// - /// Performs an SQL update. + /// Updates a record and returns the number of rows affected by the update operation. /// - /// A POCO object containing the column values to be updated. - /// The number of affected rows. + /// int Update(object poco); /// - /// Performs an SQL update. + /// Updates the specified columns of a record and returns the number of rows affected by the update operation. /// - /// A POCO object containing the column values to be updated. - /// The column names of the columns to be updated, or for all. - /// The number of affected rows. + /// int Update(object poco, IEnumerable columns); /// - /// Performs an SQL update. + /// Updates a record with the given ID and returns the number of rows affected by the update operation. /// - /// A POCO object containing the column values to be updated. - /// The primary key of the record to be updated. - /// The number of affected rows. + /// int Update(object poco, object primaryKeyValue); /// - /// Performs an SQL update. + /// Updates the specified columns of a record with the given ID and returns the number of rows affected by the update operation. /// - /// A POCO object containing the column values to be updated. - /// The primary key of the record to be updated. - /// The column names of the columns to be updated, or for all. - /// The number of affected rows. + /// int Update(object poco, object primaryKeyValue, IEnumerable columns); /// - /// Performs an SQL update. + /// Updates a record in the provided table and returns the number of rows affected by the update operation. /// - /// The name of the table to update. - /// The name of the primary key column of the table. - /// A POCO object containing the column values to be updated. - /// The number of affected rows. + /// int Update(string tableName, string primaryKeyName, object poco); /// - /// Performs an SQL update. + /// Updates the specified columns of a record in the provided table and returns the number of rows affected by the update operation. /// - /// The name of the table to update. - /// The name of the primary key column of the table. - /// A POCO object containing the column values to be updated. - /// The column names of the columns to be updated, or for all. - /// The number of affected rows. + /// int Update(string tableName, string primaryKeyName, object poco, IEnumerable columns); /// - /// Performs an SQL update. + /// Updates a record with the given ID in the provided table and returns the number of rows affected by the update operation. /// - /// The name of the table to update. - /// The name of the primary key column of the table. - /// A POCO object containing the column values to be updated. - /// The primary key of the record to be updated. - /// The number of affected records. + /// int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue); /// - /// Performs an SQL update. + /// Updates the specified columns of a record with the given ID in the provided table and returns the number of rows affected by the update operation. /// /// The name of the table to update. - /// The name of the primary key column of the table. - /// A POCO object containing the column values to be updated. - /// The primary key of the record to be updated. - /// The column names of the columns to be updated, or for all. - /// The number of affected rows. + /// The name of the primary key column in the table. + /// The POCO instance containing the column values to update. + /// The primary key value identifying the record to update. + /// A list of column names to update, or to update all columns. + /// The number of rows affected by the update operation. int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable columns); /// - /// Performs an SQL update. + /// Executes an SQL update and returns the number of rows affected by the update operation. /// - /// The POCO class whose attributes specify the name of the table to update. - /// An SQL builder object representing the SQL update and condition clause (everything after UPDATE tablename). - /// The number of affected rows. + /// The POCO type associated with the table to update. + /// An SQL builder object representing the SQL update and condition clause (everything after UPDATE tablename), and its parameters. + /// The number of rows affected by the update operation. int Update(Sql sql); /// - /// Performs an SQL update. + /// Executes an SQL update and returns the number of rows affected by the update operation. /// - /// The POCO class whose attributes specify the name of the table to update. - /// The SQL update and condition clause (everything after UPDATE tablename). - /// Arguments to any embedded parameters in the SQL. - /// The number of affected rows. + /// The POCO type associated with the table to update. + /// The SQL string containing the update and condition clause (everything after UPDATE tablename). + /// The parameters to pass to the SQL string. + /// The number of rows affected by the update operation. int Update(string sql, params object[] args); #endregion @@ -144,98 +119,97 @@ public interface IAlterPoco #region Delete /// - /// Performs an SQL Delete. + /// Deletes a record and returns the number of rows affected by the update operation. /// - /// A POCO object specifying the table name and primary key value of the row to be deleted. - /// The number of rows affected. + /// A POCO instance representing the record to delete. + /// The number of rows affected by the delete operation. int Delete(object poco); /// - /// Performs an SQL Delete. + /// Deletes a record in the provided table and returns the number of rows affected by the update operation. /// - /// The name of the table to delete from. + /// The name of the table containing the record to delete. /// The name of the primary key column. - /// A POCO object whose primary key value will be used to delete the row. - /// The number of rows affected. + /// The POCO instance representing the record to delete. + /// The number of rows affected by the delete operation. int Delete(string tableName, string primaryKeyName, object poco); /// - /// Performs an SQL Delete. + /// Deletes a record with the given ID in the provided table and returns the number of rows affected by the update operation. /// - /// The name of the table to delete from. - /// The name of the primary key column. - /// A POCO object whose primary key value will be used to delete the row, or to use the supplied primary key value. - /// The value of the primary key identifying the record to be deleted. If , the primary key will be obtained from the provided . - /// The number of rows affected. + /// The name of the table containing the record to delete. + /// The name of the primary key column in the table. + /// The POCO instance representing the record to delete, or to use a provided . + /// The primary key value of the record to delete, used if is . + /// The number of rows affected by the delete operation. int Delete(string tableName, string primaryKeyName, object poco, object primaryKeyValue); /// - /// Performs an SQL Delete. + /// Deletes a record and returns the number of rows affected by the update operation. /// - /// The POCO class whose attributes identify the table and primary key to be used in the delete. - /// The value of the primary key of the row to delete. - /// The number of affected rows. + /// The POCO type associated with the table to delete. + /// Either a POCO instance representing the record to delete, or the primary key of the record. + /// The number of rows affected by the delete operation. int Delete(object pocoOrPrimaryKey); /// - /// Performs an SQL Delete. + /// Executes an SQL delete and returns the number of rows affected by the delete operation. /// - /// The POCO class whose attributes specify the name of the table to delete from. - /// An SQL builder object representing the SQL condition clause identifying the row to delete (everything after DELETE FROM tablename). - /// The number of affected rows. + /// The POCO type associated with the table to delete. + /// An SQL builder object representing the SQL condition clause identifying the row to delete (everything after DELETE FROM tablename), and its parameters. + /// The number of rows affected by the delete operation. int Delete(Sql sql); /// - /// Performs an SQL Delete. + /// Executes an SQL delete and returns the number of rows affected by the delete operation. /// - /// The POCO class whose attributes specify the name of the table to delete from. - /// The SQL condition clause identifying the row to delete (everything after DELETE FROM tablename). - /// Arguments to any embedded parameters in the SQL. - /// The number of affected rows. + /// The POCO type associated with the table to delete. + /// The SQL string containing the condition clause identifying the row to delete (everything after DELETE FROM tablename). + /// The parameters to pass to the SQL string. + /// The number of rows affected by the delete operation. int Delete(string sql, params object[] args); #endregion #region IsNew - /// - /// Checks if a poco represents a new row. - /// - /// - /// This method simply tests if the POCO's primary key column property has a non-default value. - /// - /// The object instance whose "newness" is to be tested. - /// if the POCO represents a record already in the database. + /// + /// A POCO instance is considered "new" if the property that maps to the associated table's primary key column contains a default value. + /// + /// bool IsNew(object poco); - /// - /// Checks if a poco represents a new row. - /// - /// - /// This method simply tests if the POCO's primary key column property has a non-default value. - /// - /// The name of the primary key column. - /// The object instance whose "newness" is to be tested. - /// if the POCO represents a record already in the database. + /// + /// Determines whether the specified POCO represents a new record that has not yet been saved to the database. + /// + /// + /// A POCO instance is considered "new" if the property that maps to the associated table's provided column name contains a default value. + /// + /// The name of the primary key column. + /// The POCO instance to check. + /// if the POCO represents a new record; otherwise, . bool IsNew(string primaryKeyName, object poco); #endregion #region Save - /// - /// Saves a POCO by performing either an INSERT or UPDATE operation. - /// - /// The POCO object to be saved. + /// + /// Performs an INSERT operation if the POCO is new (as determined by ), and an UPDATE operation otherwise. + /// + /// void Save(object poco); - /// - /// Saves a POCO by performing either an INSERT or UPDATE operation. - /// - /// The name of the table to be updated. - /// The name of the primary key column. - /// The POCO object to be saved. - void Save(string tableName, string primaryKeyName, object poco); + /// + /// Saves the specified POCO to the database by performing either an insert or an update operation, as appropriate. + /// + /// + /// Performs an INSERT operation if the POCO is new (as determined by ), and an UPDATE operation otherwise. + /// + /// The name of the table where the POCO will be saved. + /// The name of the primary key column in the table. + /// The POCO instance to save. + void Save(string tableName, string primaryKeyName, object poco); #endregion } diff --git a/PetaPoco/IAlterPocoAsync.cs b/PetaPoco/IAlterPocoAsync.cs index 6e1f98c0..8cccfc81 100644 --- a/PetaPoco/IAlterPocoAsync.cs +++ b/PetaPoco/IAlterPocoAsync.cs @@ -4,242 +4,274 @@ namespace PetaPoco { +#if ASYNC + /// + /// Specifies a set of methods for asynchronously performing SQL operations on POCOs such as Insert, Update, Delete, and Save. + /// public interface IAlterPocoAsync { #region InsertAsync - /// - /// Async version of . - /// + /// Task InsertAsync(object poco); - /// - /// Async version of . - /// + /// Task InsertAsync(string tableName, object poco); - /// - /// Async version of . - /// + /// Task InsertAsync(string tableName, string primaryKeyName, object poco); - /// - /// Async version of . - /// + /// Task InsertAsync(string tableName, string primaryKeyName, bool autoIncrement, object poco); /// - /// Async version of . + /// Asynchronously inserts a new record and returns the primary key of the newly inserted record. /// + /// Task InsertAsync(CancellationToken cancellationToken, object poco); - /// - /// Async version of . - /// + /// + /// If a mapped primary key column is auto-incrementing and is , the primary key property of the POCO will be updated with the new record's auto-incremented ID. + /// + /// Task InsertAsync(CancellationToken cancellationToken, string tableName, object poco); - /// - /// Async version of . - /// + /// + /// If represents an auto-incrementing column and is , the primary key property of the POCO will be updated with the new record's auto-incremented ID. + /// + /// Task InsertAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco); /// - /// Async version of . + /// Asynchronously inserts a new record into the specified table and returns the primary key of the newly inserted record. /// + /// + /// If is , the primary key property of the POCO will be updated with the new record's auto-incremented ID. + /// + /// A cancellation token that can be used to cancel the operation. + /// The name of the table where the record will be inserted. + /// The name of the primary key column in the table. + /// Indicates whether the primary key column in the database is auto-incrementing. + /// The POCO instance to insert. + /// A task that represents the asynchronous operation. The task result contains the primary key of the new record if the table has a primary key column; otherwise, . Task InsertAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, bool autoIncrement, object poco); #endregion #region UpdateAsync - /// - /// Async version of . - /// + /// Task UpdateAsync(object poco); - /// - /// Async version of . - /// + /// Task UpdateAsync(object poco, IEnumerable columns); - /// - /// Async version of . - /// + /// Task UpdateAsync(object poco, object primaryKeyValue); - /// - /// Async version of . - /// + /// Task UpdateAsync(object poco, object primaryKeyValue, IEnumerable columns); - /// - /// Async version of . - /// + /// Task UpdateAsync(string tableName, string primaryKeyName, object poco); - /// - /// Async version of . - /// + /// Task UpdateAsync(string tableName, string primaryKeyName, object poco, IEnumerable columns); - /// - /// Async version of . - /// + /// Task UpdateAsync(string tableName, string primaryKeyName, object poco, object primaryKeyValue); - /// - /// Async version of . - /// + /// Task UpdateAsync(string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable columns); - /// - /// Async version of . - /// + /// Task UpdateAsync(Sql sql); - /// - /// Async version of . - /// + /// Task UpdateAsync(string sql, params object[] args); /// - /// Async version of . + /// Asynchronously updates a record and returns the number of rows affected by the update operation. /// + /// Task UpdateAsync(CancellationToken cancellationToken, object poco); /// - /// Async version of . + /// Asynchronously updates the specified columns of a record and returns the number of rows affected by the update operation. /// + /// Task UpdateAsync(CancellationToken cancellationToken, object poco, IEnumerable columns); /// - /// Async version of . + /// Asynchronously updates a record with the given ID and returns the number of rows affected by the update operation. /// + /// Task UpdateAsync(CancellationToken cancellationToken, object poco, object primaryKeyValue); /// - /// Async version of . + /// Asynchronously updates the specified columns of a record with the given ID and returns the number of rows affected by the update operation. /// + /// Task UpdateAsync(CancellationToken cancellationToken, object poco, object primaryKeyValue, IEnumerable columns); /// - /// Async version of . + /// Asynchronously a record in the provided table and returns the number of rows affected by the update operation. /// + /// Task UpdateAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco); /// - /// Async version of . + /// Asynchronously updates the specified columns of a record in the provided table and returns the number of rows affected by the update operation. /// + /// Task UpdateAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco, IEnumerable columns); /// - /// Async version of . + /// Asynchronously a record with the given ID in the provided table and returns the number of rows affected by the update operation. /// + /// Task UpdateAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco, object primaryKeyValue); /// - /// Async version of . + /// Asynchronously updates the specified columns of a record with the given ID in the provided table and returns the number of rows affected by the update operation. /// + /// A cancellation token that can be used to cancel the operation. + /// The name of the table to update. + /// The name of the primary key column in the table. + /// The POCO instance containing the column values to update. + /// The primary key value identifying the record to update. + /// A list of column names to update, or to update all columns. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the update operation. Task UpdateAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable columns); /// - /// Async version of . + /// Asynchronously executes an SQL update and returns the number of rows affected by the update operation. /// + /// The POCO type associated with the table to update. + /// A cancellation token that can be used to cancel the operation. + /// An SQL builder object representing the SQL update and condition clause (everything after UPDATE tablename), and its parameters. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the update operation. Task UpdateAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously executes an SQL update and returns the number of rows affected by the update operation. /// + /// The POCO type associated with the table to update. + /// A cancellation token that can be used to cancel the operation. + /// The SQL string containing the update and condition clause (everything after UPDATE tablename). + /// The parameters to pass to the SQL string. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the update operation. Task UpdateAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion #region DeleteAsync - /// - /// Async version of . - /// + /// Task DeleteAsync(object poco); - /// - /// Async version of . - /// + /// Task DeleteAsync(string tableName, string primaryKeyName, object poco); - /// - /// Async version of . - /// + /// Task DeleteAsync(string tableName, string primaryKeyName, object poco, object primaryKeyValue); - /// - /// Async version of . - /// + /// Task DeleteAsync(object pocoOrPrimaryKey); - /// - /// Async version of . - /// + /// Task DeleteAsync(Sql sql); - /// - /// Async version of . - /// + /// Task DeleteAsync(string sql, params object[] args); /// - /// Async version of . + /// Asynchronously deletes a record and returns the number of rows affected by the update operation. /// + /// A cancellation token that can be used to cancel the operation. + /// A POCO instance representing the record to delete. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the delete operation. Task DeleteAsync(CancellationToken cancellationToken, object poco); /// - /// Async version of . + /// Asynchronously deletes a record from the provided table and returns the number of rows affected by the delete operation. /// + /// A cancellation token that can be used to cancel the operation. + /// The name of the table containing the record to delete. + /// The name of the primary key column in the table. + /// The POCO instance representing the record to delete. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the delete operation. Task DeleteAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco); /// - /// Async version of . + /// Asynchronously deletes a record with the given ID from the provided table and returns the number of rows affected by the delete operation. /// + /// A cancellation token that can be used to cancel the operation. + /// The name of the table containing the record to delete. + /// The name of the primary key column in the table. + /// The POCO instance representing the record to delete, or to use the provided . + /// The primary key value of the record to delete, used if is . + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the delete operation. Task DeleteAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco, object primaryKeyValue); /// - /// Async version of . + /// Asynchronously deletes a record and returns the number of rows affected by the update operation. /// + /// The POCO type associated with the table to delete. + /// A cancellation token that can be used to cancel the operation. + /// Either a POCO instance representing the record to delete, or the primary key of the record. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the delete operation. Task DeleteAsync(CancellationToken cancellationToken, object pocoOrPrimaryKey); /// - /// Async version of . + /// Asynchronously executes an SQL delete and returns the number of rows affected by the delete operation. /// + /// The POCO type associated with the table to delete. + /// A cancellation token that can be used to cancel the operation. + /// An SQL builder object representing the SQL condition clause identifying the row to delete (everything after DELETE FROM tablename), and its parameters. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the delete operation. Task DeleteAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously executes an SQL delete and returns the number of rows affected by the delete operation. /// + /// The POCO type associated with the table to delete. + /// A cancellation token that can be used to cancel the operation. + /// The SQL string containing the condition clause identifying the row to delete (everything after DELETE FROM tablename). + /// The parameters to pass to the SQL string. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected by the delete operation. Task DeleteAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion #region SaveAsync - /// - /// Async version of . - /// + /// Task SaveAsync(object poco); - /// - /// Async version of . - /// + /// Task SaveAsync(string tableName, string primaryKeyName, object poco); - /// - /// Async version of . - /// + /// + /// This method performs an INSERT operation if the POCO is new (as determined by ), and an UPDATE operation otherwise. + /// + /// Task SaveAsync(CancellationToken cancellationToken, object poco); /// - /// Async version of . + /// Asynchronously saves the specified POCO to the database by performing either an insert or an update operation, as appropriate. /// + /// + /// This method performs an INSERT operation if the POCO is new (as determined by ), and an UPDATE operation otherwise. + /// + /// A cancellation token that can be used to cancel the operation. + /// The name of the table where the record will be saved. + /// The name of the primary key column in the table. + /// The POCO instance to save. + /// A task that represents the asynchronous operation. Task SaveAsync(CancellationToken cancellationToken, string tableName, string primaryKeyName, object poco); #endregion } +#endif } diff --git a/PetaPoco/IAsyncReader.cs b/PetaPoco/IAsyncReader.cs index 00141747..981d2be1 100644 --- a/PetaPoco/IAsyncReader.cs +++ b/PetaPoco/IAsyncReader.cs @@ -4,9 +4,9 @@ namespace PetaPoco { /// - /// Defines methods for asynchronously reading data as POCO objects from a data source. + /// Specifies a set of methods for asynchronously reading data as POCO objects from a data source. /// - /// The type of POCO object to read from the data source. + /// The POCO type representing a single result record. public interface IAsyncReader : IDisposable { /// @@ -17,7 +17,9 @@ public interface IAsyncReader : IDisposable /// /// Asynchronously reads the next row from the data source. /// - /// A task that represents the asynchronous read operation. The task result contains if more records exist; otherwise, . + /// A task that represents the asynchronous operation. The task result contains if more records exist, otherwise . Task ReadAsync(); + + // TODO: Missing: `Task ReadAsync(CancellationToken cancellationToken);` } } diff --git a/PetaPoco/IConnection.cs b/PetaPoco/IConnection.cs index b0333ba0..5e55a5a3 100644 --- a/PetaPoco/IConnection.cs +++ b/PetaPoco/IConnection.cs @@ -3,52 +3,51 @@ namespace PetaPoco { + /// + /// Defines methods and properties for managing database connections. This includes opening and closing shared connections, and accessing the currently open connection. + /// public interface IConnection { /// /// Gets or sets the connection reuse policy for the shared connection or instance. /// /// - /// When set to the first opened connection is kept alive until is called or the is disposed. + /// When set to the first opened connection is kept alive until is called or the is disposed. /// - /// bool KeepConnectionAlive { get; set; } /// /// Gets the currently open shared connection, or if there is no open connection. /// - /// - /// - /// IDbConnection Connection { get; } /// /// Opens a connection that will be used for all subsequent queries. /// /// - /// Calls to and are reference counted and should be balanced. + /// Calls to and are reference counted and should be balanced. /// - /// - /// - /// void OpenSharedConnection(); -#if !NET40 +#if ASYNC /// - /// The asyncronous version of . + /// Asynchronously opens a connection that will be used for all subsequent queries. /// + /// + /// Calls to and are reference counted and should be balanced. + /// + /// A task that represents the asynchronous operation. Task OpenSharedConnectionAsync(); + + // TODO: Missing overload in IConnection interface: Task OpenSharedConnectionAsync(CancellationToken); #endif /// /// Releases the shared connection. /// /// - /// Calls to and are reference counted and should be balanced. + /// Calls to and are reference counted and should be balanced. /// - /// - /// - /// void CloseSharedConnection(); } } diff --git a/PetaPoco/IDatabase.cs b/PetaPoco/IDatabase.cs index 5d04de0b..baf3fca0 100644 --- a/PetaPoco/IDatabase.cs +++ b/PetaPoco/IDatabase.cs @@ -6,7 +6,6 @@ namespace PetaPoco { - // TODO: Comments stating default values should be moved to the base implementation, where the defaults are actually set. /// /// Represents the core functionality of PetaPoco. /// @@ -18,157 +17,105 @@ public interface IDatabase : IDisposable, IQuery, IAlterPoco, IExecute, ITransac /// /// Gets the default mapper. /// - /// - /// By default, this is the . - /// - /// The default mapper. IMapper DefaultMapper { get; } /// - /// Gets the SQL of the last executed statement. + /// Gets the SQL of the last executed command. /// - /// The last executed SQL. string LastSQL { get; } /// - /// Gets the arguments to the last execute statement. + /// Gets an array containing the arguments of last executed command. /// - /// The last executed SQL arguments. object[] LastArgs { get; } /// - /// Gets a formatted string describing the last executed SQL statement and its argument values. + /// Gets a formatted string describing the last executed command and its argument values. /// - /// The formatted string. string LastCommand { get; } /// - /// Gets or sets the enable auto select. The default value is . + /// Gets or sets a value indicating whether automatic generation of the SELECT and WHERE parts of an SQL statement is enabled when not explicitly provided by the caller. /// - /// - /// When set to , PetaPoco will automatically create the "SELECT columns" section of the query for any query which is found to require them. - /// - /// , if auto select is enabled; otherwise, . bool EnableAutoSelect { get; set; } /// - /// Gets or sets the flag for whether named params are enabled. The default value is . + /// Gets or sets a value indicating whether named parameters are enabled. /// - /// - /// When set to , parameters can be named ?myparam and populated from properties of the passed-in argument values. - /// - /// , if named parameters are enabled; otherwise, . bool EnableNamedParams { get; set; } /// - /// Gets or sets the command timeout value, in seconds, which PetaPoco applies to all commands. The default value is 0 seconds. + /// Gets or sets the wait time (in seconds) before terminating the attempt to execute a command. /// - /// - /// If the current value is zero PetaPoco will not set the command timeout, and therefore the .NET default (30 seconds) will be in effect. - /// - /// The current command timeout. int CommandTimeout { get; set; } /// - /// Gets or sets the timeout value for the next (and only next) SQL statement. + /// Gets or sets a single-use timeout value that will temporarily override for the next command execution. /// - /// - /// This is a one-shot setting, which after use, will revert back to the previously set setting. - /// - /// The one time command timeout. int OneTimeCommandTimeout { get; set; } /// - /// Gets the current database Provider. + /// Gets the underlying database Provider. /// - /// The current database provider. IProvider Provider { get; } /// /// Gets the connection string. /// - /// The connection string. string ConnectionString { get; } + #region Transaction Interface + /// /// Gets or sets the transaction isolation level. /// - /// If , the underlying provider's default isolation level is used. IsolationLevel? IsolationLevel { get; set; } /// - /// Starts or continues a transaction. - /// - /// - /// This method facilitates proper transaction lifetime management, especially when nested. - /// Transactions can be nested but they must all be completed prior to leaving their scope, otherwise the entire transaction is aborted. - /// - /// A basic example of using transactional scopes (part pseudocode) is shown below: - /// - /// - /// - /// - /// - /// An reference that must be completed or disposed. + /// Begins or continues a transaction. + /// ITransaction GetTransaction(); /// - /// Starts a transaction scope. + /// Begins a transaction scope. /// - /// - /// - /// - /// - /// void BeginTransaction(); #if ASYNC /// - /// Async version of . + /// Asynchronously begins a transaction scope. /// + /// A task representing the asynchronous operation. Task BeginTransactionAsync(); /// - /// Async version of . + /// Asynchronously begins a transaction scope. /// + /// A cancellation token that can be used to cancel the operation. + /// A task representing the asynchronous operation. Task BeginTransactionAsync(CancellationToken cancellationToken); #endif /// /// Aborts the entire outermost transaction scope. /// - /// - /// Called automatically by if the transaction wasn't completed. - /// void AbortTransaction(); +#if ASYNC + // TODO: Not in interface: `AbortTransactionAsync()` + // TODO: Not in interface: `AbortTransactionAsync(CancellationToken()` +#endif + /// /// Marks the current transaction scope as complete. /// - /// - /// - /// - /// - /// void CompleteTransaction(); +#if ASYNC + // TODO: Not in interface: `CompleteTransactionAsync()` + // TODO: Not in interface: `CompleteTransactionAsync(CancellationToken()` +#endif + /// /// Occurs when a new transaction has started. /// @@ -179,6 +126,8 @@ public interface IDatabase : IDisposable, IQuery, IAlterPoco, IExecute, ITransac /// event EventHandler TransactionEnding; + #endregion + /// /// Occurs when a database command is about to be executed. /// @@ -189,6 +138,8 @@ public interface IDatabase : IDisposable, IQuery, IAlterPoco, IExecute, ITransac /// event EventHandler CommandExecuted; + // TODO: Not in interface: `event EventHandler ConnectionOpening` + /// /// Occurs when a database connection has been opened. /// diff --git a/PetaPoco/IExecute.cs b/PetaPoco/IExecute.cs index 9fe2154b..220b46a3 100644 --- a/PetaPoco/IExecute.cs +++ b/PetaPoco/IExecute.cs @@ -1,43 +1,40 @@ namespace PetaPoco { /// - /// Defines an interface for executing SQL commands and queries. + /// Specifies a set of methods for executing SQL non-query commands and scalar queries. /// - /// - /// This interface provides methods for executing SQL non-query commands and scalar queries. It supports SQL commands and queries represented as strings or as Sql Builder objects. - /// public interface IExecute { /// - /// Executes a non-query command. + /// Executes a non-query command and returns the number of rows affected. /// - /// An Sql builder object representing the SQL statement and its arguments. + /// An SQL builder object representing the SQL statement and its parameters. /// The number of rows affected. int Execute(Sql sql); /// - /// Executes a non-query command. + /// Executes a non-query command and returns the number of rows affected. /// - /// The SQL statement to execute. - /// Arguments to any embedded parameters in the SQL statement. + /// The SQL string. + /// The parameters to pass to the SQL string. /// The number of rows affected. int Execute(string sql, params object[] args); /// - /// Executes the query and returns the first column of the first row in the result set. + /// Executes a scalar command and returns the first column of the first row in the result set. /// - /// The type that the result value should be cast to. - /// An Sql builder object representing the SQL query and its arguments. - /// The scalar value cast to . + /// The type of the result value. + /// An SQL builder object representing the SQL statement and its parameters. + /// The scalar result value of type . T ExecuteScalar(Sql sql); /// - /// Executes the query and returns the first column of the first row in the result set. + /// Executes a scalar command and returns the first column of the first row in the result set. /// - /// The type that the result value should be cast to. - /// The SQL query to execute. - /// Arguments to any embedded parameters in the SQL statement. - /// The scalar value cast to . + /// The type of the result value. + /// The SQL query string. + /// The parameters to pass to the SQL query string. + /// The scalar result value of type . T ExecuteScalar(string sql, params object[] args); } } diff --git a/PetaPoco/IExecuteAsync.cs b/PetaPoco/IExecuteAsync.cs index 38e00178..b2f08974 100644 --- a/PetaPoco/IExecuteAsync.cs +++ b/PetaPoco/IExecuteAsync.cs @@ -5,11 +5,8 @@ namespace PetaPoco { #if ASYNC /// - /// Defines an interface for asynchronously executing SQL commands and queries. + /// Specifies a set of methods for asynchronously executing SQL non-query commands and scalar queries. /// - /// - /// This interface provides asynchronous methods for executing SQL non-query commands and scalar queries. It supports SQL commands and queries represented as strings or as Sql Builder objects. - /// public interface IExecuteAsync { /// @@ -25,39 +22,39 @@ public interface IExecuteAsync Task ExecuteScalarAsync(string sql, params object[] args); /// - /// Asynchronously executes a non-query command with a cancellation token. + /// Asynchronously executes a non-query command and returns the number of rows affected. /// /// A cancellation token that can be used to cancel the operation. - /// An Sql builder object representing the SQL statement and its arguments. - /// A task that represents the asynchronous operation. The task result is the number of rows affected. + /// An SQL builder object representing the SQL statement and its parameters. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected. Task ExecuteAsync(CancellationToken cancellationToken, Sql sql); /// - /// Asynchronously executes a non-query command with a cancellation token. + /// Asynchronously executes a non-query command and returns the number of rows affected. /// /// A cancellation token that can be used to cancel the operation. - /// The SQL statement to execute. - /// Arguments to any embedded parameters in the SQL statement. - /// A task that represents the asynchronous operation. The task result is the number of rows affected. + /// The SQL string. + /// The parameters to pass to the SQL string. + /// A task that represents the asynchronous operation. The task result contains the number of rows affected. Task ExecuteAsync(CancellationToken cancellationToken, string sql, params object[] args); /// - /// Asynchronously executes the query with a cancellation token and returns the first column of the first row in the result set. + /// Asynchronously executes a scalar command and returns the first column of the first row in the result set. /// - /// The type that the result value should be cast to. + /// The type of the result value. /// A cancellation token that can be used to cancel the operation. - /// An Sql builder object representing the SQL query and its arguments. - /// A task that represents the asynchronous operation. The task result is the scalar value cast to . + /// An SQL builder object representing the SQL statement and its parameters. + /// A task that represents the asynchronous operation. The task result contains the scalar result value of type . Task ExecuteScalarAsync(CancellationToken cancellationToken, Sql sql); /// - /// Asynchronously executes the query with a cancellation token and returns the first column of the first row in the result set. + /// Asynchronously executes a scalar command and returns the first column of the first row in the result set. /// - /// The type that the result value should be cast to. + /// The type of the result value. /// A cancellation token that can be used to cancel the operation. - /// The SQL query to execute. - /// Arguments to any embedded parameters in the SQL statement. - /// A task that represents the asynchronous operation. The task result is the scalar value cast to . + /// The SQL query string. + /// The parameters to pass to the SQL query string. + /// A task that represents the asynchronous operation. The task result contains the scalar result value of type . Task ExecuteScalarAsync(CancellationToken cancellationToken, string sql, params object[] args); } #endif diff --git a/PetaPoco/IQuery.cs b/PetaPoco/IQuery.cs index d2bd1a98..98ebc030 100644 --- a/PetaPoco/IQuery.cs +++ b/PetaPoco/IQuery.cs @@ -1,652 +1,457 @@ -using System; +using System; using System.Collections.Generic; namespace PetaPoco { + /// + /// Specifies a set of methods for executing SQL queries and returning the result set as lists, enumerables, single POCOs, multi-POCOs, or paged results. + /// public interface IQuery { - #region Query : Single-Poco + #region Query : Single-POCO /// - /// Streams the result of a select all query (SELECT *). + /// Executes an auto-select query (SELECT *) and returns the results as a sequence of type . /// /// - /// For some DB providers, care should be taken to not start a new Query before finishing with and disposing of the previous one. In cases where this is an issue, consider using Fetch, which returns the results as a List rather than streaming as an IEnumerable. + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// /// - /// The POCO type. - /// An IEnumerable collection of POCOs. + /// The POCO type representing a single result record. + /// An enumerable sequence of POCOs of type . IEnumerable Query(); - /// - /// Runs an SQL query, returning the results as an IEnumerable collection. - /// - /// - /// For some DB providers, care should be taken to not start a new Query before finishing with and disposing of the previous one. In cases where this is an issue, consider using Fetch, which returns the results as a List rather than an IEnumerable. - /// - /// The Type representing a row in the result set. - /// An SQL builder object representing the base SQL query and its arguments. - /// An IEnumerable collection of POCOs. + /// An SQL builder object representing the SQL query and its parameters. + /// IEnumerable Query(Sql sql); /// - /// Runs an SQL query, returning the results as an IEnumerable collection. + /// Executes a query and returns the results as a sequence of type . /// /// - /// For some DB providers, care should be taken to not start a new Query before finishing with and disposing of the previous one. In cases where this is an issue, consider using Fetch, which returns the results as a List rather than an IEnumerable. + /// Because this method streams the results from the database, care should be taken to not start a new query before finishing with and disposing of the previous one to prevent encountering database locks. In cases where contention could be an issue, consider using the equivalent Fetch method. /// - /// The Type representing a row in the result set. - /// The SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// An IEnumerable collection of POCOs. + /// The POCO type representing a single result record. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// An enumerable sequence of POCOs of type . IEnumerable Query(string sql, params object[] args); #endregion - #region Query : Multi-Poco + #region Query with Default Mapping : Multi-POCO - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. + /// IEnumerable Query(Sql sql); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. + /// IEnumerable Query(Sql sql); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. + /// IEnumerable Query(Sql sql); /// - /// Perform a multi-poco query. + /// Executes a multi-poco query and projects the result sequence into a new form of type using a default mapping function. /// + /// + /// PetaPoco will automatically attempt to determine the split points and auto-map each additional POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. /// The fifth POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. + /// An SQL builder object representing the SQL query and its parameters. + /// An enumerable sequence of POCOs of type . IEnumerable Query(Sql sql); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. + /// IEnumerable Query(string sql, params object[] args); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. + /// IEnumerable Query(string sql, params object[] args); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. + /// IEnumerable Query(string sql, params object[] args); /// - /// Perform a multi-poco query. + /// Executes a multi-poco query and projects the result sequence into a new form of type using a default mapping function. /// + /// + /// PetaPoco will automatically attempt to determine the split points and auto-map each additional POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. /// The fifth POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// An enumerable sequence of POCOs of type . IEnumerable Query(string sql, params object[] args); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, Sql sql); + #endregion - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, Sql sql); + #region Query with Custom Mapping : Multi-POCO - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, Sql sql); + /// + IEnumerable Query(Func projector, Sql sql); + + /// + IEnumerable Query(Func projector, Sql sql); + + /// + IEnumerable Query(Func projector, Sql sql); /// - /// Perform a multi-poco query. + /// Executes a multi-poco query and projects the result sequence into a new form of type using the provided mapping function. /// + /// + /// If is , PetaPoco will automatically attempt to determine the split points and auto-map each POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. /// The fifth POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, Sql sql); + /// The projected POCO type representing a single result record. + /// A function that transforms each of the given types into a , or null to use a default mapping function. + /// An SQL builder object representing the SQL query and its parameters. + /// An enumerable sequence of POCOs of type . + IEnumerable Query(Func projector, Sql sql); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, string sql, params object[] args); + /// + IEnumerable Query(Func projector, string sql, params object[] args); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, string sql, params object[] args); + /// + IEnumerable Query(Func projector, string sql, params object[] args); - /// - /// Perform a multi-poco query. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, string sql, params object[] args); + /// + IEnumerable Query(Func projector, string sql, params object[] args); /// - /// Perform a multi-poco query. + /// Executes a multi-poco query and projects the result sequence into a new form of type using the provided mapping function. /// + /// + /// If is , PetaPoco will automatically attempt to determine the split points and auto-map each POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. /// The fifth POCO type. - /// The type of objects in the returned IEnumerable. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Func cb, string sql, params object[] args); + /// The projected POCO type representing a single result record. + /// A function that transforms each of the given types into a , or null to use a default mapping function. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// An enumerable sequence of POCOs of type . + IEnumerable Query(Func projector, string sql, params object[] args); /// - /// Performs a multi-poco query. + /// Executes a multi-poco query and projects the result sequence into a new form of type using the provided mapping function. /// - /// The type of objects in the returned IEnumerable. - /// An array of Types representing the POCO types of the returned result set. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as an IEnumerable. - IEnumerable Query(Type[] types, object cb, string sql, params object[] args); + /// + /// If is , PetaPoco will automatically attempt to determine the split points and auto-map each POCO type into . + /// + /// The projected POCO type representing a single result record. + /// An array of POCO types representing the types referenced in composite type . + /// A function that transforms each of the given types into a , or null to use a default mapping function. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// An enumerable sequence of POCOs of type . + IEnumerable Query(Type[] types, object projector, string sql, params object[] args); #endregion - #region QueryMultiple : Multi-POCO Result Set IGridReader + #region QueryMultiple using IGridReader : Multi-POCO Result Set - /// - /// Perform a multi-results set query. - /// - /// An SQL builder object representing the query and its arguments. - /// A GridReader to be queried. + /// An SQL builder object representing the SQL query and its parameters. + /// IGridReader QueryMultiple(Sql sql); /// - /// Perform a multi-results set query. + /// Executes a multi-result set query. /// - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A GridReader to be queried. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A GridReader for reading the sequence of results. IGridReader QueryMultiple(string sql, params object[] args); #endregion - #region Fetch : Single-Poco + #region Fetch : Single-POCO /// - /// Runs a SELECT * query and returns the result set as a typed list. + /// Executes an auto-select query (SELECT *) and returns the results as a list of type . /// - /// The Type representing a row in the result set. - /// A List holding the results of the query. + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A list of POCOs of type . List Fetch(); - /// - /// Runs a query and returns the result set as a typed list. - /// - /// The Type representing a row in the result set. - /// An SQL builder object representing the query and its arguments. - /// A List holding the results of the query. + /// An SQL builder object representing the SQL query and its parameters. + /// List Fetch(Sql sql); /// - /// Runs a query and returns the result set as a typed list. + /// Executes a query and returns the results as a list of type . /// - /// The Type representing a row in the result set. - /// The SQL query to execute. - /// Arguments to any embedded parameters in the SQL. - /// A List holding the results of the query. + /// The POCO type representing a single result record. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A list of POCOs of type . List Fetch(string sql, params object[] args); #endregion - #region Fetch : Multi-Poco + #region Fetch with Default Mapping : Multi-POCO - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. + /// List Fetch(Sql sql); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. + /// List Fetch(Sql sql); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. + /// List Fetch(Sql sql); /// - /// Perform a multi-poco fetch. + /// Executes a multi-poco query and projects the result sequence into a new form of type using a default mapping function. /// + /// + /// PetaPoco will automatically attempt to determine the split points and auto-map each additional POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. - /// The fourth POCO type. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. + /// The fifth POCO type. + /// An SQL builder object representing the SQL query and its parameters. + /// A list of POCOs of type . List Fetch(Sql sql); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. + /// List Fetch(string sql, params object[] args); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. + /// List Fetch(string sql, params object[] args); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. + /// List Fetch(string sql, params object[] args); /// - /// Perform a multi-poco fetch. + /// Executes a multi-poco query and projects the result sequence into a new form of type using a default mapping function. /// + /// + /// PetaPoco will automatically attempt to determine the split points and auto-map each additional POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. /// The fifth POCO type. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A list of POCOs of type . List Fetch(string sql, params object[] args); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. - List Fetch(Func cb, Sql sql); + #endregion - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. - List Fetch(Func cb, Sql sql); + #region Fetch with Custom Mapping : Multi-POCO - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. - List Fetch(Func cb, Sql sql); + /// + List Fetch(Func projector, Sql sql); + + /// + List Fetch(Func projector, Sql sql); + + /// + List Fetch(Func projector, Sql sql); /// - /// Perform a multi-poco fetch. + /// Executes a multi-poco query and projects the result sequence into a new form of type using the provided mapping function. /// + /// + /// If is , PetaPoco will automatically attempt to determine the split points and auto-map each POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. /// The fifth POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// An SQL builder object representing the query and its arguments. - /// A collection of POCOs as a List. - List Fetch(Func cb, Sql sql); + /// The projected POCO type representing a single result record. + /// A function that transforms each of the given types into a , or null to use a default mapping function. + /// An SQL builder object representing the SQL query and its parameters. + /// A list of POCOs of type . + List Fetch(Func projector, Sql sql); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. - List Fetch(Func cb, string sql, params object[] args); + /// + List Fetch(Func projector, string sql, params object[] args); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. - List Fetch(Func cb, string sql, params object[] args); + /// + List Fetch(Func projector, string sql, params object[] args); - /// - /// Perform a multi-poco fetch. - /// - /// The first POCO type. - /// The second POCO type. - /// The third POCO type. - /// The fourth POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. - List Fetch(Func cb, string sql, params object[] args); + /// + List Fetch(Func projector, string sql, params object[] args); /// - /// Perform a multi-poco fetch. + /// Executes a multi-poco query and projects the result sequence into a new form of type using the provided mapping function. /// + /// + /// If is , PetaPoco will automatically attempt to determine the split points and auto-map each POCO type into . + /// /// The first POCO type. /// The second POCO type. /// The third POCO type. /// The fourth POCO type. /// The fifth POCO type. - /// The returned list POCO type. - /// A callback function to connect the POCO instances, or to automatically guess the relationships. - /// The SQL query to be executed. - /// Arguments to any embedded parameters in the SQL. - /// A collection of POCOs as a List. - List Fetch(Func cb, string sql, params object[] args); + /// The projected POCO type representing a single result record. + /// A function that transforms each of the given types into a , or null to use a default mapping function. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A list of POCOs of type . + List Fetch(Func projector, string sql, params object[] args); #endregion #region Fetch : Paged SkipTake /// - /// Retrieves a page of records (without the total count). + /// Executes an auto-select query (SELECT *) for a subset of records based on the specified parameters, and returns the results as a list of type . /// /// - /// PetaPoco will automatically modify a default SELECT * statement to only retrieve the records for the specified page. + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// This method performs essentially the same operation as . + /// Determining the number of records to skip, and how many to take, however, are calculated automatically based on the specified index and values. /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// A List of results. - List Fetch(long page, long itemsPerPage); + /// + List Fetch(long page, long maxItemsPerPage); - /// - /// Retrieves a page of records (without the total count). - /// /// - /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the records for the specified page. + /// This method performs essentially the same operation as . + /// Determining the number of records to skip, and how many to take, however, are calculated automatically based on the specified index and values. /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// An SQL builder object representing the base SQL query and its arguments. - /// A List of results. - List Fetch(long page, long itemsPerPage, Sql sql); + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// An SQL builder object representing the SQL query and its parameters. + /// + List Fetch(long page, long maxItemsPerPage, Sql sql); /// - /// Retrieves a page of records (without the total count). + /// Executes a query for a subset of records based on the specified parameters, and returns the results as a list of type . /// /// - /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the records for the specified page. + /// This method performs essentially the same operation as . + /// Determining the number of records to skip, and how many to take, however, are calculated automatically based on the specified index and values. /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// The base SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// A List of results. - List Fetch(long page, long itemsPerPage, string sql, params object[] args); + /// The POCO type representing a single result record. + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A list containing at most POCOs of type . + List Fetch(long page, long maxItemsPerPage, string sql, params object[] args); #endregion #region Page /// - /// Retrieves a page of records and the total number of available records. + /// Executes an auto-select query (SELECT *) for a subset of records based on the specified parameters, and returns the results as a Page of type . /// /// - /// PetaPoco will automatically modify a default SELECT * statement to only retrieve the records for the specified page. It will also execute a second query to retrieve the total number of records in the result set. + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// PetaPoco will automatically modify a default SELECT * statement to only retrieve the records for the specified page. + /// It will also execute a second query to retrieve the total number of records in the result set. /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// A Page of results. - Page Page(long page, long itemsPerPage); + /// The POCO type representing a single result record. + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// An initialized containing a list of POCOs. + Page Page(long page, long maxItemsPerPage); - /// - /// Retrieves a page of records and the total number of available records. - /// - /// - /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the records for the specified page. It will also execute a second query to retrieve the total number of records in the result set. - /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// An SQL builder object representing the base SQL query and its arguments. - /// A Page of results. - Page Page(long page, long itemsPerPage, Sql sql); + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// An SQL builder object representing the SQL query and its parameters. + /// + Page Page(long page, long maxItemsPerPage, Sql sql); /// - /// Retrieves a page of records and the total number of available records. + /// Executes a query for a subset of records based on the specified parameters, and returns the results as a Page of type . /// /// - /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the records for the specified page. It will also execute a second query to retrieve the total number of records in the result set. + /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the records for the specified page. + /// It will also execute a second query to retrieve the total number of records in the result set. /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// The base SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// A Page of results. - Page Page(long page, long itemsPerPage, string sql, params object[] args); + /// The POCO type representing a single result record. + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// An initialized containing a list of POCOs. + Page Page(long page, long maxItemsPerPage, string sql, params object[] args); - /// - /// Retrieves a page of records and the total number of available records. - /// - /// - /// This method allows separate SQL statements to be explicitly provided for the two parts of the page query. The page and itemsPerPage parameters are not used directly and are used simply to populate the returned Page object. - /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// An SQL builder object representing the SQL to retrieve the total number of records. - /// An SQL builder object representing the SQL to retrieve a single page of results. - /// A Page of results. - Page Page(long page, long itemsPerPage, Sql sqlCount, Sql sqlPage); + /// The one-based page number for this page. + /// The maximum number of records per page. + /// An SQL builder object representing the SQL statement and its parameters, used to query the total number of records. + /// An SQL builder object representing the SQL statement and its parameters, used to query a single page of results. + /// + Page Page(long page, long maxItemsPerPage, Sql countSql, Sql pageSql); /// - /// Retrieves a page of records and the total number of available records. + /// Executes a query for a subset of records based on the specified parameters, and returns the results as a Page of type . /// /// - /// This method allows separate SQL statements to be explicitly provided for the two parts of the page query. The page and itemsPerPage parameters are not used directly and are used simply to populate the returned Page object. + /// This method accepts two separate SQL statements that will be used explicitly for both parts of the page query. + /// The and parameters are used to populate the returned Page object. /// - /// The Type representing a row in the result set. - /// The 1-based page number to retrieve. - /// The number of records per page. - /// The SQL to retrieve the total number of records. - /// Arguments to any embedded parameters in the sqlCount statement. - /// The SQL to retrieve a single page of results. - /// Arguments to any embedded parameters in the sqlPage statement. - /// A Page of results. - Page Page(long page, long itemsPerPage, string sqlCount, object[] countArgs, string sqlPage, object[] pageArgs); + /// The POCO type representing a single result record. + /// The one-based page number for this page. + /// The maximum number of records per page. + /// The SQL statement used to query the total number of records. + /// The parameters to embed in . + /// The SQL statement used to query a single page of results. + /// The parameters to embed in . + /// An initialized containing a list of POCOs. + Page Page(long page, long maxItemsPerPage, string countSql, object[] countArgs, string pageSql, object[] pageArgs); #endregion #region SkipTake /// - /// Retrieves a range of records from result set. + /// Executes an auto-select query (SELECT *) and returns a subset of the results as a list of type . /// /// - /// PetaPoco will automatically modify a default SELECT * statement to only retrieve the records for the specified range. + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// /// - /// The Type representing a row in the result set. - /// The number of rows at the start of the result set to skip over. - /// The number of rows to retrieve. - /// A List of results. + /// The POCO type representing a single result record. + /// The number of records to skip. + /// The number of records to take. + /// A list of POCOs of type . List SkipTake(long skip, long take); - /// - /// Retrieves a range of records from result set. - /// - /// - /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the records for the specified range. - /// - /// The Type representing a row in the result set. - /// The number of rows at the start of the result set to skip over. - /// The number of rows to retrieve. - /// An SQL builder object representing the base SQL query and its arguments. - /// A List of results. + /// The number of records to skip. + /// The number of records to take. + /// An SQL builder object representing the SQL query and its parameters. + /// List SkipTake(long skip, long take, Sql sql); /// - /// Retrieves a range of records from result set. + /// Executes a query and returns a subset of the results as a list of type . /// /// - /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the records for the specified range. + /// The provided SQL query will be modified to limit the starting offset and number of returned records based on the specified parameters. /// - /// The Type representing a row in the result set. - /// The number of rows at the start of the result set to skip over. - /// The number of rows to retrieve. - /// The base SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// A List of results. + /// The POCO type representing a single result record. + /// The number of records to skip. + /// The number of records to take. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A list of POCOs of type . List SkipTake(long skip, long take, string sql, params object[] args); #endregion @@ -654,58 +459,50 @@ public interface IQuery #region Exists /// - /// Checks for the existence of a row with the specified primary key value. + /// Determines whether a record exists with the specified primary key value. /// - /// The Type representing the table being queried. - /// The primary key value to look for. - /// if a record with the specified primary key value exists, otherwise . - bool Exists(object primaryKey); + /// + /// If provided a POCO instance as the parameter, PetaPoco will extract the value from the POCO's mapped primary key property, and perform the same query as if the primary key value was provided directly. + /// + /// The POCO type to be queried. + /// The primary key value, or a POCO containing an assigned primary key value to query. + /// if one or more records exist with the specified primary key value; otherwise, . + bool Exists(object pocoOrPrimaryKey); + + // TODO: Missing overload: `bool Exists(Sql sql);` /// - /// Checks for the existence of a row matching the specified condition. + /// Determines whether a record exists that matches the conditions defined by the specified query. /// - /// The Type representing the table being queried. - /// The SQL expression to be tested for (the WHERE expression). - /// Arguments to any embedded parameters in the SQL statement. - /// if a record matching the condition is found, otherwise . - bool Exists(string sqlCondition, params object[] args); + /// The POCO type to be queried. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// if one or more records exist that satisfy the conditions defined in the specified query; otherwise, . + bool Exists(string sql, params object[] args); #endregion #region Single /// - /// Returns the record with the specified primary key value. + /// Returns the only record that matches the specified primary key value, and throws an exception if there is not exactly one matching record. /// - /// - /// Throws an exception if there is not exactly one record with the specified primary key value. - /// - /// The Type representing a row in the result set. - /// The primary key value of the record to fetch. - /// The single record matching the specified primary key value. + /// The POCO type being queried. + /// The primary key value. + /// The single result returned by the query. T Single(object primaryKey); - /// - /// Runs a query that should always return a single row. - /// - /// - /// Throws an exception if there is not exactly one matching record - /// - /// The Type representing a row in the result set. - /// An SQL builder object representing the query and its arguments. - /// The single record matching the specified SQL query. + /// An SQL builder object representing the SQL query and its parameters. + /// T Single(Sql sql); /// - /// Runs a query that should always return a single row. + /// Returns the only record that matches the specified query, and throws an exception if there is not exactly one matching record. /// - /// - /// Throws an exception if there is not exactly one record - /// - /// The Type representing a row in the result set. - /// The SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// The single record matching the specified SQL query. + /// The POCO type being queried. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// The single result returned by the query. T Single(string sql, params object[] args); #endregion @@ -713,73 +510,58 @@ public interface IQuery #region SingleOrDefault /// - /// Returns the record with the specified primary key value, or the default value if not found. + /// Returns the only record that matches the specified primary key value, or a default value if the result set is empty; this method throws an exception if there is more than one matching record. /// - /// - /// If there are no records with the specified primary key value, default(T) (typically ) is returned. - /// - /// The Type representing a row in the result set. - /// The primary key value of the record to fetch. - /// The single record matching the specified primary key value. + /// The POCO type being queried. + /// The primary key value. + /// default(T) if no record is found; otherwise, the single result returned by the query. T SingleOrDefault(object primaryKey); - /// - /// Runs a query that should always return either a single row, or no rows. - /// - /// The Type representing a row in the result set. - /// An SQL builder object representing the query and its arguments. - /// The single record matching the specified primary key value, or default(T) if no matching rows. + /// An SQL builder object representing the SQL query and its parameters. + /// T SingleOrDefault(Sql sql); /// - /// Runs a query that should always return either a single row, or no rows. + /// Returns the only record that matches the specified query, or a default value if the result set is empty; this method throws an exception if there is more than one matching record. /// - /// The Type representing a row in the result set. - /// The SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// The single record matching the specified primary key value, or default(T) if no matching rows. + /// The POCO type being queried. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// default(T) if no record is found; otherwise, the single result returned by the query. T SingleOrDefault(string sql, params object[] args); #endregion #region First - /// - /// Runs a query that should always return at least one record. - /// - /// The Type representing a row in the result set. - /// An SQL builder object representing the query and its arguments. - /// The first record in the result set. + /// An SQL builder object representing the SQL query and its parameters. + /// T First(Sql sql); /// - /// Runs a query that should always return at least one record. + /// Returns the first record that matches the specified query, and throws an exception if the result set is empty. /// - /// The Type representing a row in the result set. - /// The SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// The first record in the result set. + /// The POCO type being queried. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// The first result record returned by the specified query. T First(string sql, params object[] args); #endregion #region FirstOrDefault - /// - /// Runs a query and returns the first record, or the default value if no matching records. - /// - /// The Type representing a row in the result set. - /// An SQL builder object representing the query and its arguments. - /// The first record in the result set, or default(T) if no matching rows. + /// An SQL builder object representing the SQL query and its parameters. + /// T FirstOrDefault(Sql sql); /// - /// Runs a query and returns the first record, or the default value if no matching records. + /// Returns the first record that matches the specified query, or a default value if the result set is empty. /// - /// The Type representing a row in the result set. - /// The SQL query. - /// Arguments to any embedded parameters in the SQL statement. - /// The first record in the result set, or default(T) if no matching rows. + /// The POCO type being queried. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// default(T) if the result set is empty; otherwise, the first record that matches the specified query. T FirstOrDefault(string sql, params object[] args); #endregion diff --git a/PetaPoco/IQueryAsync.cs b/PetaPoco/IQueryAsync.cs index 1dd74562..b35d2bb9 100644 --- a/PetaPoco/IQueryAsync.cs +++ b/PetaPoco/IQueryAsync.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data; using System.Threading; @@ -7,482 +7,621 @@ namespace PetaPoco { #if ASYNC + /// + /// Specifies a set of methods for asynchronously executing SQL queries and returning the result set as lists, enumerables, single POCOs, multi-POCOs, or paged results. + /// public interface IQueryAsync { - #region QueryAsync : Single-Poco + #region QueryAsync : Single-POCO - /// - /// Async version of . - /// + /// Task> QueryAsync(); - /// - /// Async version of . - /// + /// Task> QueryAsync(Sql sql); - /// - /// Async version of . - /// + /// Task> QueryAsync(string sql, params object[] args); /// - /// Async version of . + /// Asynchronously executes an auto-select query (SELECT *) and returns an async reader. /// + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. Task> QueryAsync(CancellationToken cancellationToken); /// - /// Async version of . + /// Asynchronously executes a query and returns an async reader. /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// An SQL builder object representing the SQL query and its parameters. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. Task> QueryAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously executes a query and returns an async reader. /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. Task> QueryAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion - #region QueryAsync : Single-Poco as CommandType + #region QueryAsync : Single-POCO as CommandType - /// - /// Async version of . - /// + /// Task> QueryAsync(CommandType commandType); - /// - /// Async version of . - /// + /// Task> QueryAsync(CommandType commandType, Sql sql); - /// - /// Async version of . - /// + /// Task> QueryAsync(CommandType commandType, string sql, params object[] args); /// - /// Async version of . + /// Asynchronously executes an auto-select query (SELECT *) for the specified command type and returns an async reader. /// + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The type of command to execute. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. Task> QueryAsync(CancellationToken cancellationToken, CommandType commandType); /// - /// Async version of . + /// Asynchronously executes a query for the specified command type and returns an async reader. /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The type of command to execute. + /// An SQL builder object representing the SQL query and its parameters. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. Task> QueryAsync(CancellationToken cancellationToken, CommandType commandType, Sql sql); /// - /// Async version of . + /// Asynchronously executes a query for the specified command type and returns an async reader. /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The type of command to execute. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. + /// A task representing the asynchronous operation. The task result contains an for reading the result set. Task> QueryAsync(CancellationToken cancellationToken, CommandType commandType, string sql, params object[] args); #endregion - #region QueryAsync with Action : Single-Poco + #region QueryAsync with Action : Single-POCO - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback); + /// + Task QueryAsync(Action action); - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback, Sql sql); + /// + Task QueryAsync(Action action, Sql sql); - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback, string sql, params object[] args); + /// + Task QueryAsync(Action action, string sql, params object[] args); /// - /// Async version of . + /// Asynchronously executes an auto-select query (SELECT *) and invokes the specified action on each result read from the underlying data reader. /// - Task QueryAsync(Action receivePocoCallback, CancellationToken cancellationToken); + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// An action to perform on each POCO in the result set. + /// A task representing the asynchronous operation. + Task QueryAsync(Action action, CancellationToken cancellationToken); - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback, CancellationToken cancellationToken, Sql sql); + /// A cancellation token that can be used to cancel the operation. + /// An action to perform on each POCO in the result set. + /// An SQL builder object representing the SQL query and its parameters. + /// + Task QueryAsync(Action action, CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously executes a query and invokes the specified action on each result read from the underlying data reader. /// - Task QueryAsync(Action receivePocoCallback, CancellationToken cancellationToken, string sql, params object[] args); + /// The POCO type representing a single result record. + /// An action to perform on each POCO in the result set. + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task representing the asynchronous operation. + Task QueryAsync(Action action, CancellationToken cancellationToken, string sql, params object[] args); #endregion - #region QueryAsync with Action : Single-Poco as CommandType + #region QueryAsync with Action : Single-POCO as CommandType - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback, CommandType commandType); + /// + Task QueryAsync(Action action, CommandType commandType); - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback, CommandType commandType, Sql sql); + /// + Task QueryAsync(Action action, CommandType commandType, Sql sql); - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback, CommandType commandType, string sql, params object[] args); + /// + Task QueryAsync(Action action, CommandType commandType, string sql, params object[] args); /// - /// Async version of . + /// Asynchronously executes an auto-select query (SELECT *) for the specified command type and invokes the specified action on each result read from the underlying data reader. /// - Task QueryAsync(Action receivePocoCallback, CancellationToken cancellationToken, CommandType commandType); + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// An action to perform on each POCO in the result set. + /// The type of command to execute. + /// A task representing the asynchronous operation. + Task QueryAsync(Action action, CancellationToken cancellationToken, CommandType commandType); - /// - /// Async version of . - /// - Task QueryAsync(Action receivePocoCallback, CancellationToken cancellationToken, CommandType commandType, Sql sql); + /// A cancellation token that can be used to cancel the operation. + /// An action to perform on each POCO in the result set. + /// The type of command to execute. + /// An SQL builder object representing the SQL query and its parameters. + /// + Task QueryAsync(Action action, CancellationToken cancellationToken, CommandType commandType, Sql sql); /// - /// Async version of . + /// Asynchronously executes a query for the specified command type and invokes the specified action on each result read from the underlying data reader. /// - Task QueryAsync(Action receivePocoCallback, CancellationToken cancellationToken, CommandType commandType, string sql, params object[] args); + /// The POCO type representing a single result record. + /// An action to perform on each POCO in the result set. + /// A cancellation token that can be used to cancel the operation. + /// The type of command to execute. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task representing the asynchronous operation. + Task QueryAsync(Action action, CancellationToken cancellationToken, CommandType commandType, string sql, params object[] args); #endregion - #region QueryAsync : Multi-Poco + #region QueryAsync : Multi-POCO + + //... #endregion #region QueryMultipleAsync : Multi-POCO Result Set + //... + #endregion - #region FetchAsync : Single-Poco + #region FetchAsync : Single-POCO - /// - /// Async version of . - /// + /// Task> FetchAsync(); - /// - /// Async version of . - /// + /// Task> FetchAsync(Sql sql); - /// - /// Async version of . - /// + /// Task> FetchAsync(string sql, params object[] args); /// - /// Async version of . + /// Asynchronously executes an auto-select query (SELECT *) and returns the results as a list of type . /// + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// A list of POCOs of type . Task> FetchAsync(CancellationToken cancellationToken); - /// - /// Async version of . - /// + /// A cancellation token that can be used to cancel the operation. + /// An SQL builder object representing the SQL query and its parameters. + /// Task> FetchAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Executes a query and returns the results as a list of type . /// + /// + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A list of POCOs of type . Task> FetchAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion - #region FetchAsync : Single-Poco as CommandType + #region FetchAsync : Single-POCO as CommandType - /// - /// Async version of . - /// + /// Task> FetchAsync(CommandType commandType); - /// - /// Async version of . - /// + /// Task> FetchAsync(CommandType commandType, Sql sql); - /// - /// Async version of . - /// + /// Task> FetchAsync(CommandType commandType, string sql, params object[] args); /// - /// Async version of . + /// Asynchronously executes an auto-select query (SELECT *) for the specified command type and returns the results as a list of type . /// + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The type of command to execute. + /// A list of POCOs of type . Task> FetchAsync(CancellationToken cancellationToken, CommandType commandType); - /// - /// Async version of . - /// + /// A cancellation token that can be used to cancel the operation. + /// The type of command to execute. + /// An SQL builder object representing the SQL query and its parameters. + /// Task> FetchAsync(CancellationToken cancellationToken, CommandType commandType, Sql sql); /// - /// Async version of . + /// Executes a query for the specified command type and returns the results as a list of type . /// + /// + /// A cancellation token that can be used to cancel the operation. + /// The type of command to execute. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A list of POCOs of type . Task> FetchAsync(CancellationToken cancellationToken, CommandType commandType, string sql, params object[] args); #endregion - #region FetchAsync : Multi-Poco + #region FetchAsync : Multi-POCO + + //... #endregion #region FetchAsync : Paged SkipTake - /// - /// Async version of . - /// - Task> FetchAsync(long page, long itemsPerPage); - - /// - /// Async version of . - /// - Task> FetchAsync(long page, long itemsPerPage, Sql sql); - - /// - /// Async version of . - /// - Task> FetchAsync(long page, long itemsPerPage, string sql, params object[] args); - - /// - /// Async version of . - /// - Task> FetchAsync(CancellationToken cancellationToken, long page, long itemsPerPage); - - /// - /// Async version of . - /// - Task> FetchAsync(CancellationToken cancellationToken, long page, long itemsPerPage, Sql sql); - - /// - /// Async version of . - /// - Task> FetchAsync(CancellationToken cancellationToken, long page, long itemsPerPage, string sql, params object[] args); + /// + Task> FetchAsync(long page, long maxItemsPerPage); + + /// + Task> FetchAsync(long page, long maxItemsPerPage, Sql sql); + + /// + Task> FetchAsync(long page, long maxItemsPerPage, string sql, params object[] args); + + /// + /// Asynchronoushly executes an auto-select query (SELECT *) for a subset of records based on the specified parameters, and returns the results as a list of type . + /// + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// This method performs essentially the same operation as . + /// Determining the number of records to skip, and how many to take, however, are calculated automatically based on the specified index and values. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// A task representing the asynchronous operation. The task result is a list of type containing the results. + Task> FetchAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage); + + /// + /// This method performs essentially the same operation as . + /// Determining the number of records to skip, and how many to take, however, are calculated automatically based on the specified index and values. + /// + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// An SQL builder object representing the SQL query and its parameters. + /// + Task> FetchAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage, Sql sql); + + /// + /// Asynchronoushly executes a query for a subset of records based on the specified parameters, and returns the results as a list of type . + /// + /// + /// This method performs essentially the same operation as . + /// Determining the number of records to skip, and how many to take, however, are calculated automatically based on the specified index and values. + /// + /// + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number used to calculate the number of records to skip. + /// The maximum number of records per page. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task representing the asynchronous operation. The task result is a list of type containing the results. + Task> FetchAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage, string sql, params object[] args); #endregion #region PageAsync - /// - /// Async version of . - /// - Task> PageAsync(long page, long itemsPerPage); + /// + Task> PageAsync(long page, long maxItemsPerPage); - /// - /// Async version of . - /// - Task> PageAsync(long page, long itemsPerPage, Sql sql); + /// + Task> PageAsync(long page, long maxItemsPerPage, Sql sql); - /// - /// Async version of . - /// - Task> PageAsync(long page, long itemsPerPage, string sql, params object[] args); + /// + Task> PageAsync(long page, long maxItemsPerPage, string sql, params object[] args); - /// - /// Async version of . - /// - Task> PageAsync(long page, long itemsPerPage, Sql sqlCount, Sql sqlPage); + /// + Task> PageAsync(long page, long maxItemsPerPage, Sql countSql, Sql pageSql); - /// - /// Async version of . - /// - Task> PageAsync(long page, long itemsPerPage, string sqlCount, object[] countArgs, string sqlPage, object[] pageArgs); + /// + Task> PageAsync(long page, long maxItemsPerPage, string countSql, object[] countArgs, string pageSql, object[] pageArgs); /// - /// Async version of . + /// Asynchronously executes an auto-select query (SELECT *) for a subset of records based on the specified parameters, and returns the results as a Page of type . /// - Task> PageAsync(CancellationToken cancellationToken, long page, long itemsPerPage); + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number for this page. + /// The maximum number of records per page. + /// A task that represents the asynchronous operation. The task result contains an initialized containing a list of POCOs. + Task> PageAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage); /// - /// Async version of . + /// Asynchronously executes a query for a subset of records based on the specified parameters, and returns the results as a Page of type . /// - Task> PageAsync(CancellationToken cancellationToken, long page, long itemsPerPage, Sql sql); + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number for this page. + /// The maximum number of records per page. + /// An SQL builder object representing the SQL query and its parameters. + /// A task that represents the asynchronous operation. The task result contains an initialized containing a list of POCOs. + Task> PageAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage, Sql sql); /// - /// Async version of . + /// Asynchronously executes a query for a subset of records based on the specified parameters, and returns the results as a Page of type . /// - Task> PageAsync(CancellationToken cancellationToken, long page, long itemsPerPage, string sql, params object[] args); + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number for this page. + /// The maximum number of records per page. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task that represents the asynchronous operation. The task result contains an initialized containing a list of POCOs. + Task> PageAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage, string sql, params object[] args); /// - /// Async version of . + /// Asynchronously executes a query for a subset of records based on the specified parameters, and returns the results as a Page of type . /// - Task> PageAsync(CancellationToken cancellationToken, long page, long itemsPerPage, Sql sqlCount, Sql sqlPage); + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number for this page. + /// The maximum number of records per page. + /// An SQL builder object representing the SQL statement and its parameters, used to query the total number of records. + /// An SQL builder object representing the SQL statement and its parameters, used to query a single page of results. + /// A task that represents the asynchronous operation. The task result contains an initialized containing a list of POCOs. + Task> PageAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage, Sql countSql, Sql pageSql); /// - /// Async version of . + /// Asynchronously executes a query for a subset of records based on the specified parameters, and returns the results as a Page of type . /// - Task> PageAsync(CancellationToken cancellationToken, long page, long itemsPerPage, string sqlCount, object[] countArgs, string sqlPage, object[] pageArgs); + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The one-based page number for this page. + /// The maximum number of records per page. + /// The SQL statement used to query the total number of records. + /// The parameters to embed in . + /// The SQL statement used to query a single page of results. + /// The parameters to embed in . + /// A task that represents the asynchronous operation. The task result contains an initialized containing a list of POCOs. + Task> PageAsync(CancellationToken cancellationToken, long page, long maxItemsPerPage, string countSql, object[] countArgs, string pageSql, object[] pageArgs); #endregion #region SkipTakeAsync - /// - /// Async version of . - /// + /// Task> SkipTakeAsync(long skip, long take); - /// - /// Async version of . - /// + /// Task> SkipTakeAsync(long skip, long take, Sql sql); - /// - /// Async version of . - /// + /// Task> SkipTakeAsync(long skip, long take, string sql, params object[] args); /// - /// Async version of . + /// Asynchronoushly executes an auto-select query (SELECT *) for a subset of records based on the specified parameters, and returns the results as a list of type . /// + /// + /// must be enabled in order to generate the auto-select portion of the SQL statement. + /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The number of records to skip. + /// The number of records to take. + /// A task that represents the asynchronous operation. The task result contains a list of POCOs of type . Task> SkipTakeAsync(CancellationToken cancellationToken, long skip, long take); - /// - /// Async version of . - /// + /// A cancellation token that can be used to cancel the operation. + /// The number of records to skip. + /// The number of records to take. + /// An SQL builder object representing the SQL query and its parameters. + /// Task> SkipTakeAsync(CancellationToken cancellationToken, long skip, long take, Sql sql); /// - /// Async version of . + /// Asynchronoushly executes a query for a subset of records based on the specified parameters, and returns the results as a list of type . /// + /// The POCO type representing a single result record. + /// A cancellation token that can be used to cancel the operation. + /// The number of records to skip. + /// The number of records to take. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task that represents the asynchronous operation. The task result contains a list of POCOs of type . Task> SkipTakeAsync(CancellationToken cancellationToken, long skip, long take, string sql, params object[] args); #endregion #region ExistsAsync - /// - /// Async version of . - /// - Task ExistsAsync(object primaryKey); + /// + Task ExistsAsync(object pocoOrPrimaryKey); - /// - /// Async version of . - /// + /// Task ExistsAsync(string sqlCondition, params object[] args); /// - /// Async version of . + /// Asynchronously determines whether a record exists with the specified primary key value. /// - Task ExistsAsync(CancellationToken cancellationToken, object primaryKey); + /// + /// If provided a POCO object as the parameter, PetaPoco will extract the value from the POCO's mapped primary key property, and perform the same query as if the primary key value was provided directly. + /// + /// The POCO type to be queried. + /// A cancellation token that can be used to cancel the operation. + /// The primary key value, or a POCO containing an assigned primary key value to query. + /// A task that represents the asynchronous operation. The task result contains if one or more records exist with the specified primary key value; otherwise, . + Task ExistsAsync(CancellationToken cancellationToken, object pocoOrPrimaryKey); /// - /// Async version of . + /// Asynchronously determines whether a record exists that matches the conditions defined by the specified query. /// + /// The POCO type to be queried. + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the query string. + /// A task that represents the asynchronous operation. The task result contains if one or more records exist that satisfy the conditions defined in the specified query; otherwise, . Task ExistsAsync(CancellationToken cancellationToken, string sqlCondition, params object[] args); #endregion #region SingleAsync - /// - /// Async version of . - /// + /// Task SingleAsync(object primaryKey); - /// - /// Async version of . - /// + /// Task SingleAsync(Sql sql); - /// - /// Async version of . - /// + /// Task SingleAsync(string sql, params object[] args); /// - /// Async version of . + /// Asynchronously returns the only record that matches the specified primary key value, and throws an exception if there is not exactly one matching record. /// + /// The POCO type being queried. + /// A cancellation token that can be used to cancel the operation. + /// The primary key value, or a POCO containing an assigned primary key value to query. + /// A task that represents the asynchronous operation. The task result contains the single result returned by the query. Task SingleAsync(CancellationToken cancellationToken, object primaryKey); - /// - /// Async version of . - /// + /// A cancellation token that can be used to cancel the operation. + /// An SQL builder object representing the SQL query and its parameters. + /// Task SingleAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously returns the only record that matches the specified query, and throws an exception if there is not exactly one matching record. /// + /// The POCO type being queried. + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the query string. + /// A task that represents the asynchronous operation. The task result contains the single result returned by the query. Task SingleAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion #region SingleOrDefaultAsync - /// - /// Async version of . - /// + /// Task SingleOrDefaultAsync(object primaryKey); - /// - /// Async version of . - /// + /// Task SingleOrDefaultAsync(Sql sql); - /// - /// Async version of . - /// + /// Task SingleOrDefaultAsync(string sql, params object[] args); /// - /// Async version of . + /// Asynchronously returns the only record that matches the specified primary key value, or a default value if the result set is empty; this method throws an exception if there is more than one matching record. /// + /// The POCO type being queried. + /// A cancellation token that can be used to cancel the operation. + /// The primary key value, or a POCO containing an assigned primary key value to query. + /// A task that represents the asynchronous operation. The task result contains default(T) if no record is found; otherwise, the single result returned by the specified query. Task SingleOrDefaultAsync(CancellationToken cancellationToken, object primaryKey); - /// - /// Async version of . - /// + /// A cancellation token that can be used to cancel the operation. + /// An SQL builder object representing the SQL query and its parameters. + /// Task SingleOrDefaultAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously returns the only record that matches the specified query, or a default value if the result set is empty; this method throws an exception if there is more than one matching record. /// + /// The POCO type being queried. + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task that represents the asynchronous operation. The task result contains default(T) if no record is found; otherwise, the single result returned by the specified query. Task SingleOrDefaultAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion #region FirstAsync - /// - /// Async version of . - /// + /// Task FirstAsync(Sql sql); - /// - /// Async version of . - /// + /// Task FirstAsync(string sql, params object[] args); - /// - /// Async version of . - /// + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// Task FirstAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously returns the first record that matches the specified query, and throws an exception if the result set is empty. /// + /// The POCO type being queried. + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task that represents the asynchronous operation. The task result contains the first result returned by the specified query. Task FirstAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion #region FirstOrDefaultAsync - /// - /// Async version of . - /// + /// Task FirstOrDefaultAsync(Sql sql); - /// - /// Async version of . - /// + /// Task FirstOrDefaultAsync(string sql, params object[] args); - /// - /// Async version of . - /// + /// A cancellation token that can be used to cancel the operation. + /// An SQL builder object representing the SQL query and its parameters. + /// Task FirstOrDefaultAsync(CancellationToken cancellationToken, Sql sql); /// - /// Async version of . + /// Asynchronously returns the first record that matches the specified query, or a default value if the result set is empty. /// + /// The POCO type being queried. + /// A cancellation token that can be used to cancel the operation. + /// The SQL query string. + /// The parameters to embed in the SQL string. + /// A task that represents the asynchronous operation. The task result contains default(T) if the result set is empty; otherwise, the first record that matches the specified query. Task FirstOrDefaultAsync(CancellationToken cancellationToken, string sql, params object[] args); #endregion diff --git a/PetaPoco/IStoredProc.cs b/PetaPoco/IStoredProc.cs index 54e0830d..0e5fb5f9 100644 --- a/PetaPoco/IStoredProc.cs +++ b/PetaPoco/IStoredProc.cs @@ -3,7 +3,7 @@ namespace PetaPoco { /// - /// Defines an interface for executing stored procedures. + /// Specifies a set of methods for executing stored procedures. /// public interface IStoredProc { @@ -15,43 +15,43 @@ public interface IStoredProc /// /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// The number of rows affected by the stored procedure. + /// The number of rows affected. int ExecuteNonQueryProc(string storedProcedureName, params object[] args); /// - /// Executes a stored procedure and returns the first column of the first row in the result set as type T. + /// Executes a scalar stored procedure and returns the first column of the first row in the result set. /// /// /// For any arguments which are POCOs, each readable property will be turned into a named parameter for the stored procedure. Arguments which are IDbDataParameters will be passed through. Any other argument types will throw an exception. /// - /// The type that the result value should be cast to. + /// The type of the result value. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// The scalar result of the stored procedure of type T. + /// The scalar result value of type . T ExecuteScalarProc(string storedProcedureName, params object[] args); /// - /// Executes a stored procedure and returns the result as an IEnumerable of type T. + /// Executes a query stored procedure and returns the results as a sequence of type . /// /// /// For any arguments which are POCOs, each readable property will be turned into a named parameter for the stored procedure. Arguments which are IDbDataParameters will be passed through. Any other argument types will throw an exception. /// - /// The Type representing a row in the result set. + /// The POCO type representing a single result record. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// An IEnumerable of type T containing the result set of the stored procedure. + /// An sequence of results. IEnumerable QueryProc(string storedProcedureName, params object[] args); /// - /// Executes a stored procedure and returns the result as a List of type T. + /// Executes a query stored procedure and returns the results as a list of type . /// /// /// For any arguments which are POCOs, each readable property will be turned into a named parameter for the stored procedure. Arguments which are IDbDataParameters will be passed through. Any other argument types will throw an exception. /// - /// The Type representing a row in the result set. + /// The POCO type representing a single result record. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// A List of type T containing the result set of the stored procedure. + /// A containing the results. List FetchProc(string storedProcedureName, params object[] args); } } diff --git a/PetaPoco/IStoredProcAsync.cs b/PetaPoco/IStoredProcAsync.cs index d3e9386e..370d97fc 100644 --- a/PetaPoco/IStoredProcAsync.cs +++ b/PetaPoco/IStoredProcAsync.cs @@ -5,8 +5,9 @@ namespace PetaPoco { +#if ASYNC /// - /// Defines an interface for asynchronously executing stored procedures. + /// Specifies a set of methods for asynchronously executing stored procedures. /// public interface IStoredProcAsync { @@ -20,7 +21,7 @@ public interface IStoredProcAsync Task> QueryProcAsync(string storedProcedureName, params object[] args); /// - Task QueryProcAsync(Action receivePocoCallback, string storedProcedureName, params object[] args); + Task QueryProcAsync(Action action, string storedProcedureName, params object[] args); /// Task> FetchProcAsync(string storedProcedureName, params object[] args); @@ -34,60 +35,61 @@ public interface IStoredProcAsync /// A cancellation token that can be used to cancel the operation. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// A task representing the asynchronous operation. The task result is the number of rows affected by the stored procedure. + /// A task representing the asynchronous operation. The task result is the number of rows affected. Task ExecuteNonQueryProcAsync(CancellationToken cancellationToken, string storedProcedureName, params object[] args); /// - /// Asynchronously executes a stored procedure and returns the first column of the first row in the result set as type T. + /// Asynchronously executes a scalar stored procedure and returns the first column of the first row in the result set. /// /// /// For any arguments which are POCOs, each readable property will be turned into a named parameter for the stored procedure. Arguments which are IDbDataParameters will be passed through. Any other argument types will throw an exception. /// - /// The type that the result value should be cast to. + /// The type of the result value. /// A cancellation token that can be used to cancel the operation. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// A task representing the asynchronous operation. The task result is the scalar result of the stored procedure of type T. + /// A task representing the asynchronous operation. The task result is the scalar result value of type . Task ExecuteScalarProcAsync(CancellationToken cancellationToken, string storedProcedureName, params object[] args); /// - /// Asynchronously executes a stored procedure and returns the result as an IAsyncReader of type T. + /// Asynchronously executes a query stored procedure and returns the results as an IAsyncReader of type . /// /// /// For any arguments which are POCOs, each readable property will be turned into a named parameter for the stored procedure. Arguments which are IDbDataParameters will be passed through. Any other argument types will throw an exception. /// - /// The Type representing a row in the result set. + /// The POCO type representing a single result record. /// A cancellation token that can be used to cancel the operation. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// A task representing the asynchronous operation. The task result is an IAsyncReader of type T containing the result set of the stored procedure. + /// A task representing the asynchronous operation. The task result is an for reading the sequence of results. Task> QueryProcAsync(CancellationToken cancellationToken, string storedProcedureName, params object[] args); /// - /// Asynchronously executes a stored procedure and returns the result as an IAsyncReader of type T. + /// Asynchronously executes a query stored procedure and invokes the specified action on each POCO in the result set. /// /// /// For any arguments which are POCOs, each readable property will be turned into a named parameter for the stored procedure. Arguments which are IDbDataParameters will be passed through. Any other argument types will throw an exception. /// - /// The Type representing a row in the result set. - /// An action callback to execute on each POCO in the result set. + /// The POCO type representing a single result record. + /// An action to perform on each POCO in the result set. /// A cancellation token that can be used to cancel the operation. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// A task representing the asynchronous operation. The task result is an IAsyncReader of type T containing the result set of the stored procedure. - Task QueryProcAsync(Action receivePocoCallback, CancellationToken cancellationToken, string storedProcedureName, params object[] args); + /// A task representing the asynchronous operation. + Task QueryProcAsync(Action action, CancellationToken cancellationToken, string storedProcedureName, params object[] args); /// - /// Asynchronously executes a stored procedure and returns the result as a List of type T. + /// Asynchronously executes a query stored procedure and returns the results as a list of type . /// /// /// For any arguments which are POCOs, each readable property will be turned into a named parameter for the stored procedure. Arguments which are IDbDataParameters will be passed through. Any other argument types will throw an exception. /// - /// The Type representing a row in the result set. + /// The POCO type representing a single result record. /// A cancellation token that can be used to cancel the operation. /// The name of the stored procedure to execute. /// The arguments to pass to the stored procedure. - /// A task representing the asynchronous operation. The task result is a List of type T containing the result set of the stored procedure. + /// A task representing the asynchronous operation. The task result is a list of type containing the results. Task> FetchProcAsync(CancellationToken cancellationToken, string storedProcedureName, params object[] args); } +#endif } diff --git a/PetaPoco/OracleProvider.cs b/PetaPoco/OracleProvider.cs index 50784d6c..760f9faa 100644 --- a/PetaPoco/OracleProvider.cs +++ b/PetaPoco/OracleProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Data.Common; using System.Reflection; @@ -9,8 +9,8 @@ namespace PetaPoco /// /// /// For later versions of Oracle, the standard OracleProviderFactory class should work fine. Uses reflection to load Oracle.DataAccess assembly and in-turn create connections and commands. - /// Thanks to Adam Schroder (@schotime) for this. - /// Currently untested. + /// Thanks to Adam Schroder (@schotime) for this. + /// Currently untested. /// /// /// @@ -53,7 +53,7 @@ public class OracleProvider : DbProviderFactory /// /// Initializes a new instance of the class. /// - /// Thrown when unable to find the connection type from the assembly. + /// Unable to find the connection type from the assembly. public OracleProvider() { _connectionType = TypeFromAssembly(_connectionTypeName, _assemblyName); diff --git a/PetaPoco/Providers/FirebirdDbDatabaseProvider.cs b/PetaPoco/Providers/FirebirdDbDatabaseProvider.cs index b5e7afba..89bda30d 100644 --- a/PetaPoco/Providers/FirebirdDbDatabaseProvider.cs +++ b/PetaPoco/Providers/FirebirdDbDatabaseProvider.cs @@ -28,18 +28,18 @@ public override string BuildPageQuery(long skip, long take, SQLParts parts, ref } /// - public override object ExecuteInsert(Database database, IDbCommand cmd, string primaryKeyName) + public override object ExecuteInsert(Database db, IDbCommand cmd, string primaryKeyName) { PrepareInsert(cmd, primaryKeyName); - return ExecuteScalarHelper(database, cmd); + return ExecuteScalarHelper(db, cmd); } #if ASYNC /// - public override Task ExecuteInsertAsync(CancellationToken cancellationToken, Database database, IDbCommand cmd, string primaryKeyName) + public override Task ExecuteInsertAsync(CancellationToken cancellationToken, Database db, IDbCommand cmd, string primaryKeyName) { PrepareInsert(cmd, primaryKeyName); - return ExecuteScalarHelperAsync(cancellationToken, database, cmd); + return ExecuteScalarHelperAsync(cancellationToken, db, cmd); } #endif diff --git a/PetaPoco/Providers/MsAccessDbDatabaseProvider.cs b/PetaPoco/Providers/MsAccessDbDatabaseProvider.cs index 2bd6cbcf..dd51c435 100644 --- a/PetaPoco/Providers/MsAccessDbDatabaseProvider.cs +++ b/PetaPoco/Providers/MsAccessDbDatabaseProvider.cs @@ -20,20 +20,20 @@ public override DbProviderFactory GetFactory() => GetFactory("System.Data.OleDb.OleDbFactory, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); /// - public override object ExecuteInsert(Database database, IDbCommand cmd, string primaryKeyName) + public override object ExecuteInsert(Database db, IDbCommand cmd, string primaryKeyName) { - ExecuteNonQueryHelper(database, cmd); + ExecuteNonQueryHelper(db, cmd); cmd.CommandText = "SELECT @@IDENTITY AS NewID;"; - return ExecuteScalarHelper(database, cmd); + return ExecuteScalarHelper(db, cmd); } #if ASYNC /// - public override async Task ExecuteInsertAsync(CancellationToken cancellationToken, Database database, IDbCommand cmd, string primaryKeyName) + public override async Task ExecuteInsertAsync(CancellationToken cancellationToken, Database db, IDbCommand cmd, string primaryKeyName) { - await ExecuteNonQueryHelperAsync(cancellationToken, database, cmd).ConfigureAwait(false); + await ExecuteNonQueryHelperAsync(cancellationToken, db, cmd).ConfigureAwait(false); cmd.CommandText = "SELECT @@IDENTITY AS NewID;"; - return await ExecuteScalarHelperAsync(cancellationToken, database, cmd).ConfigureAwait(false); + return await ExecuteScalarHelperAsync(cancellationToken, db, cmd).ConfigureAwait(false); } #endif @@ -41,7 +41,7 @@ public override async Task ExecuteInsertAsync(CancellationToken cancella /// Page queries are not supported by MsAccess database. /// /// This method always throws a . - /// Always thrown because the Access provider does not support paging. + /// The MsAccess provider does not support paging. /// public override string BuildPageQuery(long skip, long take, SQLParts parts, ref object[] args) => throw new NotSupportedException("The Access provider does not support paging."); diff --git a/PetaPoco/Utilities/AsyncReader.cs b/PetaPoco/Utilities/AsyncReader.cs index 485794fd..f0c9069d 100644 --- a/PetaPoco/Utilities/AsyncReader.cs +++ b/PetaPoco/Utilities/AsyncReader.cs @@ -9,7 +9,7 @@ namespace PetaPoco.Utilities /// /// Represents an asynchronous reader that reads a sequence of rows from a data source. /// - /// The type of POCO object to read from the data source. + /// The POCO type representing a single result record. public class AsyncReader : IAsyncReader { private readonly bool _isAsync; @@ -26,14 +26,14 @@ private AsyncReader() /// /// Initializes a new instance of the AsyncReader class. /// - /// The database from which to read data. - /// The command to execute against the database. + /// The database from which to read data. + /// The command to execute against the database. /// The data reader to use for reading data. /// The factory method to be used for when creating POCOs of type . - public AsyncReader(IDatabase db, IDbCommand cmd, IDataReader reader, Func pocoFactory) + public AsyncReader(IDatabase database, IDbCommand command, IDataReader reader, Func pocoFactory) { - _db = db; - _cmd = cmd; + _db = database; + _cmd = command; _reader = reader; _pocoFactory = pocoFactory; _isAsync = reader is DbDataReader; @@ -59,7 +59,7 @@ public async Task ReadAsync() } /// - /// Releases all resources used by the current instance. + /// Disposes the AsyncReader, closing and releasing the underlying , , and shared . /// public void Dispose() { diff --git a/PetaPoco/Utilities/IPagingHelper.cs b/PetaPoco/Utilities/IPagingHelper.cs index d128e308..0d9c438b 100644 --- a/PetaPoco/Utilities/IPagingHelper.cs +++ b/PetaPoco/Utilities/IPagingHelper.cs @@ -6,13 +6,10 @@ namespace PetaPoco.Utilities public interface IPagingHelper { /// - /// Splits the given SQL query into its constituent parts. + /// Splits the given SQL statement into parts, and initializes an instance containing the resulting substrings at . /// - /// - /// This method is used to split a SQL query into its constituent parts for easier manipulation. The parts include the select clause, order by clause, and count clause. - /// - /// The SQL query to split. - /// The parts of the SQL query. + /// The complete SQL statement to be parsed. + /// The destination where the object containing the split parts will be created. /// if the SQL query could be split; otherwise, . bool SplitSQL(string sql, out SQLParts parts); } diff --git a/PetaPoco/Utilities/PagingHelper.cs b/PetaPoco/Utilities/PagingHelper.cs index dff13981..0a4ab396 100644 --- a/PetaPoco/Utilities/PagingHelper.cs +++ b/PetaPoco/Utilities/PagingHelper.cs @@ -8,45 +8,73 @@ namespace PetaPoco.Utilities public class PagingHelper : IPagingHelper { /// - /// Gets the regular expression used for matching the columns in a SELECT statement. + /// Gets the regular expression used for matching the columns in a SELECT statement. /// + /// + /// Beginning at the start of the string, this expression matches the keyword SELECT (inclusive), followed by one or more spaces, capturing everything in front of the word FROM (exclusive), accounting for special handling of nested parentheses, functions, etc. + /// SELECT column1, column2 FROM tbl;
+ /// SELECT SUM(column1) AS sum_col1, column2 FROM tbl; + ///
public Regex RegexColumns { get; } = new Regex( @"\A\s*SELECT\s+((?:\((?>\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(? - /// Gets the regular expression used for matching the DISTINCT keyword. + /// Gets the regular expression used for matching the DISTINCT keyword. /// - public Regex RegexDistinct { get; } = new Regex( - @"\ADISTINCT\s", + /// + /// Starting at the beginning of the string, this expression matches the keyword DISTINCT, followed by a space. + /// SELECT DISTINCT * FROM tbl;
+ /// SELECT DISTINCT column1 FROM tbl; + ///
+ public Regex RegexDistinct { get; } = new Regex(@"\ADISTINCT\s", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); /// - /// Gets the regular expression used for matching the ORDER BY clause. + /// Gets the regular expression used for matching the ORDER BY clause. /// + /// + /// This expression matches the ORDER BY part of the statement, followed by one or more column names as well as the accompanying optional sort order modifier keywords, ASC and DESC, for each (inclusive). AS alias declarations are excluded. + /// SELECT * FROM tbl ORDER BY column1, column2 DESC;
+ /// SELECT column1, column2 AS col2 ORDER BY SUM(column1) ASC, col2;
+ ///
public Regex RegexOrderBy { get; } = new Regex( @"\bORDER\s+BY\s+(?!.*?(?:\)|\s+)AS\s)(?:\((?>\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); /// - /// Gets the regular expression used for matching the simple ORDER BY clause. + /// Gets the regular expression used for matching the simple ORDER BY clause. /// - public Regex SimpleRegexOrderBy { get; } = new Regex( - @"\bORDER\s+BY\s+", + /// + /// Unlike it's more complex big brother, only the ORDER BY keywords are matched. + /// SELECT * FROM tbl ORDER BY column1, column2 DESC;
+ /// SELECT column1, column2 AS col2 ORDER BY SUM(column1) ASC, col2; + ///
+ public Regex SimpleRegexOrderBy { get; } = new Regex(@"\bORDER\s+BY\s+", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); /// - /// Gets the regular expression used for matching the GROUP BY clause. + /// Gets the regular expression used for matching the GROUP BY clause. /// + /// + /// Matches the GROUP BY clause of the statement, followed by one or more column names along with any functions or nested parentheses. AS alias declarations are excluded in a match. + /// SELECT * FROM tbl GROUP BY column1, column2;
+ /// SELECT column1, column2 GROUP BY SUM(column1), column2;
+ /// SELECT column1 AS col1 FROM tbl GROUP BY col1 ORDER BY col1; + ///
public Regex RegexGroupBy { get; } = new Regex( @"\bGROUP\s+BY\s+(?!.*?(?:\)|\s+)AS\s)(?:\((?>\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+?(?:\s*,\s*(?:\((?>\((?)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+?)*", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); /// - /// Gets the regular expression used for matching the simple GROUP BY clause. + /// Gets the regular expression used for matching the simple GROUP BY clause. /// - public Regex SimpleRegexGroupBy { get; } = new Regex( - @"\bGROUP\s+BY\s+", + /// + /// Performs a simple match, for the GROUP BY keywords in a SQL statement. Everything after is excluded. + /// SELECT * FROM tbl GROUP BY column1, column2;
+ /// SELECT column1, COUNT(column2) AS count_col2 FROM tbl GROUP BY column1 ORDER BY column1; + ///
+ public Regex SimpleRegexGroupBy { get; } = new Regex(@"\bGROUP\s+BY\s+", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); /// diff --git a/PetaPoco/Utilities/ParametersHelper.cs b/PetaPoco/Utilities/ParametersHelper.cs index 3457fb98..ddfe2912 100644 --- a/PetaPoco/Utilities/ParametersHelper.cs +++ b/PetaPoco/Utilities/ParametersHelper.cs @@ -47,8 +47,19 @@ public static string EnsureParamPrefix(this int input, string paramPrefix) public static string EnsureParamPrefix(this string input, string paramPrefix) => input.StartsWith(paramPrefix) ? input : NonWordStartRegex.Replace(input, paramPrefix); - // Helper to handle named parameters from object properties - public static string ProcessQueryParams(string sql, object[] args_src, List args_dest) + /// + /// Processes the parameters for a SQL query. + /// + /// + /// Helper method for processing named parameters from object properties. + /// + /// The SQL query to process. + /// The source arguments to be processed. + /// The destination list to store the processed arguments. + /// The SQL query with the parameters processed. + /// The number of parameters is less than the count of numbered parameters in the SQL string. + /// None of the passed parameters have a property with the name used as a named parameter. + public static string ProcessQueryParams(string sql, object[] srcArgs, List destArgs) { return ParamPrefixRegex.Replace(sql, m => { @@ -60,17 +71,16 @@ public static string ProcessQueryParams(string sql, object[] args_src, List= args_src.Length) - throw new ArgumentOutOfRangeException(string.Format("Parameter '@{0}' specified but only {1} parameters supplied (in `{2}`)", paramIndex, args_src.Length, - sql)); - arg_val = args_src[paramIndex]; + if (paramIndex < 0 || paramIndex >= srcArgs.Length) + throw new ArgumentOutOfRangeException(string.Format("Parameter '@{0}' specified but only {1} parameters supplied (in `{2}`)", paramIndex, srcArgs.Length, sql)); + arg_val = srcArgs[paramIndex]; } else { bool found = false; arg_val = null; - foreach (var o in args_src) + foreach (var o in srcArgs) { if (o is IDictionary dict) { @@ -94,8 +104,7 @@ public static string ProcessQueryParams(string sql, object[] args_src, ListThe arguments to be processed. /// An action delegate to set properties of the database parameters. /// An array of database parameters processed from the input arguments. - /// Throws when a value type or string is passed as a stored procedure argument. + /// Value type or string passed as stored procedure argument. public static object[] ProcessStoredProcParams(IDbCommand cmd, object[] args, Action setParameterProperties) { // For a stored proc, we assume that we're only getting POCOs or parameters diff --git a/PetaPoco/Utilities/SQLParts.cs b/PetaPoco/Utilities/SQLParts.cs index 37f50fe0..f90e07d5 100644 --- a/PetaPoco/Utilities/SQLParts.cs +++ b/PetaPoco/Utilities/SQLParts.cs @@ -1,27 +1,27 @@ -namespace PetaPoco.Utilities +namespace PetaPoco.Utilities { /// - /// Presents the SQL parts. + /// Represents a parsed SQL statement, providing access to its constituent parts for convenient modification and rebuilding. /// public struct SQLParts { /// - /// The SQL statement. + /// Gets or sets the complete SQL statement. /// public string Sql; /// - /// The SQL count. + /// Gets or sets the COUNT clause of the SQL statement, used for operations such as Exists and paged requests. /// public string SqlCount; /// - /// The SQL Select. + /// Gets or sets the SQL statement with the SELECT clause removed, for generating auto-select queries. /// public string SqlSelectRemoved; /// - /// The SQL OrderBy. + /// Gets or sets the ORDER BY clause of the SQL statement, used for sorting the records. /// public string SqlOrderBy; }