Skip to content

Allow to override default types with length or precision parameters #2100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/NHibernate.Test/TypesTest/ChangeDefaultTypeClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@ public class ChangeDefaultTypeClass
public int Id { get; set; }

public DateTime NormalDateTimeValue { get; set; } = DateTime.Today;

public string StringTypeLengthInType25 { get; set; }
public string StringTypeExplicitLength20 { get; set; }
public decimal CurrencyTypePrecisionInType5And2 { get; set; }
public decimal CurrencyTypeExplicitPrecision6And3 { get; set; }
}
}
4 changes: 4 additions & 0 deletions src/NHibernate.Test/TypesTest/ChangeDefaultTypeClass.hbm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@
</id>

<property name="NormalDateTimeValue"/>
<property name="StringTypeExplicitLength20" column="string20" length="20"/>
<property name="StringTypeLengthInType25" column="string25" type="string(25)" />
<property name="CurrencyTypePrecisionInType5And2" column="currency1" type="currency(5,2)" />
<property name="CurrencyTypeExplicitPrecision6And3" column="currency2" type="currency" precision="6" scale="3" />
</class>
</hibernate-mapping>
113 changes: 113 additions & 0 deletions src/NHibernate.Test/TypesTest/ChangeDefaultTypeWithLengthFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using NHibernate.Cfg;
using NHibernate.Engine;
using NHibernate.Impl;
using NHibernate.SqlTypes;
using NHibernate.Type;
using NUnit.Framework;

namespace NHibernate.Test.TypesTest
{
/// <summary>
/// TestFixtures for changing a default .Net type.
/// </summary>
[TestFixture]
public class ChangeDefaultTypeWithLengthFixture : TypeFixtureBase
{
public class CustomStringType : AbstractStringType
{
public CustomStringType() : base(new StringSqlType())
{
}

public CustomStringType(int length) : base(new StringSqlType(length))
{
}

public override string Name => "CustomStringType";
}

protected override string TypeName => "ChangeDefaultType";

private IType _originalDefaultStringType;
private IType _testDefaultStringType;
private static System.Type _replacedType = typeof(string);

protected override void Configure(Configuration configuration)
{
_originalDefaultStringType = TypeFactory.GetDefaultTypeFor(_replacedType);
Assert.That(_originalDefaultStringType, Is.Not.Null);
_testDefaultStringType = new CustomStringType();

TypeFactory.RegisterType(
_replacedType,
_testDefaultStringType,
new[] {"string"},
length => new CustomStringType(length));
base.Configure(configuration);
}

protected override void DropSchema()
{
base.DropSchema();
TypeFactory.ClearCustomRegistrations();
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.Not.EqualTo(_testDefaultStringType));
}

[Test]
public void DefaultType()
{
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.EqualTo(_testDefaultStringType));
}

[Test]
public void PropertyType()
{
var propertyType25 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
.GetPropertyType(nameof(ChangeDefaultTypeClass.StringTypeLengthInType25));
Assert.That(
propertyType25,
Is.EqualTo(_testDefaultStringType));
Assert.That(propertyType25.SqlTypes(Sfi)[0].Length, Is.EqualTo(25));

var propertyType20 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
.GetPropertyType(nameof(ChangeDefaultTypeClass.StringTypeExplicitLength20));

Assert.That(
propertyType20,
Is.EqualTo(_testDefaultStringType));
Assert.That(propertyType20.SqlTypes(Sfi)[0].Length, Is.EqualTo(20));
}

[Test]
public void GuessType()
{
Assert.That(NHibernateUtil.GuessType(_replacedType), Is.EqualTo(_testDefaultStringType));
}

[Test]
public void ParameterType()
{
var namedParametersField = typeof(AbstractQueryImpl)
.GetField("namedParameters", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.That(namedParametersField, Is.Not.Null, "Missing internal field");

using (var s = OpenSession())
{
// Query where the parameter type cannot be deducted from compared entity property
var q = s.CreateQuery($"from {nameof(ChangeDefaultTypeClass)} where :str1 = :str2 or :str1 = :str3")
.SetParameter("str1", "aaa")
.SetString("str2", "bbb")
.SetAnsiString("str3", "bbb");

var namedParameters = namedParametersField.GetValue(q) as Dictionary<string, TypedValue>;
Assert.That(namedParameters, Is.Not.Null, "Unable to retrieve parameters internal field");
Assert.That(namedParameters["str1"].Type, Is.EqualTo(_testDefaultStringType));
Assert.That(namedParameters["str2"].Type, Is.EqualTo(NHibernateUtil.String));
Assert.That(namedParameters["str3"].Type, Is.EqualTo(NHibernateUtil.AnsiString));
}
}
}
}
114 changes: 114 additions & 0 deletions src/NHibernate.Test/TypesTest/ChangeDefaultTypeWithPrecisionFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using NHibernate.Cfg;
using NHibernate.Engine;
using NHibernate.Impl;
using NHibernate.SqlTypes;
using NHibernate.Type;
using NUnit.Framework;

