Skip to content

Commit fca1513

Browse files
committed
Merge remote-tracking branch 'upstream/master' into nuget
2 parents 8e6213f + aebf174 commit fca1513

File tree

6 files changed

+181
-152
lines changed

6 files changed

+181
-152
lines changed
Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
2-
using System.Collections;
3-
using System.Collections.Generic;
2+
using System.Collections.Concurrent;
43
using System.Data;
4+
using System.Linq;
55
using NHibernate.Connection;
66

77
namespace NHibernate.Test
@@ -12,70 +12,49 @@ namespace NHibernate.Test
1212
/// </summary>
1313
public class DebugConnectionProvider : DriverConnectionProvider
1414
{
15-
private ISet<IDbConnection> connections = new HashSet<IDbConnection>();
15+
private ConcurrentDictionary<IDbConnection, byte> connections = new ConcurrentDictionary<IDbConnection, byte>();
1616

1717
public override IDbConnection GetConnection()
1818
{
1919
try
2020
{
2121
IDbConnection connection = base.GetConnection();
22-
connections.Add(connection);
22+
connections.TryAdd(connection, 0);
2323
return connection;
2424
}
2525
catch (Exception e)
2626
{
2727
throw new HibernateException("Could not open connection to: " + ConnectionString, e);
2828
}
29-
3029
}
3130

3231
public override void CloseConnection(IDbConnection conn)
3332
{
3433
base.CloseConnection(conn);
35-
connections.Remove(conn);
34+
byte _;
35+
connections.TryRemove(conn, out _);
3636
}
3737

3838
public bool HasOpenConnections
3939
{
4040
get
4141
{
42-
// check to see if all connections that were at one point opened
43-
// have been closed through the CloseConnection
44-
// method
45-
if (connections.Count == 0)
46-
{
47-
// there are no connections, either none were opened or
48-
// all of the closings went through CloseConnection.
49-
return false;
50-
}
51-
else
52-
{
53-
// Disposing of an ISession does not call CloseConnection (should it???)
54-
// so a Diposed of ISession will leave an IDbConnection in the list but
55-
// the IDbConnection will be closed (atleast with MsSql it works this way).
56-
foreach (IDbConnection conn in connections)
57-
{
58-
if (conn.State != ConnectionState.Closed)
59-
{
60-
return true;
61-
}
62-
}
63-
64-
// all of the connections have been Disposed and were closed that way
65-
// or they were Closed through the CloseConnection method.
66-
return false;
67-
}
42+
// Disposing of an ISession does not call CloseConnection (should it???)
43+
// so a Diposed of ISession will leave an IDbConnection in the list but
44+
// the IDbConnection will be closed (atleast with MsSql it works this way).
45+
return connections.Keys.Any(conn => conn.State != ConnectionState.Closed);
6846
}
6947
}
7048

7149
public void CloseAllConnections()
7250
{
7351
while (connections.Count != 0)
7452
{
75-
IEnumerator en = connections.GetEnumerator();
76-
en.MoveNext();
77-
CloseConnection(en.Current as IDbConnection);
53+
foreach (var conn in connections.Keys.ToArray())
54+
{
55+
CloseConnection(conn);
56+
}
7857
}
7958
}
8059
}
81-
}
60+
}

src/NHibernate/AdoNet/MySqlClientSqlCommandSet.cs

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,51 @@
22
using System.Data;
33
using System.Diagnostics;
44
using System.Reflection;
5+
using NHibernate.Util;
56

