Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 55129bc

Browse files
committed
Upgrade to latest version of Dapper
Removed refs to System.Xml.Linq to avoid adding any additional deps to OrmLite
1 parent e37e819 commit 55129bc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+5040
-3814
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#if NET45
2+
#define ASYNC
3+
#endif
4+
5+
using System;
6+
using System.Data;
7+
using System.Reflection;
8+
using System.Reflection.Emit;
9+
using System.Threading;
10+
11+
//Apache 2.0 License: https://github.com/StackExchange/dapper-dot-net/blob/master/License.txt
12+
namespace ServiceStack.OrmLite.Dapper
13+
{
14+
/// <summary>
15+
/// Represents the key aspects of a sql operation
16+
/// </summary>
17+
public struct CommandDefinition
18+
{
19+
internal static CommandDefinition ForCallback(object parameters)
20+
{
21+
if (parameters is DynamicParameters)
22+
{
23+
return new CommandDefinition(parameters);
24+
}
25+
else
26+
{
27+
return default(CommandDefinition);
28+
}
29+
}
30+
31+
internal void OnCompleted()
32+
{
33+
(Parameters as SqlMapper.IParameterCallbacks)?.OnCompleted();
34+
}
35+
36+
/// <summary>
37+
/// The command (sql or a stored-procedure name) to execute
38+
/// </summary>
39+
public string CommandText { get; }
40+
41+
/// <summary>
42+
/// The parameters associated with the command
43+
/// </summary>
44+
public object Parameters { get; }
45+
46+
/// <summary>
47+
/// The active transaction for the command
48+
/// </summary>
49+
public IDbTransaction Transaction { get; }
50+
51+
/// <summary>
52+
/// The effective timeout for the command
53+
/// </summary>
54+
public int? CommandTimeout { get; }
55+
56+
/// <summary>
57+
/// The type of command that the command-text represents
58+
/// </summary>
59+
public CommandType? CommandType { get; }
60+
61+
/// <summary>
62+
/// Should data be buffered before returning?
63+
/// </summary>
64+
public bool Buffered => (Flags & CommandFlags.Buffered) != 0;
65+
66+
/// <summary>
67+
/// Should the plan for this query be cached?
68+
/// </summary>
69+
internal bool AddToCache => (Flags & CommandFlags.NoCache) == 0;
70+
71+
/// <summary>
72+
/// Additional state flags against this command
73+
/// </summary>
74+
public CommandFlags Flags { get; }
75+
76+
/// <summary>
77+
/// Can async queries be pipelined?
78+
/// </summary>
79+
public bool Pipelined => (Flags & CommandFlags.Pipelined) != 0;
80+
81+
/// <summary>
82+
/// Initialize the command definition
83+
/// </summary>
84+
public CommandDefinition(string commandText, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null,
85+
CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered
86+
#if ASYNC
87+
, CancellationToken cancellationToken = default(CancellationToken)
88+
#endif
89+
)
90+
{
91+
CommandText = commandText;
92+
Parameters = parameters;
93+
Transaction = transaction;
94+
CommandTimeout = commandTimeout;
95+
CommandType = commandType;
96+
Flags = flags;
97+
#if ASYNC
98+
CancellationToken = cancellationToken;
99+
#endif
100+
}
101+
102+
private CommandDefinition(object parameters) : this()
103+
{
104+
Parameters = parameters;
105+
}
106+
107+
#if ASYNC
108+
109+
/// <summary>
110+
/// For asynchronous operations, the cancellation-token
111+
/// </summary>
112+
public CancellationToken CancellationToken { get; }
113+
#endif
114+
115+
internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object> paramReader)
116+
{
117+
var cmd = cnn.CreateCommand();
118+
var init = GetInit(cmd.GetType());
119+
init?.Invoke(cmd);
120+
if (Transaction != null)
121+
cmd.Transaction = Transaction;
122+
cmd.CommandText = CommandText;
123+
if (CommandTimeout.HasValue)
124+
{
125+
cmd.CommandTimeout = CommandTimeout.Value;
126+
}
127+
else if (SqlMapper.Settings.CommandTimeout.HasValue)
128+
{
129+
cmd.CommandTimeout = SqlMapper.Settings.CommandTimeout.Value;
130+
}
131+
if (CommandType.HasValue)
132+
cmd.CommandType = CommandType.Value;
133+
paramReader?.Invoke(cmd, Parameters);
134+
return cmd;
135+
}
136+
137+
private static SqlMapper.Link<Type, Action<IDbCommand>> commandInitCache;
138+
139+
private static Action<IDbCommand> GetInit(Type commandType)
140+
{
141+
if (commandType == null)
142+
return null; // GIGO
143+
Action<IDbCommand> action;
144+
if (SqlMapper.Link<Type, Action<IDbCommand>>.TryGet(commandInitCache, commandType, out action))
145+
{
146+
return action;
147+
}
148+
var bindByName = GetBasicPropertySetter(commandType, "BindByName", typeof(bool));
149+
var initialLongFetchSize = GetBasicPropertySetter(commandType, "InitialLONGFetchSize", typeof(int));
150+
151+
action = null;
152+
if (bindByName != null || initialLongFetchSize != null)
153+
{
154+
var method = new DynamicMethod(commandType.Name + "_init", null, new Type[] { typeof(IDbCommand) });
155+
var il = method.GetILGenerator();
156+
157+
if (bindByName != null)
158+
{
159+
// .BindByName = true
160+
il.Emit(OpCodes.Ldarg_0);
161+
il.Emit(OpCodes.Castclass, commandType);
162+
il.Emit(OpCodes.Ldc_I4_1);
163+
il.EmitCall(OpCodes.Callvirt, bindByName, null);
164+
}
165+
if (initialLongFetchSize != null)
166+
{
167+
// .InitialLONGFetchSize = -1
168+
il.Emit(OpCodes.Ldarg_0);
169+
il.Emit(OpCodes.Castclass, commandType);
170+
il.Emit(OpCodes.Ldc_I4_M1);
171+
il.EmitCall(OpCodes.Callvirt, initialLongFetchSize, null);
172+
}
173+
il.Emit(OpCodes.Ret);
174+
action = (Action<IDbCommand>)method.CreateDelegate(typeof(Action<IDbCommand>));
175+
}
176+
// cache it
177+
SqlMapper.Link<Type, Action<IDbCommand>>.TryAdd(ref commandInitCache, commandType, ref action);
178+
return action;
179+
}
180+
181+
private static MethodInfo GetBasicPropertySetter(Type declaringType, string name, Type expectedType)
182+
{
183+
var prop = declaringType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
184+
if (prop != null && prop.CanWrite && prop.PropertyType == expectedType && prop.GetIndexParameters().Length == 0)
185+
{
186+
return prop.GetSetMethod();
187+
}
188+
return null;
189+
}
190+
}
191+
192+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
3+
//Apache 2.0 License: https://github.com/StackExchange/dapper-dot-net/blob/master/License.txt
4+
namespace ServiceStack.OrmLite.Dapper
5+
{
6+
7+
/// <summary>
8+
/// Additional state flags that control command behaviour
9+
/// </summary>
10+
[Flags]
11+
public enum CommandFlags
12+
{
13+
/// <summary>
14+
/// No additional flags
15+
/// </summary>
16+
None = 0,
17+
/// <summary>
18+
/// Should data be buffered before returning?
19+
/// </summary>
20+
Buffered = 1,
21+
/// <summary>
22+
/// Can async queries be pipelined?
23+
/// </summary>
24+
Pipelined = 2,
25+
/// <summary>
26+
/// Should the plan cache be bypassed?
27+
/// </summary>
28+
NoCache = 4,
29+
}
30+
31+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using System.Reflection;
3+
4+
//Apache 2.0 License: https://github.com/StackExchange/dapper-dot-net/blob/master/License.txt
5+
namespace ServiceStack.OrmLite.Dapper
6+
{
7+
8+
/// <summary>
9+
/// Implements custom property mapping by user provided criteria (usually presence of some custom attribute with column to member mapping)
10+
/// </summary>
11+
public sealed class CustomPropertyTypeMap : SqlMapper.ITypeMap
12+
{
13+
private readonly Type _type;
14+
private readonly Func<Type, string, PropertyInfo> _propertySelector;
15+
16+
/// <summary>
17+
/// Creates custom property mapping
18+
/// </summary>
19+
/// <param name="type">Target entity type</param>
20+
/// <param name="propertySelector">Property selector based on target type and DataReader column name</param>
21+
public CustomPropertyTypeMap(Type type, Func<Type, string, PropertyInfo> propertySelector)
22+
{
23+
if (type == null)
24+
throw new ArgumentNullException(nameof(type));
25+
26+
if (propertySelector == null)
27+
throw new ArgumentNullException(nameof(propertySelector));
28+
29+
_type = type;
30+
_propertySelector = propertySelector;
31+
}
32+
33+
/// <summary>
34+
/// Always returns default constructor
35+
/// </summary>
36+
/// <param name="names">DataReader column names</param>
37+
/// <param name="types">DataReader column types</param>
38+
/// <returns>Default constructor</returns>
39+
public ConstructorInfo FindConstructor(string[] names, Type[] types)
40+
{
41+
return _type.GetConstructor(new Type[0]);
42+
}
43+
44+
/// <summary>
45+
/// Always returns null
46+
/// </summary>
47+
/// <returns></returns>
48+
public ConstructorInfo FindExplicitConstructor()
49+
{
50+
return null;
51+
}
52+
53+
/// <summary>
54+
/// Not implemented as far as default constructor used for all cases
55+
/// </summary>
56+
/// <param name="constructor"></param>
57+
/// <param name="columnName"></param>
58+
/// <returns></returns>
59+
public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
60+
{
61+
throw new NotSupportedException();
62+
}
63+
64+
/// <summary>
65+
/// Returns property based on selector strategy
66+
/// </summary>
67+
/// <param name="columnName">DataReader column name</param>
68+
/// <returns>Poperty member map</returns>
69+
public SqlMapper.IMemberMap GetMember(string columnName)
70+
{
71+
var prop = _propertySelector(_type, columnName);
72+
return prop != null ? new SimpleMemberMap(columnName, prop) : null;
73+
}
74+
}
75+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Data;
3+
4+
#if !COREFX
5+
//Apache 2.0 License: https://github.com/StackExchange/dapper-dot-net/blob/master/License.txt
6+
namespace ServiceStack.OrmLite.Dapper
7+
{
8+
sealed class DataTableHandler : SqlMapper.ITypeHandler
9+
{
10+
public object Parse(Type destinationType, object value)
11+
{
12+
throw new NotImplementedException();
13+
}
14+
15+
public void SetValue(IDbDataParameter parameter, object value)
16+
{
17+
TableValuedParameter.Set(parameter, value as DataTable, null);
18+
}
19+
}
20+
}
21+
#endif

0 commit comments

Comments
 (0)