namespace NHibernate.Test.TypesTest
{
/// <summary>
/// TestFixtures for changing a default .Net type.
/// </summary>
[TestFixture]
public class ChangeDefaultTypeWithPrecisionFixture : TypeFixtureBase
{
public class CustomCurrencyType : DecimalType
{
public CustomCurrencyType() : base(SqlTypeFactory.Currency)
{
}

public CustomCurrencyType(byte precision, byte scale) : base(new SqlType(DbType.Currency, precision, scale))
{
}

public override string Name => "CustomCurrencyType";
}

protected override string TypeName => "ChangeDefaultType";

private IType _originalDefaultType;
private IType _testDefaultType;
private static System.Type _replacedType = typeof(decimal);

protected override void Configure(Configuration configuration)
{
_originalDefaultType = TypeFactory.GetDefaultTypeFor(_replacedType);
_testDefaultType = new CustomCurrencyType();
Assert.That(_originalDefaultType, Is.Not.Null);
Assert.That(_originalDefaultType, Is.Not.EqualTo(_testDefaultType));

TypeFactory.RegisterType(
_replacedType,
_testDefaultType,
new[] {"currency"},
(precision, scale) => new CustomCurrencyType(precision, scale));
base.Configure(configuration);
}

protected override void DropSchema()
{
base.DropSchema();
TypeFactory.ClearCustomRegistrations();
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.Not.EqualTo(_testDefaultType));
}

[Test]
public void DefaultType()
{
Assert.That(TypeFactory.GetDefaultTypeFor(_replacedType), Is.EqualTo(_testDefaultType));
}

[Test]
public void PropertyType()
{
var propertyType1 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
.GetPropertyType(nameof(ChangeDefaultTypeClass.CurrencyTypeExplicitPrecision6And3));
Assert.That(
propertyType1,
Is.EqualTo(_testDefaultType));
Assert.That(propertyType1.SqlTypes(Sfi)[0].Precision, Is.EqualTo(6));
Assert.That(propertyType1.SqlTypes(Sfi)[0].Scale, Is.EqualTo(3));

var propertyType2 = Sfi.GetClassMetadata(typeof(ChangeDefaultTypeClass))
.GetPropertyType(nameof(ChangeDefaultTypeClass.CurrencyTypePrecisionInType5And2));

Assert.That(
propertyType2,
Is.EqualTo(_testDefaultType));
Assert.That(propertyType2.SqlTypes(Sfi)[0].Precision, Is.EqualTo(5));
Assert.That(propertyType2.SqlTypes(Sfi)[0].Scale, Is.EqualTo(2));
}

[Test]
public void GuessType()
{
Assert.That(NHibernateUtil.GuessType(_replacedType), Is.EqualTo(_testDefaultType));
}

[Test]
public void ParameterType()
{
var namedParametersField = typeof(AbstractQueryImpl)
.GetField("namedParameters", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.That(namedParametersField, Is.Not.Null, "Missing internal field");

using (var s = OpenSession())
{
// Query where the parameter type cannot be deducted from compared entity property
var q = s.CreateQuery($"from {nameof(ChangeDefaultTypeClass)} where :str1 = :str2")
.SetParameter("str1", 1.22m)
.SetDecimal("str2", 1m);

var namedParameters = namedParametersField.GetValue(q) as Dictionary<string, TypedValue>;
Assert.That(namedParameters, Is.Not.Null, "Unable to retrieve parameters internal field");
Assert.That(namedParameters["str1"].Type, Is.EqualTo(_testDefaultType));
Assert.That(namedParameters["str2"].Type, Is.EqualTo(NHibernateUtil.Decimal));
}
}
}
}
Loading