Commit 40282d19 authored by Marc Gravell's avatar Marc Gravell

Precision and scale controls (fixes Issue #261)

parent 8ab859c7
...@@ -4457,6 +4457,9 @@ partial class ParamInfo ...@@ -4457,6 +4457,9 @@ partial class ParamInfo
internal Action<object, DynamicParameters> OutputCallback { get; set; } internal Action<object, DynamicParameters> OutputCallback { get; set; }
internal object OutputTarget { get; set; } internal object OutputTarget { get; set; }
internal bool CameFromTemplate { get; set; } internal bool CameFromTemplate { get; set; }
public byte? Precision { get; set; }
public byte? Scale { get; set; }
} }
/// <summary> /// <summary>
...@@ -4529,20 +4532,30 @@ public void AddDynamicParams(object param) ...@@ -4529,20 +4532,30 @@ public void AddDynamicParams(object param)
/// <summary> /// <summary>
/// Add a parameter to this dynamic parameter list /// Add a parameter to this dynamic parameter list
/// </summary> /// </summary>
/// <param name="name"></param> public void Add(string name, object value, DbType? dbType, ParameterDirection? direction, int? size)
/// <param name="value"></param> {
/// <param name="dbType"></param> parameters[Clean(name)] = new ParamInfo() {
/// <param name="direction"></param> Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input,
/// <param name="size"></param> DbType = dbType, Size = size
};
}
/// <summary>
/// Add a parameter to this dynamic parameter list
/// </summary>
public void Add( public void Add(
#if CSHARP30 #if CSHARP30
string name, object value, DbType? dbType, ParameterDirection? direction, int? size string name, object value, DbType? dbType, ParameterDirection? direction, int? size, byte? precision, byte? scale
#else #else
string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null, byte? precision = null, byte? scale = null
#endif #endif
) )
{ {
parameters[Clean(name)] = new ParamInfo() { Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input, DbType = dbType, Size = size }; parameters[Clean(name)] = new ParamInfo() {
Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input,
DbType = dbType, Size = size,
Precision = precision, Scale = scale
};
} }
static string Clean(string name) static string Clean(string name)
...@@ -4686,7 +4699,9 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity) ...@@ -4686,7 +4699,9 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
if (param.Size != null) if (param.Size != null)
{ {
p.Size = param.Size.Value; p.Size = param.Size.Value;
} }
if (param.Precision != null) p.Precision = param.Precision.Value;
if (param.Scale != null) p.Scale = param.Scale.Value;
} }
else else
{ {
......
...@@ -1571,10 +1571,10 @@ public void TestMultiMappingWithNonReturnedProperty() ...@@ -1571,10 +1571,10 @@ public void TestMultiMappingWithNonReturnedProperty()
2 as BlogId, 'Blog' as Title"; 2 as BlogId, 'Blog' as Title";
var postWithBlog = connection.Query<Post_DupeProp, Blog_DupeProp, Post_DupeProp>(sql, var postWithBlog = connection.Query<Post_DupeProp, Blog_DupeProp, Post_DupeProp>(sql,
(p, b) => (p, b) =>
{ {
p.Blog = b; p.Blog = b;
return p; return p;
}, splitOn: "BlogId").First(); }, splitOn: "BlogId").First();
postWithBlog.PostId.IsEqualTo(1); postWithBlog.PostId.IsEqualTo(1);
postWithBlog.Title.IsEqualTo("Title"); postWithBlog.Title.IsEqualTo("Title");
...@@ -1830,15 +1830,15 @@ public void ParentChildIdentityAssociations() ...@@ -1830,15 +1830,15 @@ public void ParentChildIdentityAssociations()
var lookup = new Dictionary<int, Parent>(); var lookup = new Dictionary<int, Parent>();
var parents = connection.Query<Parent, Child, Parent>(@"select 1 as [Id], 1 as [Id] union all select 1,2 union all select 2,3 union all select 1,4 union all select 3,5", var parents = connection.Query<Parent, Child, Parent>(@"select 1 as [Id], 1 as [Id] union all select 1,2 union all select 2,3 union all select 1,4 union all select 3,5",
(parent, child) => (parent, child) =>
{
Parent found;
if (!lookup.TryGetValue(parent.Id, out found))
{ {
lookup.Add(parent.Id, found = parent); Parent found;
} if (!lookup.TryGetValue(parent.Id, out found))
found.Children.Add(child); {
return found; lookup.Add(parent.Id, found = parent);
}).Distinct().ToDictionary(p => p.Id); }
found.Children.Add(child);
return found;
}).Distinct().ToDictionary(p => p.Id);
parents.Count().IsEqualTo(3); parents.Count().IsEqualTo(3);
parents[1].Children.Select(c => c.Id).SequenceEqual(new[] { 1, 2, 4 }).IsTrue(); parents[1].Children.Select(c => c.Id).SequenceEqual(new[] { 1, 2, 4 }).IsTrue();
parents[2].Children.Select(c => c.Id).SequenceEqual(new[] { 3 }).IsTrue(); parents[2].Children.Select(c => c.Id).SequenceEqual(new[] { 3 }).IsTrue();
...@@ -2782,9 +2782,9 @@ public void TestIssue131() ...@@ -2782,9 +2782,9 @@ public void TestIssue131()
var results = connection.Query<dynamic, int, dynamic>( var results = connection.Query<dynamic, int, dynamic>(
"SELECT 1 Id, 'Mr' Title, 'John' Surname, 4 AddressCount", "SELECT 1 Id, 'Mr' Title, 'John' Surname, 4 AddressCount",
(person, addressCount) => (person, addressCount) =>
{ {
return person; return person;
}, },
splitOn: "AddressCount" splitOn: "AddressCount"
).FirstOrDefault(); ).FirstOrDefault();
...@@ -3175,9 +3175,12 @@ class HasDoubleDecimal ...@@ -3175,9 +3175,12 @@ class HasDoubleDecimal
public void DataTableParameters() public void DataTableParameters()
{ {
try { connection.Execute("drop proc #DataTableParameters"); } catch { } try { connection.Execute("drop proc #DataTableParameters"); }
try { connection.Execute("drop table #DataTableParameters"); } catch { } catch { }
try { connection.Execute("drop type MyTVPType"); } catch { } try { connection.Execute("drop table #DataTableParameters"); }
catch { }
try { connection.Execute("drop type MyTVPType"); }
catch { }
connection.Execute("create type MyTVPType as table (id int)"); connection.Execute("create type MyTVPType as table (id int)");
connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids"); connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids");
...@@ -3193,7 +3196,8 @@ public void DataTableParameters() ...@@ -3193,7 +3196,8 @@ public void DataTableParameters()
{ {
connection.Query<int>("select count(1) from @ids", new { ids = table.AsTableValuedParameter() }).First(); connection.Query<int>("select count(1) from @ids", new { ids = table.AsTableValuedParameter() }).First();
throw new InvalidOperationException(); throw new InvalidOperationException();
} catch (Exception ex) }
catch (Exception ex)
{ {
ex.Message.Equals("The table type parameter 'ids' must have a valid type name."); ex.Message.Equals("The table type parameter 'ids' must have a valid type name.");
} }
...@@ -3201,12 +3205,14 @@ public void DataTableParameters() ...@@ -3201,12 +3205,14 @@ public void DataTableParameters()
public void SO26468710_InWithTVPs() public void SO26468710_InWithTVPs()
{ {
// this is just to make it re-runnable; normally you only do this once // this is just to make it re-runnable; normally you only do this once
try { connection.Execute("drop type MyIdList"); } catch { } try { connection.Execute("drop type MyIdList"); }
catch { }
connection.Execute("create type MyIdList as table(id int);"); connection.Execute("create type MyIdList as table(id int);");
DataTable ids = new DataTable { DataTable ids = new DataTable
Columns = {{"id", typeof(int)}}, {
Rows = {{1},{3},{5}} Columns = { { "id", typeof(int) } },
Rows = { { 1 }, { 3 }, { 5 } }
}; };
ids.SetTypeName("MyIdList"); ids.SetTypeName("MyIdList");
int sum = connection.Query<int>(@" int sum = connection.Query<int>(@"
...@@ -3217,9 +3223,12 @@ public void SO26468710_InWithTVPs() ...@@ -3217,9 +3223,12 @@ public void SO26468710_InWithTVPs()
} }
public void DataTableParametersWithExtendedProperty() public void DataTableParametersWithExtendedProperty()
{ {
try { connection.Execute("drop proc #DataTableParameters"); } catch { } try { connection.Execute("drop proc #DataTableParameters"); }
try { connection.Execute("drop table #DataTableParameters"); } catch { } catch { }
try { connection.Execute("drop type MyTVPType"); } catch { } try { connection.Execute("drop table #DataTableParameters"); }
catch { }
try { connection.Execute("drop type MyTVPType"); }
catch { }
connection.Execute("create type MyTVPType as table (id int)"); connection.Execute("create type MyTVPType as table (id int)");
connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids"); connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids");
...@@ -3624,7 +3633,8 @@ public class LocalDateResult ...@@ -3624,7 +3633,8 @@ public class LocalDateResult
public LocalDate? NullableIsNull { get; set; } public LocalDate? NullableIsNull { get; set; }
} }
public class LotsOfNumerics { public class LotsOfNumerics
{
public enum E_Byte : byte { A = 0, B = 1 } public enum E_Byte : byte { A = 0, B = 1 }
public enum E_SByte : sbyte { A = 0, B = 1 } public enum E_SByte : sbyte { A = 0, B = 1 }
public enum E_Short : short { A = 0, B = 1 } public enum E_Short : short { A = 0, B = 1 }
...@@ -3832,7 +3842,8 @@ public void SO25069578_DynamicParams_Procs() ...@@ -3832,7 +3842,8 @@ public void SO25069578_DynamicParams_Procs()
var parameters = new DynamicParameters(); var parameters = new DynamicParameters();
parameters.Add("foo", "bar"); parameters.Add("foo", "bar");
// parameters = new DynamicParameters(parameters); // parameters = new DynamicParameters(parameters);
try { connection.Execute("drop proc SO25069578"); } catch { } try { connection.Execute("drop proc SO25069578"); }
catch { }
connection.Execute("create proc SO25069578 @foo nvarchar(max) as select @foo as [X]"); connection.Execute("create proc SO25069578 @foo nvarchar(max) as select @foo as [X]");
var tran = connection.BeginTransaction(); // gist used transaction; behaves the same either way, though var tran = connection.BeginTransaction(); // gist used transaction; behaves the same either way, though
var row = connection.Query<HazX>("SO25069578", parameters, var row = connection.Query<HazX>("SO25069578", parameters,
...@@ -3849,14 +3860,15 @@ public void Issue149_TypeMismatch_SequentialAccess() ...@@ -3849,14 +3860,15 @@ public void Issue149_TypeMismatch_SequentialAccess()
{ {
var result = connection.Query<Issue149_Person>(@"select @guid as Id", new { guid }).First(); var result = connection.Query<Issue149_Person>(@"select @guid as Id", new { guid }).First();
error = null; error = null;
} catch(Exception ex) }
catch (Exception ex)
{ {
error = ex.Message; error = ex.Message;
} }
error.IsEqualTo("Error parsing column 0 (Id=cf0ef7ac-b6fe-4e24-aeda-a2b45bb5654e - Object)"); error.IsEqualTo("Error parsing column 0 (Id=cf0ef7ac-b6fe-4e24-aeda-a2b45bb5654e - Object)");
} }
public class Issue149_Person { public string Id { get; set; } } public class Issue149_Person { public string Id { get; set; } }
public class HazX public class HazX
{ {
public string X { get; set; } public string X { get; set; }
...@@ -3878,7 +3890,7 @@ public void SO25297173_DynamicIn() ...@@ -3878,7 +3890,7 @@ public void SO25297173_DynamicIn()
var queryParams = new Dictionary<string, object> { var queryParams = new Dictionary<string, object> {
{ "myIds", new [] { 5, 6 } } { "myIds", new [] { 5, 6 } }
}; };
var dynamicParams = new DynamicParameters(queryParams); var dynamicParams = new DynamicParameters(queryParams);
List<int> result = connection.Query<int>(query, dynamicParams).ToList(); List<int> result = connection.Query<int>(query, dynamicParams).ToList();
result.Count.IsEqualTo(2); result.Count.IsEqualTo(2);
...@@ -3900,8 +3912,10 @@ public void AllowIDictionaryParameters() ...@@ -3900,8 +3912,10 @@ public void AllowIDictionaryParameters()
public void Issue178_SqlServer() public void Issue178_SqlServer()
{ {
const string sql = @"select count(*) from Issue178"; const string sql = @"select count(*) from Issue178";
try { connection.Execute("drop table Issue178"); } catch { } try { connection.Execute("drop table Issue178"); }
try { connection.Execute("create table Issue178(id int not null)"); } catch { } catch { }
try { connection.Execute("create table Issue178(id int not null)"); }
catch { }
// raw ADO.net // raw ADO.net
var sqlCmd = new SqlCommand(sql, connection); var sqlCmd = new SqlCommand(sql, connection);
using (IDataReader reader1 = sqlCmd.ExecuteReader()) using (IDataReader reader1 = sqlCmd.ExecuteReader())
...@@ -3930,7 +3944,8 @@ public void Issue178_SqlServer() ...@@ -3930,7 +3944,8 @@ public void Issue178_SqlServer()
{ {
connection.Open(); connection.Open();
const string sql = @"select count(*) from Issue178"; const string sql = @"select count(*) from Issue178";
try { connection.Execute("drop table Issue178"); } catch { } try { connection.Execute("drop table Issue178"); }
catch { }
connection.Execute("create table Issue178(id int not null)"); connection.Execute("create table Issue178(id int not null)");
connection.Execute("insert into Issue178(id) values(42)"); connection.Execute("insert into Issue178(id) values(42)");
// raw ADO.net // raw ADO.net
...@@ -4055,7 +4070,7 @@ public class Dyno ...@@ -4055,7 +4070,7 @@ public class Dyno
public dynamic Id { get; set; } public dynamic Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public object Foo { get;set; } public object Foo { get; set; }
} }
public void Issue151_ExpandoObjectArgsQuery() public void Issue151_ExpandoObjectArgsQuery()
...@@ -4147,8 +4162,33 @@ public void ExplicitConstructors() ...@@ -4147,8 +4162,33 @@ public void ExplicitConstructors()
public void Issue220_InParameterCanBeSpecifiedInAnyCase() public void Issue220_InParameterCanBeSpecifiedInAnyCase()
{ {
// note this might fail if your database server is case-sensitive // note this might fail if your database server is case-sensitive
connection.Query<int>("select * from (select 1 as Id) as X where Id in @ids", new {Ids = new[] {1}}) connection.Query<int>("select * from (select 1 as Id) as X where Id in @ids", new { Ids = new[] { 1 } })
.IsSequenceEqualTo(new[] {1}); .IsSequenceEqualTo(new[] { 1 });
}
public void SO29343103_UtcDates()
{
const string sql = "select @date";
var date = DateTime.UtcNow;
var returned = connection.Query<DateTime>(sql, new { date }).Single();
var delta = returned - date;
Assert.IsTrue(delta.TotalMilliseconds >= -1 && delta.TotalMilliseconds <= 1);
}
public void Issue261_Decimals()
{
var parameters = new DynamicParameters();
parameters.Add("c", dbType: DbType.Decimal, direction: ParameterDirection.Output, precision: 10, scale: 5);
connection.Execute("create proc #Issue261 @c decimal(10,5) OUTPUT as begin set @c=11.884 end");
connection.Execute("#Issue261", parameters, commandType: CommandType.StoredProcedure);
var c = parameters.Get<Decimal>("c");
c.IsEqualTo(11.884M);
}
public void BasicDecimals()
{
var c = connection.Query<decimal>("select @c", new { c = 11.884M }).Single();
c.IsEqualTo(11.884M);
} }
#if POSTGRESQL #if POSTGRESQL
......
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