67
namespace NHibernate.AdoNet
78
{
8-
using Action = System.Action;
9-
109
public class MySqlClientSqlCommandSet : IDisposable
1110
{
1211
private static readonly System.Type adapterType;
12+
private static readonly Action<object> doInitialise;
13+
private static readonly Action<object, int> batchSizeSetter;
14+
private static readonly Action<object, IDbCommand> doAppend;
15+
private static readonly Func<object, int> doExecuteNonQuery;
16+
private static readonly Action<object> doDispose;
17+
1318
private readonly object instance;
14-
private readonly Action doInitialise;
15-
private readonly Action<int> batchSizeSetter;
16-
private readonly Func<IDbCommand, int> doAppend;
17-
private readonly Func<int> doExecuteNonQuery;
18-
private readonly Action doDispose;
1919
private int countOfCommands;
2020

2121
static MySqlClientSqlCommandSet()
2222
{
2323
var sysData = Assembly.Load("MySql.Data");
2424
adapterType = sysData.GetType("MySql.Data.MySqlClient.MySqlDataAdapter");
2525
Debug.Assert(adapterType != null, "Could not find MySqlDataAdapter!");
26+
27+
doInitialise = DelegateHelper.BuildAction(adapterType, "InitializeBatching");
28+
batchSizeSetter = DelegateHelper.BuildPropertySetter<int>(adapterType, "UpdateBatchSize");
29+
doAppend = DelegateHelper.BuildAction<IDbCommand>(adapterType, "AddToBatch");
30+
doExecuteNonQuery = DelegateHelper.BuildFunc<int>(adapterType, "ExecuteBatch");
31+
doDispose = DelegateHelper.BuildAction(adapterType, "Dispose");
2632
}
2733

2834
public MySqlClientSqlCommandSet(int batchSize)
2935
{
3036
instance = Activator.CreateInstance(adapterType, true);
31-
doInitialise = (Action) Delegate.CreateDelegate(typeof (Action), instance, "InitializeBatching");
32-
batchSizeSetter = (Action<int>) Delegate.CreateDelegate(typeof (Action<int>), instance, "set_UpdateBatchSize");
33-
doAppend = (Func<IDbCommand, int>) Delegate.CreateDelegate(typeof (Func<IDbCommand, int>), instance, "AddToBatch");
34-
doExecuteNonQuery = (Func<int>) Delegate.CreateDelegate(typeof (Func<int>), instance, "ExecuteBatch");
35-
doDispose = (Action)Delegate.CreateDelegate(typeof(Action), instance, "Dispose");
36-
37-
Initialise(batchSize);
38-
}
39-
40-
private void Initialise(int batchSize)
41-
{
42-
doInitialise();
43-
batchSizeSetter(batchSize);
37+
doInitialise(instance);
38+
batchSizeSetter(instance, batchSize);
4439
}
4540

4641
public void Append(IDbCommand command)
4742
{
48-
doAppend(command);
43+
doAppend(instance, command);
4944
countOfCommands++;
5045
}
5146

5247
public void Dispose()
5348
{
54-
doDispose();
49+
doDispose(instance);
5550
}
5651

5752
public int ExecuteNonQuery()
@@ -63,7 +58,7 @@ public int ExecuteNonQuery()
6358
return 0;
6459
}
6560

66-
return doExecuteNonQuery();
61+
return doExecuteNonQuery(instance);
6762
}
6863
catch (Exception exception)
6964
{
@@ -73,10 +68,7 @@ public int ExecuteNonQuery()
7368

7469
public int CountOfCommands
7570
{
76-
get
77-
{
78-
return countOfCommands;
79-
}
71+
get { return countOfCommands; }
8072
}
8173
}
8274
}

src/NHibernate/AdoNet/SqlClientSqlCommandSet.cs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
using System.Data.SqlClient;
33
using System.Diagnostics;
44
using System.Reflection;
5+
using NHibernate.Util;
56

