Commit 6745addf authored by Nick Craver's avatar Nick Craver

Documentation and formatting: secondary types

parent 4d75b982
......@@ -73,9 +73,28 @@ internal void OnCompleted()
/// </summary>
public bool Pipelined => (Flags & CommandFlags.Pipelined) != 0;
#if ASYNC
/// <summary>
/// Initialize the command definition
/// </summary>
/// <param name="commandText">The text for this command.</param>
/// <param name="parameters">The parameters for this command.</param>
/// <param name="transaction">The transaction for this command to participate in.</param>
/// <param name="commandTimeout">The timeout (in seconds) for this command.</param>
/// <param name="commandType">The <see cref="CommandType"/> for this command.</param>
/// <param name="flags">The behavior flags for this command.</param>
/// <param name="cancellationToken">The cancellation token for this command.</param>
#else
/// <summary>
/// Initialize the command definition
/// </summary>
/// <param name="commandText">The text for this command.</param>
/// <param name="parameters">The parameters for this command.</param>
/// <param name="transaction">The transaction for this command to participate in.</param>
/// <param name="commandTimeout">The timeout (in seconds) for this command.</param>
/// <param name="commandType">The <see cref="CommandType"/> for this command.</param>
/// <param name="flags">The behavior flags for this command.</param>
#endif
public CommandDefinition(string commandText, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null,
CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered
#if ASYNC
......@@ -182,4 +201,4 @@ private static MethodInfo GetBasicPropertySetter(Type declaringType, string name
return null;
}
}
}
}
\ No newline at end of file
......@@ -93,8 +93,13 @@ public void AddDynamicParams(object param)
}
/// <summary>
/// Add a parameter to this dynamic parameter list
/// Add a parameter to this dynamic parameter list.
/// </summary>
/// <param name="name">The name of the parameter.</param>
/// <param name="value">The value of the parameter.</param>
/// <param name="dbType">The type of the parameter.</param>
/// <param name="direction">The in or out direction of the parameter.</param>
/// <param name="size">The size of the parameter.</param>
public void Add(string name, object value, DbType? dbType, ParameterDirection? direction, int? size)
{
parameters[Clean(name)] = new ParamInfo
......@@ -108,11 +113,16 @@ public void Add(string name, object value, DbType? dbType, ParameterDirection? d
}
/// <summary>
/// Add a parameter to this dynamic parameter list
/// Add a parameter to this dynamic parameter list.
/// </summary>
public void Add(
string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null, byte? precision = null, byte? scale = null
)
/// <param name="name">The name of the parameter.</param>
/// <param name="value">The value of the parameter.</param>
/// <param name="dbType">The type of the parameter.</param>
/// <param name="direction">The in or out direction of the parameter.</param>
/// <param name="size">The size of the parameter.</param>
/// <param name="precision">The precision of the parameter.</param>
/// <param name="scale">The scale of the parameter.</param>
public void Add(string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null, byte? precision = null, byte? scale = null)
{
parameters[Clean(name)] = new ParamInfo
{
......
......@@ -15,6 +15,7 @@ private static readonly FeatureSupport
/// <summary>
/// Gets the feature set based on the passed connection
/// </summary>
/// <param name="connection">The connection to get supported features for.</param>
public static FeatureSupport Get(IDbConnection connection)
{
string name = connection?.GetType().Name;
......@@ -26,6 +27,7 @@ private FeatureSupport(bool arrays)
{
Arrays = arrays;
}
/// <summary>
/// True if the db supports array columns e.g. Postgresql
/// </summary>
......
......@@ -13,8 +13,10 @@ internal sealed class SqlDataRecordListTVPParameter : SqlMapper.ICustomQueryPara
private readonly IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> data;
private readonly string typeName;
/// <summary>
/// Create a new instance of SqlDataRecordListTVPParameter
/// Create a new instance of <see cref="SqlDataRecordListTVPParameter"/>.
/// </summary>
/// <param name="data">The data records to convert into TVPs.</param>
/// <param name="typeName">The parameter type name.</param>
public SqlDataRecordListTVPParameter(IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> data, string typeName)
{
this.data = data;
......
......@@ -23,7 +23,7 @@ public DapperRow(DapperTable table, object[] values)
private sealed class DeadValue
{
public static readonly DeadValue Default = new DeadValue();
private DeadValue() { }
private DeadValue() { /* hiding constructor */ }
}
int ICollection<KeyValuePair<string, object>>.Count
......
......@@ -5,6 +5,6 @@ public static partial class SqlMapper
/// <summary>
/// Dummy type for excluding from multi-map
/// </summary>
private class DontMap { }
private class DontMap { /* hiding constructor */ }
}
}
......@@ -213,7 +213,7 @@ private async Task<T> ReadRowAsyncImplViaDbReader<T>(DbDataReader reader, Type t
}
result = (T)deserializer.Func(reader);
if ((row & Row.Single) != 0 && await reader.ReadAsync(cancel).ConfigureAwait(false)) ThrowMultipleRows(row);
while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { }
while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { /* ignore subsequent rows */ }
}
else if ((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one
{
......
......@@ -192,7 +192,7 @@ private T ReadRow<T>(Type type, Row row)
result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
}
if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row);
while (reader.Read()) { }
while (reader.Read()) { /* ignore subsequent rows */ }
}
else if((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one
{
......
......@@ -9,9 +9,11 @@ public static partial class SqlMapper
/// <summary>
/// Parses a data reader to a sequence of data of the supplied type. Used for deserializing a reader without a connection, etc.
/// </summary>
/// <typeparam name="T">The type to parse from the <paramref name="reader"/>.</typeparam>
/// <param name="reader">The data reader to parse results from.</param>
public static IEnumerable<T> Parse<T>(this IDataReader reader)
{
if(reader.Read())
if (reader.Read())
{
var deser = GetDeserializer(typeof(T), reader, 0, -1, false);
do
......@@ -24,6 +26,8 @@ public static IEnumerable<T> Parse<T>(this IDataReader reader)
/// <summary>
/// Parses a data reader to a sequence of data of the supplied type (as object). Used for deserializing a reader without a connection, etc.
/// </summary>
/// <param name="reader">The data reader to parse results from.</param>
/// <param name="type">The type to parse from the <paramref name="reader"/>.</param>
public static IEnumerable<object> Parse(this IDataReader reader, Type type)
{
if (reader.Read())
......@@ -39,6 +43,7 @@ public static IEnumerable<object> Parse(this IDataReader reader, Type type)
/// <summary>
/// Parses a data reader to a sequence of dynamic. Used for deserializing a reader without a connection, etc.
/// </summary>
/// <param name="reader">The data reader to parse results from.</param>
public static IEnumerable<dynamic> Parse(this IDataReader reader)
{
if (reader.Read())
......@@ -71,11 +76,12 @@ public static IEnumerable<dynamic> Parse(this IDataReader reader)
/// Gets the row parser for a specific row on a data reader. This allows for type switching every row based on, for example, a TypeId column.
/// You could return a collection of the base type but have each more specific.
/// </summary>
/// <param name="reader">The data reader to get the parser for the current row from</param>
/// <param name="concreteType">The type to get the parser for</param>
/// <param name="startIndex">The start column index of the object (default 0)</param>
/// <param name="length">The length of columns to read (default -1 = all fields following startIndex)</param>
/// <param name="returnNullIfFirstMissing">Return null if we can't find the first column? (default false)</param>
/// <typeparam name="T">The type of results to return.</typeparam>
/// <param name="reader">The data reader to get the parser for the current row from.</param>
/// <param name="concreteType">The type to get the parser for.</param>
/// <param name="startIndex">The start column index of the object (default: 0).</param>
/// <param name="length">The length of columns to read (default: -1 = all fields following startIndex).</param>
/// <param name="returnNullIfFirstMissing">Return null if we can't find the first column? (default: false).</param>
/// <returns>A parser for this specific object from this row.</returns>
/// <example>
/// var result = new List&lt;BaseType&gt;();
......
......@@ -10,6 +10,7 @@ public interface IParameterLookup : IDynamicParameters
/// <summary>
/// Get the value of the specified parameter (return null if not found)
/// </summary>
/// <param name="name">The name of the parameter to get.</param>
object this[string name] { get; }
}
}
......
......@@ -6,32 +6,27 @@ namespace Dapper
public static partial class SqlMapper
{
/// <summary>
/// Identity of a cached query in Dapper, used for extensibility
/// Identity of a cached query in Dapper, used for extensibility.
/// </summary>
public class Identity : IEquatable<Identity>
{
internal Identity ForGrid(Type primaryType, int gridIndex)
{
return new Identity(sql, commandType, connectionString, primaryType, parametersType, null, gridIndex);
}
internal Identity ForGrid(Type primaryType, int gridIndex) =>
new Identity(sql, commandType, connectionString, primaryType, parametersType, null, gridIndex);
internal Identity ForGrid(Type primaryType, Type[] otherTypes, int gridIndex) =>
new Identity(sql, commandType, connectionString, primaryType, parametersType, otherTypes, gridIndex);
internal Identity ForGrid(Type primaryType, Type[] otherTypes, int gridIndex)
{
return new Identity(sql, commandType, connectionString, primaryType, parametersType, otherTypes, gridIndex);
}
/// <summary>
/// Create an identity for use with DynamicParameters, internal use only
/// Create an identity for use with DynamicParameters, internal use only.
/// </summary>
/// <param name="type"></param>
/// <param name="type">The parameters type to create an <see cref="Identity"/> for.</param>
/// <returns></returns>
public Identity ForDynamicParameters(Type type)
{
return new Identity(sql, commandType, connectionString, this.type, type, null, -1);
}
public Identity ForDynamicParameters(Type type) =>
new Identity(sql, commandType, connectionString, this.type, type, null, -1);
internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, Type[] otherTypes)
: this(sql, commandType, connection.ConnectionString, type, parametersType, otherTypes, 0)
{ }
: this(sql, commandType, connection.ConnectionString, type, parametersType, otherTypes, 0) { /* base call */ }
private Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex)
{
this.sql = sql;
......@@ -43,19 +38,19 @@ private Identity(string sql, CommandType? commandType, string connectionString,
unchecked
{
hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this
hashCode = hashCode * 23 + commandType.GetHashCode();
hashCode = hashCode * 23 + gridIndex.GetHashCode();
hashCode = hashCode * 23 + (sql?.GetHashCode() ?? 0);
hashCode = hashCode * 23 + (type?.GetHashCode() ?? 0);
hashCode = (hashCode * 23) + commandType.GetHashCode();
hashCode = (hashCode * 23) + gridIndex.GetHashCode();
hashCode = (hashCode * 23) + (sql?.GetHashCode() ?? 0);
hashCode = (hashCode * 23) + (type?.GetHashCode() ?? 0);
if (otherTypes != null)
{
foreach (var t in otherTypes)
{
hashCode = hashCode * 23 + (t?.GetHashCode() ?? 0);
hashCode = (hashCode * 23) + (t?.GetHashCode() ?? 0);
}
}
hashCode = hashCode * 23 + (connectionString == null ? 0 : connectionStringComparer.GetHashCode(connectionString));
hashCode = hashCode * 23 + (parametersType?.GetHashCode() ?? 0);
hashCode = (hashCode * 23) + (connectionString == null ? 0 : connectionStringComparer.GetHashCode(connectionString));
hashCode = (hashCode * 23) + (parametersType?.GetHashCode() ?? 0);
}
}
......@@ -63,10 +58,7 @@ private Identity(string sql, CommandType? commandType, string connectionString,
/// Whether this <see cref="Identity"/> equals another.
/// </summary>
/// <param name="obj">The other <see cref="object"/> to compare to.</param>
public override bool Equals(object obj)
{
return Equals(obj as Identity);
}
public override bool Equals(object obj) => Equals(obj as Identity);
/// <summary>
/// The raw SQL command.
......
......@@ -9,6 +9,8 @@ public static partial class SqlMapper
/// and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE**
/// equality. The type is fully thread-safe.
/// </summary>
/// <typeparam name="TKey">The type to cache.</typeparam>
/// <typeparam name="TValue">The value type of the cache.</typeparam>
internal class Link<TKey, TValue> where TKey : class
{
public static bool TryGet(Link<TKey, TValue> link, TKey key, out TValue value)
......
......@@ -8,6 +8,7 @@ public static partial class SqlMapper
/// <summary>
/// Base-class for simple type-handlers
/// </summary>
/// <typeparam name="T">This <see cref="Type"/> this handler is for.</typeparam>
public abstract class TypeHandler<T> : ITypeHandler
{
/// <summary>
......@@ -41,19 +42,25 @@ object ITypeHandler.Parse(Type destinationType, object value)
return Parse(value);
}
}
/// <summary>
/// Base-class for simple type-handlers that are based around strings
/// </summary>
/// <typeparam name="T">This <see cref="Type"/> this handler is for.</typeparam>
public abstract class StringTypeHandler<T> : TypeHandler<T>
{
/// <summary>
/// Parse a string into the expected type (the string will never be null)
/// </summary>
/// <param name="xml">The string to parse.</param>
protected abstract T Parse(string xml);
/// <summary>
/// Format an instace into a string (the instance will never be null)
/// </summary>
/// <param name="xml">The string to format.</param>
protected abstract string Format(T xml);
/// <summary>
/// Assign the value of a parameter before a command executes
/// </summary>
......@@ -63,6 +70,7 @@ public override void SetValue(IDbDataParameter parameter, T value)
{
parameter.Value = value == null ? (object)DBNull.Value : Format(value);
}
/// <summary>
/// Parse a database value back to a typed value
/// </summary>
......
......@@ -9,6 +9,7 @@ public static partial class SqlMapper
/// <summary>
/// Not intended for direct usage
/// </summary>
/// <typeparam name="T">The type to have a cache for.</typeparam>
[Obsolete(ObsoleteInternalUsageOnly, false)]
#if !COREFX
[Browsable(false)]
......@@ -17,22 +18,19 @@ public static partial class SqlMapper
public static class TypeHandlerCache<T>
{
/// <summary>
/// Not intended for direct usage
/// Not intended for direct usage.
/// </summary>
/// <param name="value">The object to parse.</param>
[Obsolete(ObsoleteInternalUsageOnly, true)]
public static T Parse(object value)
{
return (T)handler.Parse(typeof(T), value);
}
public static T Parse(object value) => (T)handler.Parse(typeof(T), value);
/// <summary>
/// Not intended for direct usage
/// Not intended for direct usage.
/// </summary>
/// <param name="parameter">The parameter to set a value for.</param>
/// <param name="value">The value to set.</param>
[Obsolete(ObsoleteInternalUsageOnly, true)]
public static void SetValue(IDbDataParameter parameter, object value)
{
handler.SetValue(parameter, value);
}
public static void SetValue(IDbDataParameter parameter, object value) => handler.SetValue(parameter, value);
internal static void SetHandler(ITypeHandler handler)
{
......
......@@ -14,12 +14,16 @@ internal sealed class TableValuedParameter : SqlMapper.ICustomQueryParameter
private readonly string typeName;
/// <summary>
/// Create a new instance of TableValuedParameter
/// Create a new instance of <see cref="TableValuedParameter"/>.
/// </summary>
public TableValuedParameter(DataTable table) : this(table, null) { }
/// <param name="table">The <see cref="DataTable"/> to create this parameter for</param>
public TableValuedParameter(DataTable table) : this(table, null) { /* run base */ }
/// <summary>
/// Create a new instance of TableValuedParameter
/// Create a new instance of <see cref="TableValuedParameter"/>.
/// </summary>
/// <param name="table">The <see cref="DataTable"/> to create this parameter for.</param>
/// <param name="typeName">The name of the type this parameter is for.</param>
public TableValuedParameter(DataTable table, string typeName)
{
this.table = table;
......@@ -54,13 +58,10 @@ internal static void Set(IDbDataParameter parameter, DataTable table, string typ
{
typeName = table.GetTypeName();
}
if (!string.IsNullOrEmpty(typeName))
if (!string.IsNullOrEmpty(typeName) && (parameter is System.Data.SqlClient.SqlParameter sqlParam))
{
if (parameter is System.Data.SqlClient.SqlParameter sqlParam)
{
setTypeName?.Invoke(sqlParam, typeName);
sqlParam.SqlDbType = SqlDbType.Structured;
}
setTypeName?.Invoke(sqlParam, typeName);
sqlParam.SqlDbType = SqlDbType.Structured;
}
}
}
......
......@@ -14,8 +14,9 @@ public class UdtTypeHandler : ITypeHandler
{
private readonly string udtTypeName;
/// <summary>
/// Creates a new instance of UdtTypeHandler with the specified UdtTypeName
/// Creates a new instance of UdtTypeHandler with the specified <see cref="UdtTypeHandler"/>.
/// </summary>
/// <param name="udtTypeName">The user defined type name.</param>
public UdtTypeHandler(string udtTypeName)
{
if (string.IsNullOrEmpty(udtTypeName)) throw new ArgumentException("Cannot be null or empty", udtTypeName);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment