Commit 863c4c27 authored by Marc Gravell's avatar Marc Gravell

Merge branch 'master' into fix_detached_head

parents bef7af6b b87d9583
This diff is collapsed.
......@@ -95,13 +95,15 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
{
buffer.Add((T)func(reader));
}
while (await reader.NextResultAsync().ConfigureAwait(false)) { }
command.FireOutputCallbacks();
return buffer;
}
else
{
// can't use ReadAsync / cancellation; but this will have to do
wasClosed = false; // don't close if handing back an open reader; rely on the command-behavior
var deferred = ExecuteReaderSync<T>(reader, func);
var deferred = ExecuteReaderSync<T>(reader, func, command.Parameters);
reader = null; // to prevent it being disposed before the caller gets to see it
return deferred;
}
......@@ -211,7 +213,6 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
using (pending.Dequeue().Command) { } // dispose commands
}
}
return total;
}
else
{
......@@ -236,6 +237,8 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
}
}
}
command.FireOutputCallbacks();
}
finally
{
......@@ -253,7 +256,9 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
try
{
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
return await cmd.ExecuteNonQueryAsync(command.CancellationToken).ConfigureAwait(false);
var result = await cmd.ExecuteNonQueryAsync(command.CancellationToken).ConfigureAwait(false);
command.FireOutputCallbacks();
return result;
}
finally
{
......@@ -446,7 +451,7 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
using (var reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false))
{
if (!command.Buffered) wasClosed = false; // handing back open reader; rely on command-behavior
var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, default(CommandDefinition), map, splitOn, reader, identity);
var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, CommandDefinition.ForCallback(command.Parameters), map, splitOn, reader, identity);
return command.Buffered ? results.ToList() : results;
}
} finally
......@@ -455,12 +460,15 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
}
}
private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDataReader,object> func)
private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDataReader,object> func, object parameters)
{
while (reader.Read())
{
yield return (T)func(reader);
}
while (reader.NextResult()) { }
if (parameters is DynamicParameters)
((DynamicParameters)parameters).FireOutputCallbacks();
}
/// <summary>
......@@ -481,7 +489,7 @@ private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDat
partial class GridReader
{
CancellationToken cancel;
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, CancellationToken cancel) : this(command, reader, identity)
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, DynamicParameters dynamicParams, CancellationToken cancel) : this(command, reader, identity, dynamicParams)
{
this.cancel = cancel;
}
......@@ -524,7 +532,7 @@ private async Task NextResultAsync()
// need for "Cancel" etc
reader.Dispose();
reader = null;
if (dynamicParams != null) dynamicParams.FireOutputCallbacks();
Dispose();
}
}
......@@ -600,7 +608,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader);
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false);
var result = new GridReader(cmd, reader, identity, command.CancellationToken);
var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.CancellationToken);
wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader
// with the CloseConnection flag, so the reader will deal with the connection; we
// still need something in the "finally" to ensure that broken SQL still results
......@@ -758,6 +766,7 @@ private async static Task<T> ExecuteScalarImplAsync<T>(IDbConnection cnn, Comman
cmd = (DbCommand)command.SetupCommand(cnn, paramReader);
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
result = await cmd.ExecuteScalarAsync(command.CancellationToken).ConfigureAwait(false);
command.FireOutputCallbacks();
}
finally
{
......
......@@ -355,5 +355,199 @@ public void Issue22_ExecuteScalar()
k.IsNull();
}
}
public void TestSupportForDynamicParametersOutputExpressions()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
connection.ExecuteAsync(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId", p).Wait();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Scalar()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = (int)connection.ExecuteScalarAsync(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p).Result;
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_Default()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.QueryAsync<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p).Result.Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_Buffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.QueryAsync<int>(new CommandDefinition(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, flags: CommandFlags.Buffered)).Result.Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_NonBuffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.QueryAsync<int>(new CommandDefinition(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, flags: CommandFlags.None)).Result.Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_QueryMultiple()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
int x, y;
using(var multi = connection.QueryMultipleAsync(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
select 42
select 17
SET @AddressPersonId = @PersonId", p).Result)
{
x = multi.ReadAsync<int>().Result.Single();
y = multi.ReadAsync<int>().Result.Single();
}
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
x.IsEqualTo(42);
y.IsEqualTo(17);
}
}
class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public string Occupation { get; private set; }
public int NumberOfLegs = 2;
public Address Address { get; set; }
}
class Address
{
public int AddressId { get; set; }
public string Name { get; set; }
public int PersonId { get; set; }
}
}
}
\ No newline at end of file
......@@ -1200,7 +1200,130 @@ public void TestSupportForDynamicParametersOutputExpressions()
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
}
public void TestSupportForDynamicParametersOutputExpressions_Scalar()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = (int)connection.ExecuteScalar(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p);
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_Buffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.Query<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, buffered: true).Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_NonBuffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.Query<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, buffered: false).Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_QueryMultiple()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
int x, y;
using (var multi = connection.QueryMultiple(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
select 42
select 17
SET @AddressPersonId = @PersonId", p))
{
x = multi.Read<int>().Single();
y = multi.Read<int>().Single();
}
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
x.IsEqualTo(42);
y.IsEqualTo(17);
}
}
public void TestSupportForExpandoObjectParameters()
{
dynamic p = new ExpandoObject();
......
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