Skip to content

Commit b49e3f1

Browse files
author
Oren (electricessence)
committed
Update to 5.8.0.
Improved connection state/open intellegence for all connection and command extensions. Added missing async extensions for commands. (Was assumed to use expressive commands only.) Added more useful connection factory extensions.
1 parent c7c8525 commit b49e3f1

19 files changed

+3438
-7767
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,5 @@ __pycache__/
287287
*.odx.cs
288288
*.xsd.cs
289289
Open.Database.Extensions.sln
290+
291+
log.txt

ExpressiveDbCommandBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public async Task<T> ExecuteAsync<T>(Func<TCommand, Task<T>> transform, Cancella
9696
var c = cmd as TCommand;
9797
if (c == null) throw new InvalidCastException($"Actual command type ({cmd.GetType()}) is not compatible with expected command type ({typeof(TCommand)}).");
9898
AddParams(c);
99-
await con.EnsureOpenAsync(t);
99+
if (con.State != ConnectionState.Open) await con.EnsureOpenAsync(t);
100100
return await transform(c);
101101
}
102102
}
@@ -126,7 +126,7 @@ public async Task<object> ExecuteReturnAsync(CancellationToken? token = null)
126126
var returnParameter = c.CreateParameter();
127127
returnParameter.Direction = ParameterDirection.ReturnValue;
128128
cmd.Parameters.Add(returnParameter);
129-
await con.EnsureOpenAsync(t);
129+
if (con.State != ConnectionState.Open) await con.EnsureOpenAsync(t);
130130
await c.ExecuteNonQueryAsync(t);
131131
return returnParameter.Value;
132132
}

