Commit 595ef137 authored by Marc Gravell's avatar Marc Gravell

fix #465

parent b7a7856e
......@@ -3077,6 +3077,29 @@ public void Issue426_SO34439033_DateTimeGainsTicks()
}
}
[FactMySql]
public void TestStringTimespansFromMySql()
{
using (var conn = GetOpenConnection())
{
try { conn.Execute(@"drop table issue465table"); }
catch { }
conn.Execute(@"create table issue465table (
id integer primary key,
duration text not null,
);
insert into issue465table(id, duration) values (1, '0.01:00:00');");
var row = conn.QuerySingle<Issue465Row>(
"select * from issue465table");
row.Id.IsEqualTo(1);
row.Duration.IsEqualTo(TimeSpan.FromHours(1));
}
}
public class Issue465Row
{
public long Id { get; set; }
public TimeSpan Duration { get; set; }
}
public class Issue426_Test
{
......
......@@ -1723,10 +1723,29 @@ private static Exception MultiMapException(IDataRecord reader)
public static char ReadChar(object value)
{
if (value == null || value is DBNull) throw new ArgumentNullException(nameof(value));
if (value is char) return (char)value;
string s = value as string;
if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", nameof(value));
return s[0];
}
/// <summary>
/// Internal use only
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
#if !COREFX
[Browsable(false)]
#endif
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete(ObsoleteInternalUsageOnly, false)]
public static TimeSpan ReadTimeSpan(object value)
{
if (value == null || value is DBNull) throw new ArgumentNullException(nameof(value));
if (value is TimeSpan) return (TimeSpan)value;
if (value is long) return new TimeSpan((long)value);
if (value is string) return TimeSpan.Parse((string)value, CultureInfo.InvariantCulture);
return (TimeSpan)value; // we expect this to fail; we just want the error message
}
/// <summary>
/// Internal use only
......@@ -1739,9 +1758,21 @@ public static char ReadChar(object value)
public static char? ReadNullableChar(object value)
{
if (value == null || value is DBNull) return null;
string s = value as string;
if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", nameof(value));
return s[0];
return ReadChar(value);
}
/// <summary>
/// Internal use only
/// </summary>
#if !COREFX
[Browsable(false)]
#endif
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete(ObsoleteInternalUsageOnly, false)]
public static TimeSpan? ReadNullableTimeSpan(object value)
{
if (value == null || value is DBNull) return null;
return ReadTimeSpan(value);
}
......@@ -2567,6 +2598,14 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin
{
return r => ReadNullableChar(r.GetValue(index));
}
if (type == typeof(TimeSpan))
{
return r => ReadTimeSpan(r.GetValue(index));
}
if (type == typeof(TimeSpan?))
{
return r => ReadNullableTimeSpan(r.GetValue(index));
}
if (type.FullName == LinqBinary)
{
return r => Activator.CreateInstance(type, r.GetValue(index));
......@@ -2872,6 +2911,11 @@ static LocalBuilder GetTempLocal(ILGenerator il, ref Dictionary<Type, LocalBuild
il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod(
memberType == typeof(char) ? nameof(SqlMapper.ReadChar) : nameof(SqlMapper.ReadNullableChar), BindingFlags.Static | BindingFlags.Public), null); // stack is now [target][target][typed-value]
}
else if (memberType == typeof(TimeSpan) || memberType == typeof(TimeSpan?))
{
il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod(
memberType == typeof(TimeSpan) ? nameof(SqlMapper.ReadTimeSpan) : nameof(SqlMapper.ReadNullableTimeSpan), BindingFlags.Static | BindingFlags.Public), null); // stack is now [target][target][typed-value]
}
else
{
il.Emit(OpCodes.Dup); // stack is now [target][target][value][value]
......
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