Skip to content

Commit 33acaa4

Browse files
David EllingsworthDavid Ellingsworth
authored andcommitted
GH-3530: Use type specific methods of DbDataReader where possible and
use Convert with the user provided locale if necessary.
1 parent 4e714b9 commit 33acaa4

24 files changed

+456
-54
lines changed

src/NHibernate/Type/AbstractCharType.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,24 @@ public AbstractCharType(SqlType sqlType) : base(sqlType)
2020

2121
public override object Get(DbDataReader rs, int index, ISessionImplementor session)
2222
{
23-
string dbValue = Convert.ToString(rs[index]);
23+
if (rs.TryGetChar(index, out var dbValue))
24+
{
25+
return dbValue;
26+
}
27+
28+
if (!rs.TryGetString(index, out var strValue))
29+
{
30+
var locale = session.Factory.Settings.Locale;
31+
32+
strValue = Convert.ToString(rs[index], locale);
33+
}
34+
2435
// The check of the Length is a workaround see NH-2340
25-
if (dbValue.Length > 0)
36+
if (strValue.Length > 0)
2637
{
27-
return dbValue[0];
38+
return strValue[0];
2839
}
40+
2941
return '\0'; // This line should never be executed
3042
}
3143

src/NHibernate/Type/AbstractDateTimeType.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,14 @@ protected virtual DateTime GetDateTime(DbDataReader rs, int index, ISessionImple
6464
{
6565
try
6666
{
67-
return AdjustDateTime(Convert.ToDateTime(rs[index]));
67+
if (!rs.TryGetDateTime(index, out var dbValue))
68+
{
69+
var locale = session.Factory.Settings.Locale;
70+
71+
dbValue = Convert.ToDateTime(rs[index], locale);
72+
}
73+
74+
return AdjustDateTime(dbValue);
6875
}
6976
catch (Exception ex)
7077
{

src/NHibernate/Type/AbstractStringType.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Data.Common;
44
using System.Globalization;
@@ -73,7 +73,14 @@ public override void Set(DbCommand cmd, object value, int index, ISessionImpleme
7373

7474
public override object Get(DbDataReader rs, int index, ISessionImplementor session)
7575
{
76-
return Convert.ToString(rs[index]);
76+
if (!rs.TryGetString(index, out var dbValue))
77+
{
78+
var locale = session.Factory.Settings.Locale;
79+
80+
dbValue = Convert.ToString(rs[index], locale);
81+
}
82+
83+
return dbValue;
7784
}
7885

7986
public override bool IsEqual(object x, object y)

src/NHibernate/Type/BooleanType.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ public BooleanType(AnsiStringFixedLengthSqlType sqlType) : base(sqlType)
4040

4141
public override object Get(DbDataReader rs, int index, ISessionImplementor session)
4242
{
43-
return GetBooleanAsObject(Convert.ToBoolean(rs[index]));
43+
if (!rs.TryGetBoolean(index, out var dbValue))
44+
{
45+
var locale = session.Factory.Settings.Locale;
46+
47+
dbValue = Convert.ToBoolean(rs[index], locale);
48+
}
49+
50+
return GetBooleanAsObject(dbValue);
4451
}
4552

4653
public override System.Type PrimitiveClass => typeof(bool);

src/NHibernate/Type/ByteType.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,17 @@ public ByteType() : base(SqlTypeFactory.Byte)
2424

2525
public override object Get(DbDataReader rs, int index, ISessionImplementor session)
2626
{
27-
return rs[index] switch
27+
if (rs.TryGetByte(index, out var dbValue))
2828
{
29+
return dbValue;
30+
}
31+
32+
var locale = session.Factory.Settings.Locale;
2933

34+
return rs[index] switch
35+
{
3036
BigInteger bi => (byte) bi,
31-
var c => Convert.ToByte(c)
37+
var c => Convert.ToByte(c, locale)
3238
};
3339
}
3440

src/NHibernate/Type/CharBooleanType.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,20 @@ protected CharBooleanType(AnsiStringFixedLengthSqlType sqlType) : base(sqlType)
2929

3030
public override object Get(DbDataReader rs, int index, ISessionImplementor session)
3131
{
32-
string code = Convert.ToString(rs[index]);
33-
if (code == null)
32+
if (!rs.TryGetString(index, out var dbValue))
33+
{
34+
var locale = session.Factory.Settings.Locale;
35+
36+
dbValue = Convert.ToString(rs[index], locale);
37+
}
38+
39+
if (dbValue == null)
3440
{
3541
return null;
3642
}
3743
else
3844
{
39-
return GetBooleanAsObject(code.Equals(TrueString, StringComparison.InvariantCultureIgnoreCase));
45+
return GetBooleanAsObject(dbValue.Equals(TrueString, StringComparison.InvariantCultureIgnoreCase));
4046
}
4147
}
4248

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
using System;
2+
using System.Data.Common;
3+
4+
namespace NHibernate.Type
5+
{
6+
internal static class DbRecordSetExtensions
7+
{
8+
public static bool TryGetBoolean(this DbDataReader rs, int ordinal, out bool value)
9+
{
10+
try
11+
{
12+
value = rs.GetBoolean(ordinal);
13+
return true;
14+
}
15+
catch (InvalidCastException)
16+
{
17+
value = default;
18+
return false;
19+
}
20+
}
21+
22+
public static bool TryGetByte(this DbDataReader rs, int ordinal, out byte value)
23+
{
24+
try
25+
{
26+
value = rs.GetByte(ordinal);
27+
return true;
28+
}
29+
catch (InvalidCastException)
30+
{
31+
value = default;
32+
return false;
33+
}
34+
}
35+
36+
public static bool TryGetChar(this DbDataReader rs, int ordinal, out char value)
37+
{
38+
try
39+
{
40+
value = rs.GetChar(ordinal);
41+
return true;
42+
}
43+
catch (InvalidCastException)
44+
{
45+
value = default;
46+
return false;
47+
}
48+
}
49+
50+
public static bool TryGetDecimal(this DbDataReader rs, int ordinal, out decimal value)
51+
{
52+
try
53+
{
54+
value = rs.GetDecimal(ordinal);
55+
return true;
56+
}
57+
catch (InvalidCastException)
58+
{
59+
value = default;
60+
return false;
61+
}
62+
}
63+
64+
public static bool TryGetDouble(this DbDataReader rs, int ordinal, out double value)
65+
{
66+
try
67+
{
68+
value = rs.GetDouble(ordinal);
69+
return true;
70+
}
71+
catch (InvalidCastException)
72+
{
73+
value = default;
74+
return false;
75+
}
76+
}
77+
78+
public static bool TryGetDateTime(this DbDataReader rs, int ordinal, out DateTime value)
79+
{
80+
try
81+
{
82+
value = rs.GetDateTime(ordinal);
83+
return true;
84+
}
85+
catch (InvalidCastException)
86+
{
87+
value = default;
88+
return false;
89+
}
90+
}
91+
public static bool TryGetFloat(this DbDataReader rs, int ordinal, out float value)
92+
{
93+
try
94+
{
95+
value = rs.GetFloat(ordinal);
96+
return true;
97+
}
98+
catch (InvalidCastException)
99+
{
100+
value = default;
101+
return false;
102+
}
103+
}
104+
public static bool TryGetGuid(this DbDataReader rs, int ordinal, out Guid value)
105+
{
106+
try
107+
{
108+
value = rs.GetGuid(ordinal);
109+
return true;
110+
}
111+
catch (InvalidCastException)
112+
{
113+
value = default;
114+
return false;
115+
}
116+
}
117+
118+
public static bool TryGetUInt16(this DbDataReader rs, int ordinal, out ushort value)
119+
{
120+
var dbValue = rs[ordinal];
121+
122+
if (dbValue is ushort)
123+
{
124+
value = (ushort)dbValue;
125+
return true;
126+
}
127+
128+
value = default;
129+
return false;
130+
}
131+
132+
public static bool TryGetInt16(this DbDataReader rs, int ordinal, out short value)
133+
{
134+
try
135+
{
136+
value = rs.GetInt16(ordinal);
137+
return true;
138+
}
139+
catch (InvalidCastException)
140+
{
141+
value = default;
142+
return false;
143+
}
144+
}
145+
public static bool TryGetInt32(this DbDataReader rs, int ordinal, out int value)
146+
{
147+
try
148+
{
149+
value = rs.GetInt32(ordinal);
150+
return true;
151+
}
152+
catch (InvalidCastException)
153+
{
154+
value = default;
155+
return false;
156+
}
157+
}
158+
159+
public static bool TryGetUInt32(this DbDataReader rs, int ordinal, out uint value)
160+
{
161+
var dbValue = rs[ordinal];
162+
163+
if (dbValue is uint)
164+
{
165+
value = (uint) dbValue;
166+
return true;
167+
}
168+
169+
value = default;
170+
return false;
171+
}
172+
173+
public static bool TryGetInt64(this DbDataReader rs, int ordinal, out long value)
174+
{
175+
try
176+
{
177+
value = rs.GetInt64(ordinal);
178+
return true;
179+
}
180+
catch (InvalidCastException)
181+
{
182+
value = default;
183+
return false;
184+
}
185+
}
186+
187+
public static bool TryGetUInt64(this DbDataReader rs, int ordinal, out ulong value)
188+
{
189+
var dbValue = rs[ordinal];
190+
191+
if (dbValue is ulong)
192+
{
193+
value = (ulong) dbValue;
194+
return true;
195+
}
196+
197+
value = default;
198+
return false;
199+
}
200+
201+
public static bool TryGetSByte(this DbDataReader rs, int ordinal, out sbyte value)
202+
{
203+
var dbValue = rs[ordinal];
204+
205+
if (dbValue is sbyte)
206+
{
207+
value = (sbyte) rs[ordinal];
208+
return true;
209+
}
210+
211+
value = default;
212+
return false;
213+
}
214+
215+
public static bool TryGetString(this DbDataReader rs, int ordinal, out string value)
216+
{
217+
try
218+
{
219+
value = rs.GetString(ordinal);
220+
return true;
221+
}
222+
catch (InvalidCastException)
223+
{
224+
value = default;
225+
return false;
226+
}
227+
}
228+
229+
public static bool TryGetTimeSpan(this DbDataReader rs, int ordinal, out TimeSpan value)
230+
{
231+
var dbValue = rs[ordinal];
232+
233+
if (dbValue is TimeSpan)
234+
{
235+
value = (TimeSpan) dbValue;
236+
return true;
237+
}
238+
239+
value = default;
240+
return false;
241+
}
242+
}
243+
}

src/NHibernate/Type/DecimalType.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ public DecimalType(SqlType sqlType) : base(sqlType)
2828

2929
public override object Get(DbDataReader rs, int index, ISessionImplementor session)
3030
{
31-
return Convert.ToDecimal(rs[index]);
31+
if (!rs.TryGetDecimal(index, out var dbValue))
32+
{
33+
var locale = session.Factory.Settings.Locale;
34+
35+
dbValue = Convert.ToDecimal(rs[index], locale);
36+
}
37+
38+
return dbValue;
3239
}
3340

3441
public override System.Type ReturnedClass => typeof(Decimal);

0 commit comments

Comments
 (0)