Commit 10c51f42 authored by Marc Gravell's avatar Marc Gravell

async multiplexed / pipeline implemented 1.24

parent 1393169c
...@@ -32,5 +32,5 @@ ...@@ -32,5 +32,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.23.0.0")] [assembly: AssemblyVersion("1.24.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")] [assembly: AssemblyFileVersion("1.24.0.0")]
...@@ -71,6 +71,7 @@ public static Task<int> ExecuteAsync(this IDbConnection cnn, CommandDefinition c ...@@ -71,6 +71,7 @@ public static Task<int> ExecuteAsync(this IDbConnection cnn, CommandDefinition c
return ExecuteImplAsync(cnn, command, param); return ExecuteImplAsync(cnn, command, param);
} }
} }
private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandDefinition command, IEnumerable multiExec) private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandDefinition command, IEnumerable multiExec)
{ {
bool isFirst = true; bool isFirst = true;
...@@ -79,26 +80,57 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD ...@@ -79,26 +80,57 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
try try
{ {
if (wasClosed) await ((DbConnection)cnn).OpenAsync().ConfigureAwait(false); if (wasClosed) await ((DbConnection)cnn).OpenAsync().ConfigureAwait(false);
using (var cmd = (DbCommand)command.SetupCommand(cnn, null))
CacheInfo info = null;
if ((command.Flags & CommandFlags.Pipelined) != 0)
{ {
string masterSql = null; const int MAX_PENDING = 100;
CacheInfo info = null; var pending = new Queue<Task<int>>(MAX_PENDING);
foreach (var obj in multiExec) foreach (var obj in multiExec)
{ {
var cmd = (DbCommand)command.SetupCommand(cnn, null);
if (isFirst) if (isFirst)
{ {
masterSql = cmd.CommandText;
isFirst = false; isFirst = false;
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null); var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
info = GetCacheInfo(identity, obj); info = GetCacheInfo(identity, obj);
} }
else info.ParamReader(cmd, obj);
var task = cmd.ExecuteNonQueryAsync(command.CancellationToken);
pending.Enqueue(task);
if(pending.Count == MAX_PENDING)
{ {
cmd.CommandText = masterSql; // because we do magic replaces on "in" etc total += await pending.Dequeue().ConfigureAwait(false);
cmd.Parameters.Clear(); // current code is Add-tastic }
}
while(pending.Count != 0)
{
total += await pending.Dequeue().ConfigureAwait(false);
}
return total;
}
else
{
using (var cmd = (DbCommand)command.SetupCommand(cnn, null))
{
string masterSql = null;
foreach (var obj in multiExec)
{
if (isFirst)
{
masterSql = cmd.CommandText;
isFirst = false;
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
info = GetCacheInfo(identity, obj);
}
else
{
cmd.CommandText = masterSql; // because we do magic replaces on "in" etc
cmd.Parameters.Clear(); // current code is Add-tastic
}
info.ParamReader(cmd, obj);
total += await cmd.ExecuteNonQueryAsync(command.CancellationToken).ConfigureAwait(false);
} }
info.ParamReader(cmd, obj);
total += await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
} }
} }
} }
......
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.23.0.0")] [assembly: AssemblyVersion("1.24.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")] [assembly: AssemblyFileVersion("1.24.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.23.0.0")] [assembly: AssemblyVersion("1.24.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")] [assembly: AssemblyFileVersion("1.24.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.23.0.0")] [assembly: AssemblyVersion("1.24.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")] [assembly: AssemblyFileVersion("1.24.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.23.0.0")] [assembly: AssemblyVersion("1.24.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")] [assembly: AssemblyFileVersion("1.24.0.0")]
...@@ -16,9 +16,16 @@ static void Main() ...@@ -16,9 +16,16 @@ static void Main()
} }
public static readonly string connectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True"; public static readonly string connectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True";
public static SqlConnection GetOpenConnection() public static SqlConnection GetOpenConnection(bool mars = false)
{ {
var connection = new SqlConnection(connectionString); var cs = connectionString;
if (mars)
{
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder(cs);
scsb.MultipleActiveResultSets = true;
cs = scsb.ConnectionString;
}
var connection = new SqlConnection(cs);
connection.Open(); connection.Open();
return connection; return connection;
} }
......
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.23.0.0")] [assembly: AssemblyVersion("1.24.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")] [assembly: AssemblyFileVersion("1.24.0.0")]
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using Dapper; using Dapper;
using SqlMapper; using SqlMapper;
using System.Data; using System.Data;
using System.Diagnostics;
namespace DapperTests_NET45 namespace DapperTests_NET45
{ {
...@@ -207,6 +208,26 @@ public void LiteralIn() ...@@ -207,6 +208,26 @@ public void LiteralIn()
} }
} }
public void RunSequentialVersusParallel()
{
var ids = Enumerable.Range(1, 2000).Select(id => new { id }).ToArray();
using (var connection = Program.GetOpenConnection(true))
{
connection.ExecuteAsync(new CommandDefinition("select @id", ids.Take(5), flags: CommandFlags.None)).Wait();
var watch = Stopwatch.StartNew();
connection.ExecuteAsync(new CommandDefinition("select @id", ids, flags: CommandFlags.None)).Wait();
watch.Stop();
System.Console.WriteLine("No pipeline: {0}ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
connection.ExecuteAsync(new CommandDefinition("select @id", ids, flags: CommandFlags.Pipelined)).Wait();
watch.Stop();
System.Console.WriteLine("Pipeline: {0}ms", watch.ElapsedMilliseconds);
}
}
class Product class Product
{ {
public int Id { get; set; } public int Id { get; set; }
......
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.23.0.0")] [assembly: AssemblyVersion("1.24.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")] [assembly: AssemblyFileVersion("1.24.0.0")]
...@@ -2697,25 +2697,46 @@ enum AnEnum ...@@ -2697,25 +2697,46 @@ enum AnEnum
A = 2, A = 2,
B = 1 B = 1
} }
enum AnotherEnum : byte
{
A = 2,
B = 1
}
public void LiteralReplacementEnumAndString() public void LiteralReplacementEnumAndString()
{ {
var args = new { x = AnEnum.B, y = 123.45M }; var args = new { x = AnEnum.B, y = 123.45M, z = AnotherEnum.A };
var row = connection.Query("select {=x} as x,{=y} as y", args).Single(); var row = connection.Query("select {=x} as x,{=y} as y,cast({=z} as tinyint) as z", args).Single();
AnEnum x = (AnEnum)(int)row.x; AnEnum x = (AnEnum)(int)row.x;
decimal y = row.y; decimal y = row.y;
AnotherEnum z = (AnotherEnum)(byte)row.z;
x.Equals(AnEnum.B); x.Equals(AnEnum.B);
y.Equals(123.45M); y.Equals(123.45M);
z.Equals(AnotherEnum.A);
} }
public void LiteralReplacementDynamicEnumAndString() public void LiteralReplacementDynamicEnumAndString()
{ {
var args = new DynamicParameters(); var args = new DynamicParameters();
args.Add("x", AnEnum.B); args.Add("x", AnEnum.B);
args.Add("y", 123.45M); args.Add("y", 123.45M);
var row = connection.Query("select {=x} as x,{=y} as y", args).Single(); args.Add("z", AnotherEnum.A);
var row = connection.Query("select {=x} as x,{=y} as y,cast({=z} as tinyint) as z", args).Single();
AnEnum x = (AnEnum)(int)row.x; AnEnum x = (AnEnum)(int)row.x;
decimal y = row.y; decimal y = row.y;
AnotherEnum z = (AnotherEnum)(byte)row.z;
x.Equals(AnEnum.B); x.Equals(AnEnum.B);
y.Equals(123.45M); y.Equals(123.45M);
z.Equals(AnotherEnum.A);
}
public void LiteralReplacementWithIn()
{
var data = connection.Query<MyRow>("select @x where 1 in @ids and 1 ={=a}",
new { x = 1, ids = new[] { 1, 2, 3 }, a = 1 }).ToList();
}
class MyRow
{
public int x { get; set; }
} }
public void LiteralIn() public void LiteralIn()
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata schemaVersion="2"> <metadata schemaVersion="2">
<id>Dapper</id> <id>Dapper</id>
<version>1.23</version> <version>1.24</version>
<title>Dapper dot net</title> <title>Dapper dot net</title>
<authors>Sam Saffron,Marc Gravell</authors> <authors>Sam Saffron,Marc Gravell</authors>
<owners>Sam Saffron,Marc Gravell</owners> <owners>Sam Saffron,Marc Gravell</owners>
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
<frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.0-Client, .NETFramework4.0" /> <frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.0-Client, .NETFramework4.0" />
</frameworkAssemblies> </frameworkAssemblies>
<releaseNotes> <releaseNotes>
* 1.24 - Implement pipelined async multi-exec, when flag is specified (only - requires MARS etc)
* 1.23 - Improved support for optimize hints (@foo unknown) with list expansions * 1.23 - Improved support for optimize hints (@foo unknown) with list expansions
* 1.22 - Literal support now extends to enumerable types (for "in" etc usage); move to command-flags model for "buffered" etc * 1.22 - Literal support now extends to enumerable types (for "in" etc usage); move to command-flags model for "buffered" etc
* 1.21 - Limit literals to numeric types; for enums, use value not name * 1.21 - Limit literals to numeric types; for enums, use value not name
......
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