Skip to content

Commit 4d0da00

Browse files
bahusoidhazzik
authored andcommitted
Allow to override default types with length or precision parameters (#2100)
1 parent 03e5fa6 commit 4d0da00

File tree

5 files changed

+345
-29
lines changed

5 files changed

+345
-29
lines changed

src/NHibernate.Test/TypesTest/ChangeDefaultTypeClass.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,10 @@ public class ChangeDefaultTypeClass
77
public int Id { get; set; }
88

99
public DateTime NormalDateTimeValue { get; set; } = DateTime.Today;
10+
11+
public string StringTypeLengthInType25 { get; set; }
12+
public string StringTypeExplicitLength20 { get; set; }
13+
public decimal CurrencyTypePrecisionInType5And2 { get; set; }
14+
public decimal CurrencyTypeExplicitPrecision6And3 { get; set; }
1015
}
1116
}

src/NHibernate.Test/TypesTest/ChangeDefaultTypeClass.hbm.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@
1212
</id>
1313

1414
<property name="NormalDateTimeValue"/>
15+
<property name="StringTypeExplicitLength20" column="string20" length="20"/>
16+
<property name="StringTypeLengthInType25" column="string25" type="string(25)" />
17+
<property name="CurrencyTypePrecisionInType5And2" column="currency1" type="currency(5,2)" />
18+
<property name="CurrencyTypeExplicitPrecision6And3" column="currency2" type="currency" precision="6" scale="3" />
1519
</class>
1620
</hibernate-mapping>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using NHibernate.Cfg;
5+
using NHibernate.Engine;
6+
using NHibernate.Impl;
7+
using NHibernate.SqlTypes;
8+
using NHibernate.Type;
9+
using NUnit.Framework;
10+
11+
namespace NHibernate.Test.TypesTest
12+
{
13+
/// <summary>
14+
/// TestFixtures for changing a default .Net type.
15+
/// </summary>
16+
[TestFixture]
17+
public class ChangeDefaultTypeWithLengthFixture : TypeFixtureBase
18+
{
19+
public class CustomStringType : AbstractStringType
20+
{
21+
public CustomStringType() : base(new StringSqlType())
22+
{
23+
}
24+
25+
public CustomStringType(int length) : base(new StringSqlType(length))
26+
{
27+
}
28+
29+
public override string Name => "CustomStringType";
30+
}
31+
32+
protected override string TypeName => "ChangeDefaultType";
33+
34+
private IType _originalDefaultStringType;
35+
private IType _testDefaultStringType;
36+
private static System.Type _replacedType = typeof(string);
37+
38+
protected override void Configure(Configuration configuration)
39+
{
40+
_originalDefaultStringType = TypeFactory.GetDefaultTypeFor(_replacedType);
41+
Assert.That(_originalDefaultStringType, Is.Not.Null);
42+
_testDefaultStringType = new CustomStringType();
43+
44+
TypeFactory.RegisterType(
45+
_replacedType,
46+
_testDefaultStringType,
47+
new[] {"string"},
48+
length => new CustomStringType(length));
49+
base.Configure(configuration);
50+
}
51+
52+
protected override void DropSchema()
53+
{
54+
base.DropSchema();
55+
TypeFactory.ClearCustomRegistrations();
56+
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.Not.EqualTo(_testDefaultStringType));
57+
}
58+
59+
[Test]
60+
public void DefaultType()
61+
{
62+
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.EqualTo(_testDefaultStringType));
63+
}
64+
65+
[Test]
66+
public void PropertyType()
67+
{
68+
var propertyType25 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
69+
.GetPropertyType(nameof(ChangeDefaultTypeClass.StringTypeLengthInType25));
70+
Assert.That(
71+
propertyType25,
72+
Is.EqualTo(_testDefaultStringType));
73+
Assert.That(propertyType25.SqlTypes(Sfi)[0].Length, Is.EqualTo(25));
74+
75+
var propertyType20 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
76+
.GetPropertyType(nameof(ChangeDefaultTypeClass.StringTypeExplicitLength20));
77+
78+
Assert.That(
79+
propertyType20,
80+
Is.EqualTo(_testDefaultStringType));
81+
Assert.That(propertyType20.SqlTypes(Sfi)[0].Length, Is.EqualTo(20));
82+
}
83+
84+
[Test]
85+
public void GuessType()
86+
{
87+
Assert.That(NHibernateUtil.GuessType(_replacedType), Is.EqualTo(_testDefaultStringType));
88+
}
89+
90+
[Test]
91+
public void ParameterType()
92+
{
93+
var namedParametersField = typeof(AbstractQueryImpl)
94+
.GetField("namedParameters", BindingFlags.Instance | BindingFlags.NonPublic);
95+
Assert.That(namedParametersField, Is.Not.Null, "Missing internal field");
96+
97+
using (var s = OpenSession())
98+
{
99+
// Query where the parameter type cannot be deducted from compared entity property
100+
var q = s.CreateQuery($"from {nameof(ChangeDefaultTypeClass)} where :str1 = :str2 or :str1 = :str3")
101+
.SetParameter("str1", "aaa")
102+
.SetString("str2", "bbb")
103+
.SetAnsiString("str3", "bbb");
104+
105+
var namedParameters = namedParametersField.GetValue(q) as Dictionary<string, TypedValue>;
106+
Assert.That(namedParameters, Is.Not.Null, "Unable to retrieve parameters internal field");
107+
Assert.That(namedParameters["str1"].Type, Is.EqualTo(_testDefaultStringType));
108+
Assert.That(namedParameters["str2"].Type, Is.EqualTo(NHibernateUtil.String));
109+
Assert.That(namedParameters["str3"].Type, Is.EqualTo(NHibernateUtil.AnsiString));
110+
}
111+
}
112+
}
113+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using System.Collections.Generic;
2+
using System.Data;
3+
using System.Reflection;
4+
using NHibernate.Cfg;
5+
using NHibernate.Engine;
6+
using NHibernate.Impl;
7+
using NHibernate.SqlTypes;
8+
using NHibernate.Type;
9+
using NUnit.Framework;
10+
11+
namespace NHibernate.Test.TypesTest
12+
{
13+
/// <summary>
14+
/// TestFixtures for changing a default .Net type.
15+
/// </summary>
16+
[TestFixture]
17+
public class ChangeDefaultTypeWithPrecisionFixture : TypeFixtureBase
18+
{
19+
public class CustomCurrencyType : DecimalType
20+
{
21+
public CustomCurrencyType() : base(SqlTypeFactory.Currency)
22+
{
23+
}
24+
25+
public CustomCurrencyType(byte precision, byte scale) : base(new SqlType(DbType.Currency, precision, scale))
26+
{
27+
}
28+
29+
public override string Name => "CustomCurrencyType";
30+
}
31+
32+
protected override string TypeName => "ChangeDefaultType";
33+
34+
private IType _originalDefaultType;
35+
private IType _testDefaultType;
36+
private static System.Type _replacedType = typeof(decimal);
37+
38+
protected override void Configure(Configuration configuration)
39+
{
40+
_originalDefaultType = TypeFactory.GetDefaultTypeFor(_replacedType);
41+
_testDefaultType = new CustomCurrencyType();
42+
Assert.That(_originalDefaultType, Is.Not.Null);
43+
Assert.That(_originalDefaultType, Is.Not.EqualTo(_testDefaultType));
44+
45+
TypeFactory.RegisterType(
46+
_replacedType,
47+
_testDefaultType,
48+
new[] {"currency"},
49+
(precision, scale) => new CustomCurrencyType(precision, scale));
50+
base.Configure(configuration);
51+
}
52+
53+
protected override void DropSchema()
54+
{
55+
base.DropSchema();
56+
TypeFactory.ClearCustomRegistrations();
57+
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.Not.EqualTo(_testDefaultType));
58+
}
59+
60+
[Test]
61+
public void DefaultType()
62+
{
63+
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.EqualTo(_testDefaultType));
64+
}
65+
66+
[Test]
67+
public void PropertyType()
68+
{
69+
var propertyType1 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
70+
.GetPropertyType(nameof(ChangeDefaultTypeClass.CurrencyTypeExplicitPrecision6And3));
71+
Assert.That(
72+
propertyType1,
73+
Is.EqualTo(_testDefaultType));
74+
Assert.That(propertyType1.SqlTypes(Sfi)[0].Precision, Is.EqualTo(6));
75+
Assert.That(propertyType1.SqlTypes(Sfi)[0].Scale, Is.EqualTo(3));
76+
77+
var propertyType2 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
78+
.GetPropertyType(nameof(ChangeDefaultTypeClass.CurrencyTypePrecisionInType5And2));
79+
80+
Assert.That(
81+
propertyType2,
82+
Is.EqualTo(_testDefaultType));
83+
Assert.That(propertyType2.SqlTypes(Sfi)[0].Precision, Is.EqualTo(5));
84+
Assert.That(propertyType2.SqlTypes(Sfi)[0].Scale, Is.EqualTo(2));
85+
}
86+
87+
[Test]
88+
public void GuessType()
89+
{
90+
Assert.That(NHibernateUtil.GuessType(_replacedType), Is.EqualTo(_testDefaultType));
91+
}
92+
93+
[Test]
94+
public void ParameterType()
95+
{
96+
var namedParametersField = typeof(AbstractQueryImpl)
97+
.GetField("namedParameters", BindingFlags.Instance | BindingFlags.NonPublic);
98+
Assert.That(namedParametersField, Is.Not.Null, "Missing internal field");
99+
100+
using (var s = OpenSession())
101+
{
102+
// Query where the parameter type cannot be deducted from compared entity property
103+
var q = s.CreateQuery($"from {nameof(ChangeDefaultTypeClass)} where :str1 = :str2")
104+
.SetParameter("str1", 1.22m)
105+
.SetDecimal("str2", 1m);
106+
107+
var namedParameters = namedParametersField.GetValue(q) as Dictionary<string, TypedValue>;
108+
Assert.That(namedParameters, Is.Not.Null, "Unable to retrieve parameters internal field");
109+
Assert.That(namedParameters["str1"].Type, Is.EqualTo(_testDefaultType));
110+
Assert.That(namedParameters["str2"].Type, Is.EqualTo(NHibernateUtil.Decimal));
111+
}
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)