Extensions.ConnectionFactory.cs

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
using System;
2+
using System.Data;
3+
using System.Data.Common;
4+
using System.Threading.Tasks;
5+
6+
namespace Open.Database.Extensions
7+
{
8+
public static partial class Extensions
9+
{
10+
/// <summary>
11+
/// Generates a connection and executes the action within a using statement.
12+
/// Useful for single-line operations.
13+
/// </summary>
14+
/// <typeparam name="TConn">The connection type.</typeparam>
15+
/// <typeparam name="T">The type returned from the action.</typeparam>
16+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
17+
/// <param name="action">The action to execute.</param>
18+
/// <returns>The value from the action.</returns>
19+
public static T Using<TConn, T>(this IDbConnectionFactory<TConn> connectionFactory, Func<TConn, T> action)
20+
where TConn : IDbConnection
21+
{
22+
using (var conn = connectionFactory.Create())
23+
{
24+
return action(conn);
25+
}
26+
}
27+
28+
/// <summary>
29+
/// Generates a connection and executes the action within a using statement.
30+
/// Useful for single-line operations.
31+
/// </summary>
32+
/// <typeparam name="TConn">The connection type.</typeparam>
33+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
34+
/// <param name="action">The action to execute.</param>
35+
public static void Using<TConn>(this IDbConnectionFactory<TConn> connectionFactory, Action<TConn> action)
36+
where TConn : IDbConnection
37+
{
38+
using (var conn = connectionFactory.Create())
39+
{
40+
action(conn);
41+
}
42+
}
43+
44+
/// <summary>
45+
/// Generates a connection and executes the action within a using statement.
46+
/// Useful for single-line operations.
47+
/// </summary>
48+
/// <typeparam name="TConn">The connection type.</typeparam>
49+
/// <typeparam name="T">The type returned from the action.</typeparam>
50+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
51+
/// <param name="action">The action to execute.</param>
52+
/// <returns>The value from the action.</returns>
53+
public static T Using<TConn, T>(this Func<TConn> connectionFactory, Func<TConn, T> action)
54+
where TConn : IDbConnection
55+
{
56+
using (var conn = connectionFactory())
57+
{
58+
return action(conn);
59+
}
60+
}
61+
62+
/// <summary>
63+
/// Generates a connection and executes the action within a using statement.
64+
/// Useful for single-line operations.
65+
/// </summary>
66+
/// <typeparam name="TConn">The connection type.</typeparam>
67+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
68+
/// <param name="action">The action to execute.</param>
69+
public static void Using<TConn>(this Func<TConn> connectionFactory, Action<TConn> action)
70+
where TConn : IDbConnection
71+
{
72+
using (var conn = connectionFactory())
73+
{
74+
action(conn);
75+
}
76+
}
77+
78+
/// <summary>
79+
/// Generates a connection and executes the action within a using statement.
80+
/// Useful for single-line operations.
81+
/// </summary>
82+
/// <typeparam name="TConn">The connection type.</typeparam>
83+
/// <typeparam name="T">The type returned from the action.</typeparam>
84+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
85+
/// <param name="action">The action to execute.</param>
86+
/// <returns>The value from the action.</returns>
87+
public static async Task<T> UsingAsync<TConn, T>(this IDbConnectionFactory<TConn> connectionFactory, Func<TConn, Task<T>> action)
88+
where TConn : IDbConnection
89+
{
90+
using (var conn = connectionFactory.Create())
91+
{
92+
return await action(conn);
93+
}
94+
}
95+
96+
/// <summary>
97+
/// Generates a connection and executes the action within a using statement.
98+
/// Useful for single-line operations.
99+
/// </summary>
100+
/// <typeparam name="TConn">The connection type.</typeparam>
101+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
102+
/// <param name="action">The action to execute.</param>
103+
public static async Task UsingAsync<TConn>(this IDbConnectionFactory<TConn> connectionFactory, Func<TConn, Task> action)
104+
where TConn : IDbConnection
105+
{
106+
using (var conn = connectionFactory.Create())
107+
{
108+
await action(conn);
109+
}
110+
}
111+
112+
/// <summary>
113+
/// Generates a connection and executes the action within a using statement.
114+
/// Useful for single-line operations.
115+
/// </summary>
116+
/// <typeparam name="TConn">The connection type.</typeparam>
117+
/// <typeparam name="T">The type returned from the action.</typeparam>
118+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
119+
/// <param name="action">The action to execute.</param>
120+
/// <returns>The value from the action.</returns>
121+
public static async Task<T> UsingAsync<TConn, T>(this Func<TConn> connectionFactory, Func<TConn, Task<T>> action)
122+
where TConn : IDbConnection
123+
{
124+
using (var conn = connectionFactory())
125+
{
126+
return await action(conn);
127+
}
128+
}
129+
130+
/// <summary>
131+
/// Generates a connection and executes the action within a using statement.
132+
/// Useful for single-line operations.
133+
/// </summary>
134+
/// <typeparam name="TConn">The connection type.</typeparam>
135+
/// <param name="connectionFactory">The connection factory to generate connections from.</param>
136+
/// <param name="action">The action to execute.</param>
137+
public static async Task UsingAsync<TConn>(this Func<TConn> connectionFactory, Func<TConn, Task> action)
138+
where TConn : IDbConnection
139+
{
140+
using (var conn = connectionFactory())
141+
{
142+
await action(conn);
143+
}
144+
}
145+
146+
147+
/// <summary>
148+
/// Creates an ExpressiveDbCommand for subsequent configuration and execution.
149+
/// </summary>
150+
/// <param name="target">The connection to execute the command on.</param>
151+
/// <param name="command">The command text or stored procedure name to use.</param>
152+
/// <param name="type">The command type.</param>
153+
/// <returns>The resultant ExpressiveDbCommand.</returns>
154+
public static ExpressiveDbCommand Command(
155+
this DbConnection target,
156+
string command,
157+
CommandType type = CommandType.Text)
158+
=> new ExpressiveDbCommand(target, type, command);
159+
160+
/// <summary>
161+
/// Creates an ExpressiveDbCommand with command type set to StoredProcedure for subsequent configuration and execution.
162+
/// </summary>
163+
/// <param name="target">The connection to execute the command on.</param>
164+
/// <param name="command">The command text or stored procedure name to use.</param>
165+
/// <returns>The resultant ExpressiveDbCommand.</returns>
166+
public static ExpressiveDbCommand StoredProcedure(
167+
this DbConnection target,
168+
string command)
169+
=> new ExpressiveDbCommand(target, CommandType.StoredProcedure, command);
170+
171+
/// <summary>
172+
/// Creates an ExpressiveDbCommand for subsequent configuration and execution.
173+
/// </summary>
174+
/// <param name="target">The connection factory to generate a commands from.</param>
175+
/// <param name="command">The command text or stored procedure name to use.</param>
176+
/// <param name="type">The command type.</param>
177+
/// <returns>The resultant ExpressiveDbCommand.</returns>
178+
public static ExpressiveDbCommand Command(
179+
this IDbConnectionFactory<DbConnection> target,
180+
string command,
181+
CommandType type = CommandType.Text)
182+
=> new ExpressiveDbCommand(target, type, command);
183+
184+
/// <summary>
185+
/// Creates an ExpressiveDbCommand with command type set to StoredProcedure for subsequent configuration and execution.
186+
/// </summary>
187+
/// <param name="target">The connection factory to generate a commands from.</param>
188+
/// <param name="command">The command text or stored procedure name to use.</param>
189+
/// <returns>The resultant ExpressiveDbCommand.</returns>
190+
public static ExpressiveDbCommand StoredProcedure(
191+
this IDbConnectionFactory<DbConnection> target,
192+
string command)
193+
=> new ExpressiveDbCommand(target, CommandType.StoredProcedure, command);
194+
195+
/// <summary>
196+
/// Creates an ExpressiveDbCommand for subsequent configuration and execution.
197+
/// </summary>
198+
/// <param name="target">The connection factory to generate a commands from.</param>
199+
/// <param name="command">The command text or stored procedure name to use.</param>
200+
/// <param name="type">The command type.</param>
201+
/// <returns>The resultant ExpressiveDbCommand.</returns>
202+
public static ExpressiveDbCommand Command(
203+
this Func<DbConnection> target,
204+
string command,
205+
CommandType type = CommandType.Text)
206+
=> Command(new DbConnectionFactory(target), command, type);
207+
208+
/// <summary>
209+
/// Creates an ExpressiveDbCommand with command type set to StoredProcedure for subsequent configuration and execution.
210+
/// </summary>
211+
/// <param name="target">The connection factory to generate a commands from.</param>
212+
/// <param name="command">The command text or stored procedure name to use.</param>
213+
/// <returns>The resultant ExpressiveDbCommand.</returns>
214+
public static ExpressiveDbCommand StoredProcedure(
215+
this Func<DbConnection> target,
216+
string command)
217+
=> StoredProcedure(new DbConnectionFactory(target), command);
218+
219+
220+
}
221+
}

Extensions.Dataflow.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ public static async Task ToTargetBlockAsync<T>(this DbCommand command,
6161
{
6262
if (target.IsStillAlive())
6363
{
64-
using (var reader = await command.ExecuteReaderAsync())
64+
if (command.Connection.State != ConnectionState.Open) await command.Connection.EnsureOpenAsync();
65+
using (var reader = await command.ExecuteReaderAsync())
6566
{
6667
if (target.IsStillAlive())
6768
await reader.ToTargetBlockAsync(target, transform);

0 commit comments

Comments
 (0)