67
namespace NHibernate.AdoNet
78
{
8-
using Action = System.Action;
99
using SqlCommand = System.Data.SqlClient.SqlCommand;
1010

1111
/// <summary>
12-
/// Expose the batch functionality in ADO.Net 2.0
12+
/// Expose the batch functionality in ADO.Net 4.0
1313
/// Microsoft in its wisdom decided to make my life hard and mark it internal.
1414
/// Through the use of Reflection and some delegates magic, I opened up the functionality.
1515
///
@@ -18,35 +18,37 @@ namespace NHibernate.AdoNet
1818
public class SqlClientSqlCommandSet : IDisposable
1919
{
2020
private static readonly System.Type sqlCmdSetType;
21+
private static readonly Action<object, SqlConnection> connectionSetter;
22+
private static readonly Action<object, SqlTransaction> transactionSetter;
23+
private static readonly Action<object, int> commandTimeoutSetter;
24+
private static readonly Func<object, SqlConnection> connectionGetter;
25+
private static readonly Func<object, SqlCommand> batchCommandGetter;
26+
private static readonly Action<object, SqlCommand> doAppend;
27+
private static readonly Func<object, int> doExecuteNonQuery;
28+
private static readonly Action<object> doDispose;
29+
2130
private readonly object instance;
22-
private readonly Action<SqlConnection> connectionSetter;
23-
private readonly Action<SqlTransaction> transactionSetter;
24-
private readonly Action<int> commandTimeoutSetter;
25-
private readonly Func<SqlConnection> connectionGetter;
26-
private readonly Func<SqlCommand> commandGetter;
27-
private readonly Action<SqlCommand> doAppend;
28-
private readonly Func<int> doExecuteNonQuery;
29-
private readonly Action doDispose;
3031
private int countOfCommands;
3132

3233
static SqlClientSqlCommandSet()
3334
{
34-
var sysData = Assembly.Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
35+
var sysData = Assembly.Load("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
3536
sqlCmdSetType = sysData.GetType("System.Data.SqlClient.SqlCommandSet");
3637
Debug.Assert(sqlCmdSetType != null, "Could not find SqlCommandSet!");
38+
39+
connectionSetter = DelegateHelper.BuildPropertySetter<SqlConnection>(sqlCmdSetType, "Connection");
40+
connectionGetter = DelegateHelper.BuildPropertyGetter<SqlConnection>(sqlCmdSetType, "Connection");
41+
transactionSetter = DelegateHelper.BuildPropertySetter<SqlTransaction>(sqlCmdSetType, "Transaction");
42+
commandTimeoutSetter = DelegateHelper.BuildPropertySetter<int>(sqlCmdSetType, "CommandTimeout");
43+
batchCommandGetter = DelegateHelper.BuildPropertyGetter<SqlCommand>(sqlCmdSetType, "BatchCommand");
44+
doAppend = DelegateHelper.BuildAction<SqlCommand>(sqlCmdSetType, "Append");
45+
doExecuteNonQuery = DelegateHelper.BuildFunc<int>(sqlCmdSetType, "ExecuteNonQuery");
46+
doDispose = DelegateHelper.BuildAction(sqlCmdSetType, "Dispose");
3747
}
3848

3949
public SqlClientSqlCommandSet()
4050
{
4151
instance = Activator.CreateInstance(sqlCmdSetType, true);
42-
connectionSetter = (Action<SqlConnection>) Delegate.CreateDelegate(typeof (Action<SqlConnection>), instance, "set_Connection");
43-
transactionSetter = (Action<SqlTransaction>) Delegate.CreateDelegate(typeof (Action<SqlTransaction>), instance, "set_Transaction");
44-
commandTimeoutSetter = (Action<int>) Delegate.CreateDelegate(typeof (Action<int>), instance, "set_CommandTimeout");
45-
connectionGetter = (Func<SqlConnection>) Delegate.CreateDelegate(typeof (Func<SqlConnection>), instance, "get_Connection");
46-
commandGetter = (Func<SqlCommand>) Delegate.CreateDelegate(typeof (Func<SqlCommand>), instance, "get_BatchCommand");
47-
doAppend = (Action<SqlCommand>) Delegate.CreateDelegate(typeof (Action<SqlCommand>), instance, "Append");
48-
doExecuteNonQuery = (Func<int>) Delegate.CreateDelegate(typeof (Func<int>), instance, "ExecuteNonQuery");
49-
doDispose = (Action) Delegate.CreateDelegate(typeof (Action), instance, "Dispose");
5052
}
5153

5254
/// <summary>
@@ -56,7 +58,7 @@ public SqlClientSqlCommandSet()
5658
public void Append(SqlCommand command)
5759
{
5860
AssertHasParameters(command);
59-
doAppend(command);
61+
doAppend(instance, command);
6062
countOfCommands++;
6163
}
6264

@@ -79,7 +81,7 @@ private static void AssertHasParameters(SqlCommand command)
7981
/// </summary>
8082
public SqlCommand BatchCommand
8183
{
82-
get { return commandGetter(); }
84+
get { return batchCommandGetter(instance); }
8385
}
8486

8587
/// <summary>
@@ -104,23 +106,23 @@ public int ExecuteNonQuery()
104106

105107
if (CountOfCommands == 0)
106108
return 0;
107-
return doExecuteNonQuery();
109+
return doExecuteNonQuery(instance);
108110
}
109111

110112
public SqlConnection Connection
111113
{
112-
get { return connectionGetter(); }
113-
set { connectionSetter(value); }
114+
get { return connectionGetter(instance); }
115+
set { connectionSetter(instance, value); }
114116
}
115117

116118
public SqlTransaction Transaction
117119
{
118-
set { transactionSetter(value); }
120+
set { transactionSetter(instance, value); }
119121
}
120122

121123
public int CommandTimeout
122124
{
123-
set { commandTimeoutSetter(value); }
125+
set { commandTimeoutSetter(instance, value); }
124126
}
125127

126128
///<summary>
@@ -129,7 +131,7 @@ public int CommandTimeout
129131
///<filterpriority>2</filterpriority>
130132
public void Dispose()
131133
{
132-
doDispose();
134+
doDispose(instance);
133135
}
134136
}
135137
}

0 commit comments

Comments
 (0)