Commit 12886d80 authored by Nick Craver's avatar Nick Craver

Merge pull request #391 from henkmollema/code-cleanup2

Code cleanup - take 2
parents 295d1ad2 c28a87ff
......@@ -18,9 +18,10 @@
#endif
namespace Dapper
{ /// <summary>
/// Represents the key aspects of a sql operation
/// </summary>
{
/// <summary>
/// Represents the key aspects of a sql operation
/// </summary>
public struct CommandDefinition
{
internal static CommandDefinition ForCallback(object parameters)
......@@ -34,125 +35,119 @@ internal static CommandDefinition ForCallback(object parameters)
return default(CommandDefinition);
}
}
private readonly string commandText;
private readonly object parameters;
private readonly IDbTransaction transaction;
private readonly int? commandTimeout;
private readonly CommandType? commandType;
private readonly CommandFlags flags;
internal void OnCompleted()
{
if (parameters is SqlMapper.IParameterCallbacks)
{
((SqlMapper.IParameterCallbacks)parameters).OnCompleted();
}
(Parameters as SqlMapper.IParameterCallbacks)?.OnCompleted();
}
/// <summary>
/// The command (sql or a stored-procedure name) to execute
/// </summary>
public string CommandText { get { return commandText; } }
public string CommandText { get; }
/// <summary>
/// The parameters associated with the command
/// </summary>
public object Parameters { get { return parameters; } }
public object Parameters { get; }
/// <summary>
/// The active transaction for the command
/// </summary>
public IDbTransaction Transaction { get { return transaction; } }
public IDbTransaction Transaction { get; }
/// <summary>
/// The effective timeout for the command
/// </summary>
public int? CommandTimeout { get { return commandTimeout; } }
public int? CommandTimeout { get; }
/// <summary>
/// The type of command that the command-text represents
/// </summary>
public CommandType? CommandType { get { return commandType; } }
public CommandType? CommandType { get; }
/// <summary>
/// Should data be buffered before returning?
/// </summary>
public bool Buffered { get { return (flags & CommandFlags.Buffered) != 0; } }
public bool Buffered => (Flags & CommandFlags.Buffered) != 0;
/// <summary>
/// Should the plan for this query be cached?
/// </summary>
internal bool AddToCache { get { return (flags & CommandFlags.NoCache) == 0; } }
internal bool AddToCache => (Flags & CommandFlags.NoCache) == 0;
/// <summary>
/// Additional state flags against this command
/// </summary>
public CommandFlags Flags { get { return flags; } }
public CommandFlags Flags { get; }
/// <summary>
/// Can async queries be pipelined?
/// </summary>
public bool Pipelined { get { return (flags & CommandFlags.Pipelined) != 0; } }
public bool Pipelined => (Flags & CommandFlags.Pipelined) != 0;
/// <summary>
/// Initialize the command definition
/// </summary>
public CommandDefinition(string commandText, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null,
CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered
CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered
#if ASYNC
, CancellationToken cancellationToken = default(CancellationToken)
, CancellationToken cancellationToken = default(CancellationToken)
#endif
)
{
this.commandText = commandText;
this.parameters = parameters;
this.transaction = transaction;
this.commandTimeout = commandTimeout;
this.commandType = commandType;
this.flags = flags;
CommandText = commandText;
Parameters = parameters;
Transaction = transaction;
CommandTimeout = commandTimeout;
CommandType = commandType;
Flags = flags;
#if ASYNC
this.cancellationToken = cancellationToken;
CancellationToken = cancellationToken;
#endif
}
private CommandDefinition(object parameters) : this()
{
this.parameters = parameters;
Parameters = parameters;
}
#if ASYNC
private readonly CancellationToken cancellationToken;
/// <summary>
/// For asynchronous operations, the cancellation-token
/// </summary>
public CancellationToken CancellationToken { get { return cancellationToken; } }
public CancellationToken CancellationToken { get; }
#endif
internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object> paramReader)
{
var cmd = cnn.CreateCommand();
var init = GetInit(cmd.GetType());
if (init != null) init(cmd);
if (transaction != null)
cmd.Transaction = transaction;
cmd.CommandText = commandText;
if (commandTimeout.HasValue)
init?.Invoke(cmd);
if (Transaction != null)
cmd.Transaction = Transaction;
cmd.CommandText = CommandText;
if (CommandTimeout.HasValue)
{
cmd.CommandTimeout = commandTimeout.Value;
cmd.CommandTimeout = CommandTimeout.Value;
}
else if (SqlMapper.Settings.CommandTimeout.HasValue)
{
cmd.CommandTimeout = SqlMapper.Settings.CommandTimeout.Value;
}
if (commandType.HasValue)
cmd.CommandType = commandType.Value;
if (paramReader != null)
{
paramReader(cmd, parameters);
}
if (CommandType.HasValue)
cmd.CommandType = CommandType.Value;
paramReader?.Invoke(cmd, Parameters);
return cmd;
}
static SqlMapper.Link<Type, Action<IDbCommand>> commandInitCache;
static Action<IDbCommand> GetInit(Type commandType)
private static SqlMapper.Link<Type, Action<IDbCommand>> commandInitCache;
private static Action<IDbCommand> GetInit(Type commandType)
{
if (commandType == null) return null; // GIGO
if (commandType == null)
return null; // GIGO
Action<IDbCommand> action;
if (SqlMapper.Link<Type, Action<IDbCommand>>.TryGet(commandInitCache, commandType, out action))
{
......@@ -186,11 +181,12 @@ static Action<IDbCommand> GetInit(Type commandType)
il.Emit(OpCodes.Ret);
action = (Action<IDbCommand>)method.CreateDelegate(typeof(Action<IDbCommand>));
}
// cache it
// cache it
SqlMapper.Link<Type, Action<IDbCommand>>.TryAdd(ref commandInitCache, commandType, ref action);
return action;
}
static MethodInfo GetBasicPropertySetter(Type declaringType, string name, Type expectedType)
private static MethodInfo GetBasicPropertySetter(Type declaringType, string name, Type expectedType)
{
var prop = declaringType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
ParameterInfo[] indexers;
......
......@@ -20,10 +20,10 @@ public sealed class CustomPropertyTypeMap : SqlMapper.ITypeMap
public CustomPropertyTypeMap(Type type, Func<Type, string, PropertyInfo> propertySelector)
{
if (type == null)
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(type));
if (propertySelector == null)
throw new ArgumentNullException("propertySelector");
throw new ArgumentNullException(nameof(propertySelector));
_type = type;
_propertySelector = propertySelector;
......
......@@ -3,7 +3,7 @@
#if !DNXCORE50
namespace Dapper
{
sealed class DataTableHandler : Dapper.SqlMapper.ITypeHandler
sealed class DataTableHandler : SqlMapper.ITypeHandler
{
public object Parse(Type destinationType, object value)
{
......
......@@ -19,7 +19,7 @@ namespace Dapper
/// <summary>
/// This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar
/// </summary>
public sealed class DbString : Dapper.SqlMapper.ICustomQueryParameter
public sealed class DbString : SqlMapper.ICustomQueryParameter
{
/// <summary>
/// Default value for IsAnsi.
......
......@@ -11,7 +11,6 @@ namespace Dapper
sealed class DefaultTypeMap : SqlMapper.ITypeMap
{
private readonly List<FieldInfo> _fields;
private readonly List<PropertyInfo> _properties;
private readonly Type _type;
/// <summary>
......@@ -21,10 +20,10 @@ sealed class DefaultTypeMap : SqlMapper.ITypeMap
public DefaultTypeMap(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(type));
_fields = GetSettableFields(type);
_properties = GetSettableProps(type);
Properties = GetSettableProps(type);
_type = type;
}
#if DNXCORE50
......@@ -184,12 +183,6 @@ public SqlMapper.IMemberMap GetMember(string columnName)
/// </summary>
public static bool MatchNamesWithUnderscores { get; set; }
public List<PropertyInfo> Properties
{
get
{
return _properties;
}
}
public List<PropertyInfo> Properties { get; }
}
}
......@@ -198,7 +198,7 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
appender(command, template);
}
// The parameters were added to the command, but not the
// The parameters were added to the command, but not the
// DynamicParameters until now.
foreach (IDbDataParameter param in command.Parameters)
{
......@@ -246,7 +246,7 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
((SqlMapper.ICustomQueryParameter)val).AddParameter(command, name);
}
else if (dbType == DynamicParameters.EnumerableMultiParameter)
else if (dbType == EnumerableMultiParameter)
{
#pragma warning disable 612, 618
SqlMapper.PackListParameters(command, name, val);
......@@ -276,12 +276,9 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
p.DbType = dbType.Value;
}
var s = val as string;
if (s != null)
if (s?.Length <= DbString.DefaultLength)
{
if (s.Length <= DbString.DefaultLength)
{
p.Size = DbString.DefaultLength;
}
p.Size = DbString.DefaultLength;
}
if (param.Size != null) p.Size = param.Size.Value;
if (param.Precision != null) p.Precision = param.Precision.Value;
......@@ -344,7 +341,7 @@ public T Get<T>(string name)
/// <summary>
/// Allows you to automatically populate a target property/field from output parameters. It actually
/// creates an InputOutput parameter, so you can still pass data in.
/// creates an InputOutput parameter, so you can still pass data in.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="target">The object whose property/field you wish to populate.</param>
......@@ -383,13 +380,13 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
do
{
// Insert the names in the right order so expression
// Insert the names in the right order so expression
// "Post.Author.Name" becomes parameter "PostAuthorName"
names.Insert(0, diving.Member.Name);
names.Insert(0, diving?.Member.Name);
chain.Insert(0, diving);
var constant = diving.Expression as ParameterExpression;
diving = diving.Expression as MemberExpression;
var constant = diving?.Expression as ParameterExpression;
diving = diving?.Expression as MemberExpression;
if (constant != null &&
constant.Type == typeof(T))
......@@ -423,7 +420,7 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
if (setter != null) goto MAKECALLBACK;
// Come on let's build a method, let's build it, let's build it now!
var dm = new DynamicMethod(string.Format("ExpressionParam{0}", Guid.NewGuid()), null, new[] { typeof(object), this.GetType() }, true);
var dm = new DynamicMethod($"ExpressionParam{Guid.NewGuid()}", null, new[] { typeof(object), GetType() }, true);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // [object]
......@@ -446,7 +443,7 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
}
}
var paramGetter = this.GetType().GetMethod("Get", new Type[] { typeof(string) }).MakeGenericMethod(lastMemberAccess.Type);
var paramGetter = GetType().GetMethod("Get", new Type[] { typeof(string) }).MakeGenericMethod(lastMemberAccess.Type);
il.Emit(OpCodes.Ldarg_1); // [target] [DynamicParameters]
il.Emit(OpCodes.Ldstr, dynamicParamName); // [target] [DynamicParameters] [ParamName]
......@@ -478,10 +475,10 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
{
// Finally, prep the parameter and attach the callback to it
ParamInfo parameter;
var targetMemberType = lastMemberAccess.Type;
var targetMemberType = lastMemberAccess?.Type;
int sizeToSet = (!size.HasValue && targetMemberType == typeof(string)) ? DbString.DefaultLength : size ?? 0;
if (this.parameters.TryGetValue(dynamicParamName, out parameter))
if (parameters.TryGetValue(dynamicParamName, out parameter))
{
parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput;
......@@ -493,14 +490,14 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
else
{
SqlMapper.ITypeHandler handler;
dbType = (!dbType.HasValue) ? SqlMapper.LookupDbType(targetMemberType, targetMemberType.Name, true, out handler) : dbType;
dbType = (!dbType.HasValue) ? SqlMapper.LookupDbType(targetMemberType, targetMemberType?.Name, true, out handler) : dbType;
// CameFromTemplate property would not apply here because this new param
// Still needs to be added to the command
this.Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet);
Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet);
}
parameter = this.parameters[dynamicParamName];
parameter = parameters[dynamicParamName];
parameter.OutputCallback = setter;
parameter.OutputTarget = target;
});
......@@ -518,7 +515,7 @@ void SqlMapper.IParameterCallbacks.OnCompleted()
{
foreach (var param in (from p in parameters select p.Value))
{
if (param.OutputCallback != null) param.OutputCallback(param.OutputTarget, this);
param.OutputCallback?.Invoke(param.OutputTarget, this);
}
}
}
......
......@@ -28,7 +28,7 @@ private static readonly FeatureSupport
/// </summary>
public static FeatureSupport Get(IDbConnection connection)
{
string name = connection == null ? null : connection.GetType().Name;
string name = connection?.GetType().Name;
if (string.Equals(name, "npgsqlconnection", StringComparison.OrdinalIgnoreCase)) return postgres;
return @default;
}
......@@ -39,7 +39,7 @@ private FeatureSupport(bool arrays)
/// <summary>
/// True if the db supports array columns e.g. Postgresql
/// </summary>
public bool Arrays { get; private set; }
public bool Arrays { get; }
}
}
......@@ -8,11 +8,6 @@ namespace Dapper
/// </summary>
sealed class SimpleMemberMap : SqlMapper.IMemberMap
{
private readonly string _columnName;
private readonly PropertyInfo _property;
private readonly FieldInfo _field;
private readonly ParameterInfo _parameter;
/// <summary>
/// Creates instance for simple property mapping
/// </summary>
......@@ -21,13 +16,13 @@ sealed class SimpleMemberMap : SqlMapper.IMemberMap
public SimpleMemberMap(string columnName, PropertyInfo property)
{
if (columnName == null)
throw new ArgumentNullException("columnName");
throw new ArgumentNullException(nameof(columnName));
if (property == null)
throw new ArgumentNullException("property");
throw new ArgumentNullException(nameof(property));
_columnName = columnName;
_property = property;
ColumnName = columnName;
Property = property;
}
/// <summary>
......@@ -38,13 +33,13 @@ public SimpleMemberMap(string columnName, PropertyInfo property)
public SimpleMemberMap(string columnName, FieldInfo field)
{
if (columnName == null)
throw new ArgumentNullException("columnName");
throw new ArgumentNullException(nameof(columnName));
if (field == null)
throw new ArgumentNullException("field");
throw new ArgumentNullException(nameof(field));
_columnName = columnName;
_field = field;
ColumnName = columnName;
Field = field;
}
/// <summary>
......@@ -55,66 +50,39 @@ public SimpleMemberMap(string columnName, FieldInfo field)
public SimpleMemberMap(string columnName, ParameterInfo parameter)
{
if (columnName == null)
throw new ArgumentNullException("columnName");
throw new ArgumentNullException(nameof(columnName));
if (parameter == null)
throw new ArgumentNullException("parameter");
throw new ArgumentNullException(nameof(parameter));
_columnName = columnName;
_parameter = parameter;
ColumnName = columnName;
Parameter = parameter;
}
/// <summary>
/// DataReader column name
/// </summary>
public string ColumnName
{
get { return _columnName; }
}
public string ColumnName { get; }
/// <summary>
/// Target member type
/// </summary>
public Type MemberType
{
get
{
if (_field != null)
return _field.FieldType;
if (_property != null)
return _property.PropertyType;
if (_parameter != null)
return _parameter.ParameterType;
return null;
}
}
public Type MemberType => Field?.FieldType ?? Property?.PropertyType ?? Parameter?.ParameterType;
/// <summary>
/// Target property
/// </summary>
public PropertyInfo Property
{
get { return _property; }
}
public PropertyInfo Property { get; }
/// <summary>
/// Target field
/// </summary>
public FieldInfo Field
{
get { return _field; }
}
public FieldInfo Field { get; }
/// <summary>
/// Target constructor parameter
/// </summary>
public ParameterInfo Parameter
{
get { return _parameter; }
}
public ParameterInfo Parameter { get; }
}
}
......@@ -5,7 +5,7 @@
#if !DNXCORE50
namespace Dapper
{
sealed class SqlDataRecordHandler : Dapper.SqlMapper.ITypeHandler
sealed class SqlDataRecordHandler : SqlMapper.ITypeHandler
{
public object Parse(Type destinationType, object value)
{
......
......@@ -9,7 +9,7 @@ namespace Dapper
/// <summary>
/// Used to pass a IEnumerable&lt;SqlDataRecord&gt; as a SqlDataRecordListTVPParameter
/// </summary>
sealed class SqlDataRecordListTVPParameter : Dapper.SqlMapper.ICustomQueryParameter
sealed class SqlDataRecordListTVPParameter : SqlMapper.ICustomQueryParameter
{
private readonly IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> data;
private readonly string typeName;
......
......@@ -60,7 +60,7 @@ public static Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, string
/// </summary>
public static Task<IEnumerable<object>> QueryAsync(this IDbConnection cnn, Type type, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
if (type == null) throw new ArgumentNullException("type");
if (type == null) throw new ArgumentNullException(nameof(type));
return QueryAsync<object>(cnn, type, new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken)));
}
......@@ -83,7 +83,7 @@ public static Task<IEnumerable<object>> QueryAsync(this IDbConnection cnn, Type
private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, Type effectiveType, CommandDefinition command)
{
object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType(), null);
var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed;
var cancel = command.CancellationToken;
......@@ -94,7 +94,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
{
if (wasClosed) await ((DbConnection)cnn).OpenAsync(cancel).ConfigureAwait(false);
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, cancel).ConfigureAwait(false);
var tuple = info.Deserializer;
int hash = GetColumnHash(reader);
if (tuple.Func == null || tuple.Hash != hash)
......@@ -121,7 +121,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
buffer.Add((T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture));
}
}
while (await reader.NextResultAsync(cancel).ConfigureAwait(false)) { }
command.OnCompleted();
......@@ -135,13 +135,13 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
reader = null; // to prevent it being disposed before the caller gets to see it
return deferred;
}
}
finally
{
using (reader) { } // dispose if non-null
if (wasClosed) cnn.Close();
}
}
}
......@@ -170,15 +170,15 @@ public static Task<int> ExecuteAsync(this IDbConnection cnn, CommandDefinition c
return ExecuteImplAsync(cnn, command, param);
}
}
private struct AsyncExecState
{
public readonly DbCommand Command;
public readonly Task<int> Task;
public AsyncExecState(DbCommand command, Task<int> task)
{
this.Command = command;
this.Task = task;
Command = command;
Task = task;
}
}
private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandDefinition command, IEnumerable multiExec)
......@@ -189,7 +189,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
try
{
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
CacheInfo info = null;
string masterSql = null;
if ((command.Flags & CommandFlags.Pipelined) != 0)
......@@ -276,7 +276,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
}
private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, object param)
{
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param == null ? null : param.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param?.GetType(), null);
var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed;
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
......@@ -503,15 +503,15 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
/// <param name="commandTimeout">Number of seconds before command execution timeout</param>
/// <param name="commandType">Is it a stored proc or a batch?</param>
/// <returns></returns>
public static Task<IEnumerable<TReturn>> QueryAsync<TReturn>(this IDbConnection cnn, string sql, Type[] types, Func<object[], TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
public static Task<IEnumerable<TReturn>> QueryAsync<TReturn>(this IDbConnection cnn, string sql, Type[] types, Func<object[], TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken));
return MultiMapAsync<TReturn>(cnn, command, types, map, splitOn);
}
private static async Task<IEnumerable<TReturn>> MultiMapAsync<TReturn>(this IDbConnection cnn, CommandDefinition command, Type[] types, Func<object[], TReturn> map, string splitOn)
private static async Task<IEnumerable<TReturn>> MultiMapAsync<TReturn>(this IDbConnection cnn, CommandDefinition command, Type[] types, Func<object[], TReturn> map, string splitOn)
{
if (types.Length < 1)
if (types.Length < 1)
{
throw new ArgumentException("you must provide at least one type to deserialize");
}
......@@ -542,8 +542,7 @@ private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDat
yield return (T)func(reader);
}
while (reader.NextResult()) { }
if (parameters is SqlMapper.IParameterCallbacks)
((SqlMapper.IParameterCallbacks)parameters).OnCompleted();
(parameters as IParameterCallbacks)?.OnCompleted();
}
}
......@@ -598,7 +597,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
{ /* don't spoil the existing exception */ }
reader.Dispose();
}
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
if (wasClosed) cnn.Close();
throw;
}
......@@ -666,7 +665,7 @@ private static async Task<IDataReader> ExecuteReaderImplAsync(IDbConnection cnn,
finally
{
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
}
}
......@@ -743,7 +742,7 @@ private async static Task<T> ExecuteScalarImplAsync<T>(IDbConnection cnn, Comman
finally
{
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
}
return Parse<T>(result);
}
......
......@@ -17,8 +17,8 @@ private sealed class DapperRow
public DapperRow(DapperTable table, object[] values)
{
if (table == null) throw new ArgumentNullException("table");
if (values == null) throw new ArgumentNullException("values");
if (table == null) throw new ArgumentNullException(nameof(table));
if (values == null) throw new ArgumentNullException(nameof(values));
this.table = table;
this.values = values;
}
......@@ -136,11 +136,7 @@ IEnumerator IEnumerable.GetEnumerator()
return dic.Remove(item.Key);
}
bool ICollection<KeyValuePair<string, object>>.IsReadOnly
{
get { return false; }
}
bool ICollection<KeyValuePair<string, object>>.IsReadOnly => false;
#endregion
#region Implementation of IDictionary<string,object>
......@@ -177,7 +173,7 @@ public object SetValue(string key, object value)
}
private object SetValue(string key, object value, bool isAdd)
{
if (key == null) throw new ArgumentNullException("key");
if (key == null) throw new ArgumentNullException(nameof(key));
int index = table.IndexOfName(key);
if (index < 0)
{
......@@ -186,7 +182,7 @@ private object SetValue(string key, object value, bool isAdd)
else if (isAdd && index < values.Length && !(values[index] is DeadValue))
{
// then semantically, this value already exists
throw new ArgumentException("An item with the same key has already been added", "key");
throw new ArgumentException("An item with the same key has already been added", nameof(key));
}
int oldLength = values.Length;
if (oldLength <= index)
......
......@@ -10,11 +10,11 @@ private sealed class DapperTable
string[] fieldNames;
readonly Dictionary<string, int> fieldNameLookup;
internal string[] FieldNames { get { return fieldNames; } }
internal string[] FieldNames => fieldNames;
public DapperTable(string[] fieldNames)
{
if (fieldNames == null) throw new ArgumentNullException("fieldNames");
if (fieldNames == null) throw new ArgumentNullException(nameof(fieldNames));
this.fieldNames = fieldNames;
fieldNameLookup = new Dictionary<string, int>(fieldNames.Length, StringComparer.Ordinal);
......@@ -33,7 +33,7 @@ internal int IndexOfName(string name)
}
internal int AddField(string name)
{
if (name == null) throw new ArgumentNullException("name");
if (name == null) throw new ArgumentNullException(nameof(name));
if (fieldNameLookup.ContainsKey(name)) throw new InvalidOperationException("Field already exists: " + name);
int oldLen = fieldNames.Length;
Array.Resize(ref fieldNames, oldLen + 1); // yes, this is sub-optimal, but this is not the expected common case
......@@ -48,7 +48,7 @@ internal bool FieldExists(string key)
return key != null && fieldNameLookup.ContainsKey(key);
}
public int FieldCount { get { return fieldNames.Length; } }
public int FieldCount => fieldNames.Length;
}
}
......
......@@ -45,7 +45,7 @@ public Task<IEnumerable<dynamic>> ReadAsync(bool buffered = true)
/// </summary>
public Task<IEnumerable<object>> ReadAsync(Type type, bool buffered = true)
{
if (type == null) throw new ArgumentNullException("type");
if (type == null) throw new ArgumentNullException(nameof(type));
return ReadAsyncImpl<object>(type, buffered);
}
/// <summary>
......@@ -62,7 +62,7 @@ private async Task NextResultAsync()
{
readCount++;
gridIndex++;
consumed = false;
IsConsumed = false;
}
else
{
......@@ -70,7 +70,7 @@ private async Task NextResultAsync()
// need for "Cancel" etc
reader.Dispose();
reader = null;
if (callbacks != null) callbacks.OnCompleted();
callbacks?.OnCompleted();
Dispose();
}
}
......@@ -78,7 +78,7 @@ private async Task NextResultAsync()
private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
{
if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed");
if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
var typedIdentity = identity.ForGrid(type, gridIndex);
CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache);
var deserializer = cache.Deserializer;
......@@ -89,8 +89,8 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer;
}
consumed = true;
if (buffered && this.reader is DbDataReader)
IsConsumed = true;
if (buffered && reader is DbDataReader)
{
return ReadBufferedAsync<T>(gridIndex, deserializer.Func, typedIdentity);
}
......@@ -104,27 +104,23 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
private async Task<IEnumerable<T>> ReadBufferedAsync<T>(int index, Func<IDataReader, object> deserializer, Identity typedIdentity)
{
//try
//{
var reader = (DbDataReader)this.reader;
List<T> buffer = new List<T>();
while (index == gridIndex && await reader.ReadAsync(cancel).ConfigureAwait(false))
try
{
buffer.Add((T)deserializer(reader));
var reader = (DbDataReader)this.reader;
List<T> buffer = new List<T>();
while (index == gridIndex && await reader.ReadAsync(cancel).ConfigureAwait(false))
{
buffer.Add((T)deserializer(reader));
}
return buffer;
}
if (index == gridIndex) // need to do this outside of the finally pre-C#6
finally // finally so that First etc progresses things even when multiple rows
{
await NextResultAsync().ConfigureAwait(false);
if (index == gridIndex)
{
await NextResultAsync().ConfigureAwait(false);
}
}
return buffer;
//}
//finally // finally so that First etc progresses things even when multiple rows
//{
// if (index == gridIndex)
// {
// await NextResultAsync().ConfigureAwait(false);
// }
//}
}
}
......
......@@ -22,18 +22,17 @@ partial class SqlMapper
{
/// <summary>
/// The grid reader provides interfaces for reading multiple result sets from a Dapper query
/// The grid reader provides interfaces for reading multiple result sets from a Dapper query
/// </summary>
public partial class GridReader : IDisposable
{
private IDataReader reader;
private IDbCommand command;
private Identity identity;
private bool addToCache;
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, SqlMapper.IParameterCallbacks callbacks, bool addToCache)
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, IParameterCallbacks callbacks, bool addToCache)
{
this.Command = command;
Command = command;
this.reader = reader;
this.identity = identity;
this.callbacks = callbacks;
......@@ -62,14 +61,14 @@ public IEnumerable<T> Read<T>(bool buffered = true)
/// </summary>
public IEnumerable<object> Read(Type type, bool buffered = true)
{
if (type == null) throw new ArgumentNullException("type");
if (type == null) throw new ArgumentNullException(nameof(type));
return ReadImpl<object>(type, buffered);
}
private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
{
if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed");
if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
var typedIdentity = identity.ForGrid(type, gridIndex);
CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache);
var deserializer = cache.Deserializer;
......@@ -80,7 +79,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer;
}
consumed = true;
IsConsumed = true;
var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity);
return buffered ? result.ToList() : result;
}
......@@ -99,7 +98,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
}, gridIndex);
try
{
foreach (var r in SqlMapper.MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, default(CommandDefinition), func, splitOn, reader, identity, false))
foreach (var r in MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, default(CommandDefinition), func, splitOn, reader, identity, false))
{
yield return r;
}
......@@ -115,7 +114,7 @@ private IEnumerable<TReturn> MultiReadInternal<TReturn>(Type[] types, Func<objec
var identity = this.identity.ForGrid(typeof(TReturn), types, gridIndex);
try
{
foreach (var r in SqlMapper.MultiMapImpl<TReturn>(null, default(CommandDefinition), types, map, splitOn, reader, identity, false))
foreach (var r in MultiMapImpl<TReturn>(null, default(CommandDefinition), types, map, splitOn, reader, identity, false))
{
yield return r;
}
......@@ -205,34 +204,17 @@ private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> dese
}
}
private int gridIndex, readCount;
private bool consumed;
private SqlMapper.IParameterCallbacks callbacks;
private IParameterCallbacks callbacks;
/// <summary>
/// Has the underlying reader been consumed?
/// </summary>
public bool IsConsumed
{
get
{
return consumed;
}
}
public bool IsConsumed { get; private set; }
/// <summary>
/// The command associated with the reader
/// </summary>
public IDbCommand Command
{
get
{
return command;
}
set
{
command = value;
}
}
public IDbCommand Command { get; set; }
private void NextResult()
{
......@@ -240,7 +222,7 @@ private void NextResult()
{
readCount++;
gridIndex++;
consumed = false;
IsConsumed = false;
}
else
{
......@@ -248,7 +230,7 @@ private void NextResult()
// need for "Cancel" etc
reader.Dispose();
reader = null;
if (callbacks != null) callbacks.OnCompleted();
callbacks?.OnCompleted();
Dispose();
}
}
......@@ -259,7 +241,7 @@ public void Dispose()
{
if (reader != null)
{
if (!reader.IsClosed && Command != null) Command.Cancel();
if (!reader.IsClosed) Command?.Cancel();
reader.Dispose();
reader = null;
}
......
......@@ -58,22 +58,22 @@ private Identity(string sql, CommandType? commandType, string connectionString,
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 == null ? 0 : sql.GetHashCode());
hashCode = hashCode * 23 + (type == null ? 0 : type.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 == null ? 0 : t.GetHashCode());
hashCode = hashCode * 23 + (t?.GetHashCode() ?? 0);
}
}
hashCode = hashCode * 23 + (connectionString == null ? 0 : SqlMapper.connectionStringComparer.GetHashCode(connectionString));
hashCode = hashCode * 23 + (parametersType == null ? 0 : parametersType.GetHashCode());
hashCode = hashCode * 23 + (connectionString == null ? 0 : connectionStringComparer.GetHashCode(connectionString));
hashCode = hashCode * 23 + (parametersType?.GetHashCode() ?? 0);
}
}
/// <summary>
///
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
......@@ -86,28 +86,28 @@ public override bool Equals(object obj)
/// </summary>
public readonly string sql;
/// <summary>
/// The command type
/// The command type
/// </summary>
public readonly CommandType? commandType;
/// <summary>
///
///
/// </summary>
public readonly int hashCode, gridIndex;
/// <summary>
///
///
/// </summary>
public readonly Type type;
/// <summary>
///
///
/// </summary>
public readonly string connectionString;
/// <summary>
///
///
/// </summary>
public readonly Type parametersType;
/// <summary>
///
///
/// </summary>
/// <returns></returns>
public override int GetHashCode()
......@@ -127,7 +127,7 @@ public bool Equals(Identity other)
type == other.type &&
sql == other.sql &&
commandType == other.commandType &&
SqlMapper.connectionStringComparer.Equals(connectionString, other.connectionString) &&
connectionStringComparer.Equals(connectionString, other.connectionString) &&
parametersType == other.parametersType;
}
}
......
......@@ -49,9 +49,9 @@ private Link(TKey key, TValue value, Link<TKey, TValue> tail)
Value = value;
Tail = tail;
}
public TKey Key { get; private set; }
public TValue Value { get; private set; }
public Link<TKey, TValue> Tail { get; private set; }
public TKey Key { get; }
public TValue Value { get; }
public Link<TKey, TValue> Tail { get; }
}
}
}
......@@ -9,20 +9,20 @@ partial class SqlMapper
/// </summary>
internal struct LiteralToken
{
private readonly string token, member;
/// <summary>
/// The text in the original command that should be replaced
/// </summary>
public string Token { get { return token; } }
public string Token { get; }
/// <summary>
/// The name of the member referred to by the token
/// </summary>
public string Member { get { return member; } }
public string Member { get; }
internal LiteralToken(string token, string member)
{
this.token = token;
this.member = member;
Token = token;
Member = member;
}
internal static readonly IList<LiteralToken> None = new LiteralToken[0];
......
/*
License: http://www.apache.org/licenses/LICENSE-2.0
License: http://www.apache.org/licenses/LICENSE-2.0
Home page: http://code.google.com/p/dapper-dot-net/
*/
......@@ -47,7 +47,7 @@ static int GetColumnHash(IDataReader reader)
for (int i = 0; i < colCount; i++)
{ // binding code is only interested in names - not types
object tmp = reader.GetName(i);
hash = (hash * 31) + (tmp == null ? 0 : tmp.GetHashCode());
hash = (hash * 31) + (tmp?.GetHashCode() ?? 0);
}
return hash;
}
......@@ -61,7 +61,7 @@ static int GetColumnHash(IDataReader reader)
private static void OnQueryCachePurged()
{
var handler = QueryCachePurged;
if (handler != null) handler(null, EventArgs.Empty);
handler?.Invoke(null, EventArgs.Empty);
}
static readonly System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo> _queryCache = new System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo>();
......@@ -108,7 +108,7 @@ private static bool TryGetQueryCache(Identity key, out CacheInfo value)
}
/// <summary>
/// Purge the query cache
/// Purge the query cache
/// </summary>
public static void PurgeQueryCache()
{
......@@ -177,44 +177,46 @@ public static int GetCachedSQLCount()
static SqlMapper()
{
typeMap = new Dictionary<Type, DbType>();
typeMap[typeof(byte)] = DbType.Byte;
typeMap[typeof(sbyte)] = DbType.SByte;
typeMap[typeof(short)] = DbType.Int16;
typeMap[typeof(ushort)] = DbType.UInt16;
typeMap[typeof(int)] = DbType.Int32;
typeMap[typeof(uint)] = DbType.UInt32;
typeMap[typeof(long)] = DbType.Int64;
typeMap[typeof(ulong)] = DbType.UInt64;
typeMap[typeof(float)] = DbType.Single;
typeMap[typeof(double)] = DbType.Double;
typeMap[typeof(decimal)] = DbType.Decimal;
typeMap[typeof(bool)] = DbType.Boolean;
typeMap[typeof(string)] = DbType.String;
typeMap[typeof(char)] = DbType.StringFixedLength;
typeMap[typeof(Guid)] = DbType.Guid;
typeMap[typeof(DateTime)] = DbType.DateTime;
typeMap[typeof(DateTimeOffset)] = DbType.DateTimeOffset;
typeMap[typeof(TimeSpan)] = DbType.Time;
typeMap[typeof(byte[])] = DbType.Binary;
typeMap[typeof(byte?)] = DbType.Byte;
typeMap[typeof(sbyte?)] = DbType.SByte;
typeMap[typeof(short?)] = DbType.Int16;
typeMap[typeof(ushort?)] = DbType.UInt16;
typeMap[typeof(int?)] = DbType.Int32;
typeMap[typeof(uint?)] = DbType.UInt32;
typeMap[typeof(long?)] = DbType.Int64;
typeMap[typeof(ulong?)] = DbType.UInt64;
typeMap[typeof(float?)] = DbType.Single;
typeMap[typeof(double?)] = DbType.Double;
typeMap[typeof(decimal?)] = DbType.Decimal;
typeMap[typeof(bool?)] = DbType.Boolean;
typeMap[typeof(char?)] = DbType.StringFixedLength;
typeMap[typeof(Guid?)] = DbType.Guid;
typeMap[typeof(DateTime?)] = DbType.DateTime;
typeMap[typeof(DateTimeOffset?)] = DbType.DateTimeOffset;
typeMap[typeof(TimeSpan?)] = DbType.Time;
typeMap[typeof(object)] = DbType.Object;
typeMap = new Dictionary<Type, DbType>
{
[typeof(byte)] = DbType.Byte,
[typeof(sbyte)] = DbType.SByte,
[typeof(short)] = DbType.Int16,
[typeof(ushort)] = DbType.UInt16,
[typeof(int)] = DbType.Int32,
[typeof(uint)] = DbType.UInt32,
[typeof(long)] = DbType.Int64,
[typeof(ulong)] = DbType.UInt64,
[typeof(float)] = DbType.Single,
[typeof(double)] = DbType.Double,
[typeof(decimal)] = DbType.Decimal,
[typeof(bool)] = DbType.Boolean,
[typeof(string)] = DbType.String,
[typeof(char)] = DbType.StringFixedLength,
[typeof(Guid)] = DbType.Guid,
[typeof(DateTime)] = DbType.DateTime,
[typeof(DateTimeOffset)] = DbType.DateTimeOffset,
[typeof(TimeSpan)] = DbType.Time,
[typeof(byte[])] = DbType.Binary,
[typeof(byte?)] = DbType.Byte,
[typeof(sbyte?)] = DbType.SByte,
[typeof(short?)] = DbType.Int16,
[typeof(ushort?)] = DbType.UInt16,
[typeof(int?)] = DbType.Int32,
[typeof(uint?)] = DbType.UInt32,
[typeof(long?)] = DbType.Int64,
[typeof(ulong?)] = DbType.UInt64,
[typeof(float?)] = DbType.Single,
[typeof(double?)] = DbType.Double,
[typeof(decimal?)] = DbType.Decimal,
[typeof(bool?)] = DbType.Boolean,
[typeof(char?)] = DbType.StringFixedLength,
[typeof(Guid?)] = DbType.Guid,
[typeof(DateTime?)] = DbType.DateTime,
[typeof(DateTimeOffset?)] = DbType.DateTimeOffset,
[typeof(TimeSpan?)] = DbType.Time,
[typeof(object)] = DbType.Object
};
#if !DNXCORE50
AddTypeHandlerImpl(typeof(DataTable), new DataTableHandler(), false);
AddTypeHandlerImpl(typeof(IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord>), new SqlDataRecordHandler(), false);
......@@ -243,8 +245,7 @@ public static void AddTypeMap(Type type, DbType dbType)
DbType oldValue;
if (snapshot.TryGetValue(type, out oldValue) && oldValue == dbType) return; // nothing to do
var newCopy = new Dictionary<Type, DbType>(snapshot);
newCopy[type] = dbType;
var newCopy = new Dictionary<Type, DbType>(snapshot) { [type] = dbType };
typeMap = newCopy;
}
......@@ -261,7 +262,7 @@ public static void AddTypeHandler(Type type, ITypeHandler handler)
/// </summary>
public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clone)
{
if (type == null) throw new ArgumentNullException("type");
if (type == null) throw new ArgumentNullException(nameof(type));
Type secondary = null;
if(type.IsValueType())
......@@ -377,7 +378,7 @@ internal static DbType LookupDbType(Type type, string name, bool demand, out ITy
}
#endif
if(demand)
throw new NotSupportedException(string.Format("The member {0} of type {1} cannot be used as a parameter value", name, type.FullName));
throw new NotSupportedException($"The member {name} of type {type.FullName} cannot be used as a parameter value");
return DbType.Object;
}
......@@ -394,7 +395,7 @@ public static List<T> AsList<T>(this IEnumerable<T> source)
}
/// <summary>
/// Execute parameterized SQL
/// Execute parameterized SQL
/// </summary>
/// <returns>Number of rows affected</returns>
public static int Execute(
......@@ -405,7 +406,7 @@ public static List<T> AsList<T>(this IEnumerable<T> source)
return ExecuteImpl(cnn, ref command);
}
/// <summary>
/// Execute parameterized SQL
/// Execute parameterized SQL
/// </summary>
/// <returns>Number of rows affected</returns>
public static int Execute(this IDbConnection cnn, CommandDefinition command)
......@@ -617,7 +618,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, obj
this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null
)
{
if (type == null) throw new ArgumentNullException("type");
if (type == null) throw new ArgumentNullException(nameof(type));
var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None);
var data = QueryImpl<object>(cnn, command, type);
return command.Buffered ? data.ToList() : data;
......@@ -657,7 +658,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, CommandDefinition
private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandDefinition command)
{
object param = command.Parameters;
Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param == null ? null : param.GetType(), null);
Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param?.GetType(), null);
CacheInfo info = GetCacheInfo(identity, param, command.AddToCache);
IDbCommand cmd = null;
......@@ -681,11 +682,11 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD
{
if (reader != null)
{
if (!reader.IsClosed) try { cmd.Cancel(); }
if (!reader.IsClosed) try { cmd?.Cancel(); }
catch { /* don't spoil the existing exception */ }
reader.Dispose();
}
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
if (wasClosed) cnn.Close();
throw;
}
......@@ -694,7 +695,7 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD
private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefinition command, Type effectiveType)
{
object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType(), null);
var info = GetCacheInfo(identity, param, command.AddToCache);
IDbCommand cmd = null;
......@@ -749,7 +750,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
reader.Dispose();
}
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
}
}
......@@ -938,7 +939,7 @@ public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string
static IEnumerable<TReturn> MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, CommandDefinition command, Delegate map, string splitOn, IDataReader reader, Identity identity, bool finalize)
{
object param = command.Parameters;
identity = identity ?? new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param == null ? null : param.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) });
identity = identity ?? new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param?.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) });
CacheInfo cinfo = GetCacheInfo(identity, param, command.AddToCache);
IDbCommand ownedCommand = null;
......@@ -978,24 +979,18 @@ public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string
{
while (reader.NextResult()) { }
command.OnCompleted();
}
}
}
}
finally
{
try
{
if (ownedReader != null)
{
ownedReader.Dispose();
}
ownedReader?.Dispose();
}
finally
{
if (ownedCommand != null)
{
ownedCommand.Dispose();
}
ownedCommand?.Dispose();
if (wasClosed) cnn.Close();
}
}
......@@ -1056,17 +1051,11 @@ static IEnumerable<TReturn> MultiMapImpl<TReturn>(this IDbConnection cnn, Comman
{
try
{
if (ownedReader != null)
{
ownedReader.Dispose();
}
ownedReader?.Dispose();
}
finally
{
if (ownedCommand != null)
{
ownedCommand.Dispose();
}
ownedCommand?.Dispose();
if (wasClosed) cnn.Close();
}
}
......@@ -1272,7 +1261,7 @@ private static void PassByPosition(IDbCommand cmd)
if (cmd.Parameters.Count == 0) return;
Dictionary<string, IDbDataParameter> parameters = new Dictionary<string, IDbDataParameter>(StringComparer.Ordinal);
foreach(IDbDataParameter param in cmd.Parameters)
{
if (!string.IsNullOrEmpty(param.ParameterName)) parameters[param.ParameterName] = param;
......@@ -1348,7 +1337,7 @@ private static Exception MultiMapException(IDataRecord reader)
else
return new InvalidOperationException("No columns were selected");
}
internal static Func<IDataReader, object> GetDapperRowDeserializer(IDataRecord reader, int startBound, int length, bool returnNullIfFirstMissing)
{
var fieldCount = reader.FieldCount;
......@@ -1422,9 +1411,9 @@ private static Exception MultiMapException(IDataRecord reader)
[Obsolete("This method is for internal usage only", false)]
public static char ReadChar(object value)
{
if (value == null || value is DBNull) throw new ArgumentNullException("value");
if (value == null || value is DBNull) throw new ArgumentNullException(nameof(value));
string s = value as string;
if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", "value");
if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", nameof(value));
return s[0];
}
......@@ -1440,7 +1429,7 @@ public static char ReadChar(object value)
{
if (value == null || value is DBNull) return null;
string s = value as string;
if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", "value");
if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", nameof(value));
return s[0];
}
......@@ -1550,7 +1539,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
{
return "(SELECT " + variableName + " WHERE 1 = 0)";
}
}, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant);
}, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant);
var dummyParam = command.CreateParameter();
dummyParam.ParameterName = namePrefix;
dummyParam.Value = DBNull.Value;
......@@ -1565,7 +1554,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
{
// looks like an optimize hint; expand it
var suffix = match.Groups[2].Value;
var sb = GetStringBuilder().Append(variableName).Append(1).Append(suffix);
for (int i = 2; i <= count; i++)
{
......@@ -1757,13 +1746,13 @@ internal static IList<LiteralToken> GetLiteralTokens(string sql)
internal static Action<IDbCommand, object> CreateParamInfoGenerator(Identity identity, bool checkForDuplicates, bool removeUnused, IList<LiteralToken> literals)
{
Type type = identity.parametersType;
bool filterParams = false;
if (removeUnused && identity.commandType.GetValueOrDefault(CommandType.Text) == CommandType.Text)
{
filterParams = !smellsLikeOleDb.IsMatch(identity.sql);
}
var dm = new DynamicMethod(string.Format("ParamInfo{0}", Guid.NewGuid()), null, new[] { typeof(IDbCommand), typeof(object) }, type, true);
var dm = new DynamicMethod($"ParamInfo{Guid.NewGuid()}", null, new[] { typeof(IDbCommand), typeof(object) }, type, true);
var il = dm.GetILGenerator();
......@@ -1958,7 +1947,7 @@ internal static IList<LiteralToken> GetLiteralTokens(string sql)
il.MarkLabel(isLong);
EmitInt32(il, -1); // [string] [-1]
il.MarkLabel(lenDone);
il.Emit(OpCodes.Stloc_1); // [string]
il.Emit(OpCodes.Stloc_1); // [string]
}
if (prop.PropertyType.FullName == LinqBinary)
{
......@@ -2134,7 +2123,7 @@ private static int ExecuteCommand(IDbConnection cnn, ref CommandDefinition comma
finally
{
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
}
}
......@@ -2161,7 +2150,7 @@ private static T ExecuteScalarImpl<T>(IDbConnection cnn, ref CommandDefinition c
finally
{
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
}
return Parse<T>(result);
}
......@@ -2205,7 +2194,7 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null);
info = GetCacheInfo(identity, param, command.AddToCache);
}
var paramReader = info == null ? null : info.ParamReader;
var paramReader = info?.ParamReader;
return paramReader;
}
......@@ -2215,11 +2204,11 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin
#pragma warning disable 618
if (type == typeof(char))
{ // this *does* need special handling, though
return r => SqlMapper.ReadChar(r.GetValue(index));
return r => ReadChar(r.GetValue(index));
}
if (type == typeof(char?))
{
return r => SqlMapper.ReadNullableChar(r.GetValue(index));
return r => ReadNullableChar(r.GetValue(index));
}
if (type.FullName == LinqBinary)
{
......@@ -2295,7 +2284,7 @@ static readonly MethodInfo
/// <returns>Type map implementation, DefaultTypeMap instance if no override present</returns>
public static ITypeMap GetTypeMap(Type type)
{
if (type == null) throw new ArgumentNullException("type");
if (type == null) throw new ArgumentNullException(nameof(type));
#if DNXCORE50
ITypeMap map = null;
#else
......@@ -2337,7 +2326,7 @@ public static ITypeMap GetTypeMap(Type type)
public static void SetTypeMap(Type type, ITypeMap map)
{
if (type == null)
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(type));
if (map == null || map is DefaultTypeMap)
{
......@@ -2371,7 +2360,7 @@ public static void SetTypeMap(Type type, ITypeMap map)
)
{
var dm = new DynamicMethod(string.Format("Deserialize{0}", Guid.NewGuid()), typeof(object), new[] { typeof(IDataReader) }, true);
var dm = new DynamicMethod($"Deserialize{Guid.NewGuid()}", typeof(object), new[] { typeof(IDataReader) }, true);
var il = dm.GetILGenerator();
il.DeclareLocal(typeof(int));
il.DeclareLocal(type);
......@@ -2455,8 +2444,8 @@ public static void SetTypeMap(Type type, ITypeMap map)
var ctor = typeMap.FindConstructor(names, types);
if (ctor == null)
{
string proposedTypes = "(" + string.Join(", ", types.Select((t, i) => t.FullName + " " + names[i]).ToArray()) + ")";
throw new InvalidOperationException(string.Format("A parameterless default constructor or one matching signature {0} is required for {1} materialization", proposedTypes, type.FullName));
string proposedTypes = $"({string.Join(", ", types.Select((t, i) => t.FullName + " " + names[i]).ToArray())})";
throw new InvalidOperationException($"A parameterless default constructor or one matching signature {proposedTypes} is required for {type.FullName} materialization");
}
if (ctor.GetParameters().Length == 0)
......@@ -2762,7 +2751,7 @@ private static void FlexibleConvertBoxedFromHeadOfStack(ILGenerator il, Type fro
il.EmitCall(OpCodes.Call, typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) }), null); // stack is now [target][target][boxed-member-type-value]
il.Emit(OpCodes.Unbox_Any, to); // stack is now [target][target][typed-value]
}
}
}
}
static MethodInfo GetOperator(Type from, Type to)
......@@ -2789,7 +2778,7 @@ static MethodInfo ResolveOperator(MethodInfo[] methods, Type from, Type to, stri
private static void LoadLocal(ILGenerator il, int index)
{
if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException("index");
if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException(nameof(index));
switch (index)
{
case 0: il.Emit(OpCodes.Ldloc_0); break;
......@@ -2810,7 +2799,7 @@ private static void LoadLocal(ILGenerator il, int index)
}
private static void StoreLocal(ILGenerator il, int index)
{
if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException("index");
if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException(nameof(index));
switch (index)
{
case 0: il.Emit(OpCodes.Stloc_0); break;
......@@ -2831,7 +2820,7 @@ private static void StoreLocal(ILGenerator il, int index)
}
private static void LoadLocalAddress(ILGenerator il, int index)
{
if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException("index");
if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException(nameof(index));
if (index <= 255)
{
......@@ -2871,7 +2860,7 @@ public static void ThrowDataException(Exception ex, int index, IDataReader reade
formattedValue = valEx.Message;
}
}
toThrow = new DataException(string.Format("Error parsing column {0} ({1}={2})", index, name, formattedValue), ex);
toThrow = new DataException($"Error parsing column {index} ({name}={formattedValue})", ex);
}
catch
{ // throw the **original** exception, wrapped as DataException
......@@ -2956,7 +2945,7 @@ public static void SetTypeName(this DataTable table, string typeName)
/// </summary>
public static string GetTypeName(this DataTable table)
{
return table == null ? null : table.ExtendedProperties[DataTableTypeNameKey] as string;
return table?.ExtendedProperties[DataTableTypeNameKey] as string;
}
/// <summary>
......
......@@ -8,7 +8,7 @@ namespace Dapper
/// <summary>
/// Used to pass a DataTable as a TableValuedParameter
/// </summary>
sealed class TableValuedParameter : Dapper.SqlMapper.ICustomQueryParameter
sealed class TableValuedParameter : SqlMapper.ICustomQueryParameter
{
private readonly DataTable table;
private readonly string typeName;
......@@ -47,14 +47,14 @@ internal static void Set(IDbDataParameter parameter, DataTable table, string typ
parameter.Value = SqlMapper.SanitizeParameterValue(table);
if (string.IsNullOrEmpty(typeName) && table != null)
{
typeName = SqlMapper.GetTypeName(table);
typeName = table.GetTypeName();
}
if (!string.IsNullOrEmpty(typeName))
{
var sqlParam = parameter as System.Data.SqlClient.SqlParameter;
if (sqlParam != null)
{
if (setTypeName != null) setTypeName(sqlParam, typeName);
setTypeName?.Invoke(sqlParam, typeName);
sqlParam.SqlDbType = SqlDbType.Structured;
}
}
......
......@@ -252,23 +252,17 @@ public WrappedReader(IDbCommand cmd, IDataReader reader)
void IDataReader.Close()
{
if (reader != null) reader.Close();
reader?.Close();
}
int IDataReader.Depth
{
get { return Reader.Depth; }
}
int IDataReader.Depth => Reader.Depth;
DataTable IDataReader.GetSchemaTable()
{
return Reader.GetSchemaTable();
}
bool IDataReader.IsClosed
{
get { return reader == null ? true : reader.IsClosed; }
}
bool IDataReader.IsClosed => reader?.IsClosed ?? true;
bool IDataReader.NextResult()
{
......@@ -280,24 +274,18 @@ bool IDataReader.Read()
return Reader.Read();
}
int IDataReader.RecordsAffected
{
get { return Reader.RecordsAffected; }
}
int IDataReader.RecordsAffected => Reader.RecordsAffected;
void IDisposable.Dispose()
{
if (reader != null) reader.Close();
if (reader != null) reader.Dispose();
reader?.Close();
reader?.Dispose();
reader = null;
if (cmd != null) cmd.Dispose();
cmd?.Dispose();
cmd = null;
}
int IDataRecord.FieldCount
{
get { return Reader.FieldCount; }
}
int IDataRecord.FieldCount => Reader.FieldCount;
bool IDataRecord.GetBoolean(int i)
{
......@@ -409,15 +397,9 @@ bool IDataRecord.IsDBNull(int i)
return Reader.IsDBNull(i);
}
object IDataRecord.this[string name]
{
get { return Reader[name]; }
}
object IDataRecord.this[string name] => Reader[name];
object IDataRecord.this[int i]
{
get { return Reader[i]; }
}
object IDataRecord.this[int i] => Reader[i];
}
#endif
}
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