Skip to content

Commit

Permalink
nhibernateGH-3530: Separate the types into different tables to avoid …
Browse files Browse the repository at this point in the history
…failure on default values.
  • Loading branch information
David Ellingsworth authored and David Ellingsworth committed May 15, 2024
1 parent 6bb6539 commit 6f7c2e9
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 89 deletions.
18 changes: 13 additions & 5 deletions src/NHibernate.Test/NHSpecificTest/GH3530/Entities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,23 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate.SqlCommand;

namespace NHibernate.Test.NHSpecificTest.GH3530
{
public class LocaleEntity
public abstract class Entity
{
public virtual Guid Id { get; set; }
public virtual int? IntegerValue { get; set; }
public virtual DateTime? DateTimeValue { get; set; }
public virtual double? DoubleValue { get; set; }
public virtual decimal? DecimalValue { get; set; }
}

public abstract class Entity<T>:Entity where T : struct
{
public virtual T Value { get; set; }
}

public class IntegerEntity : Entity<int> { }
public class DateTimeEntity : Entity<DateTime> { }

public class DoubleEntity : Entity<double> { }
public class DecimalEntity : Entity<decimal> { }
}
112 changes: 33 additions & 79 deletions src/NHibernate.Test/NHSpecificTest/GH3530/Fixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,28 @@ protected override void OnTearDown()
}

protected override void CreateSchema()
{
CreateTable("Integer");
CreateTable("DateTime");
CreateTable("Double");
CreateTable("Decimal");
}

private void CreateTable(string name)
{
var sb = new StringBuilder();
var guidType = Dialect.GetTypeName(SqlTypeFactory.Guid);
var stringType = Dialect.GetTypeName(SqlTypeFactory.GetAnsiString(255));

var catalog = GetQuotedDefaultCatalog();
var schema = GetQuotedDefaultSchema();
var table = GetQualifiedName(catalog, schema, "LocaleEntity");
var table = GetQualifiedName(catalog, schema, $"{name}Entity");

sb.Append($"{Dialect.CreateTableString} {table} (");

// Generate columns
sb.Append($"Id {guidType}, ");
sb.Append($"IntegerValue {stringType}, ");
sb.Append($"DateTimeValue {stringType}, ");
sb.Append($"DoubleValue {stringType}, ");
sb.Append($"DecimalValue {stringType}");
sb.Append($"Value {stringType}, ");

// Add the primary key contraint for the identity column
sb.Append($", {Dialect.PrimaryKeyString} ( Id )");
Expand Down Expand Up @@ -81,7 +86,7 @@ private string GetQuotedDefaultCatalog()
var t = cfg.GetType();
var getQuotedDefaultCatalog = t.GetMethod("GetQuotedDefaultCatalog", BindingFlags.Instance | BindingFlags.NonPublic);

return (string)getQuotedDefaultCatalog.Invoke(cfg, [Dialect]);
return (string) getQuotedDefaultCatalog.Invoke(cfg, [Dialect]);
}

private string GetQuotedDefaultSchema()
Expand All @@ -97,19 +102,19 @@ private string GetQualifiedName(string catalog, string schema, string name)
return Dialect.Qualify(catalog, schema, name);
}

[Test, TestCaseSource(nameof(GetTestCases))]
public void TestDateTime(CultureInfo from, CultureInfo to)
private void PerformTest<T, U>(CultureInfo from, CultureInfo to, T expectedValue, Action<T, T> assert)
where T : struct
where U : Entity<T>, new()
{
DateTime leapDay = new DateTime(2024, 2, 29, new GregorianCalendar(GregorianCalendarTypes.USEnglish));
object id;

CurrentCulture = from;
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = new LocaleEntity()
var entity = new U()
{
DateTimeValue = leapDay
Value = expectedValue
};

id = session.Save(entity);
Expand All @@ -120,96 +125,45 @@ public void TestDateTime(CultureInfo from, CultureInfo to)
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = session.Get<LocaleEntity>(id);
var entity = session.Get<U>(id);

Assert.AreEqual(leapDay, entity.DateTimeValue);
assert(expectedValue, entity.Value);
}
}

[Test, TestCaseSource(nameof(GetTestCases))]
public void TestDecimal(CultureInfo from, CultureInfo to)
public void TestDateTime(CultureInfo from, CultureInfo to)
{
decimal decimalValue = 12.3m;
object id;

CurrentCulture = from;
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = new LocaleEntity()
{
DecimalValue = decimalValue
};
DateTime leapDay = new DateTime(2024, 2, 29, new GregorianCalendar(GregorianCalendarTypes.USEnglish));

id = session.Save(entity);
tx.Commit();
}
PerformTest<DateTime, DateTimeEntity>(from, to, leapDay, (expected, actual) => Assert.AreEqual(expected, actual));
}

CurrentCulture = to;
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = session.Get<LocaleEntity>(id);
[Test, TestCaseSource(nameof(GetTestCases))]
public void TestDecimal(CultureInfo from, CultureInfo to)
{
decimal decimalValue = 12.3m;

Assert.AreEqual(decimalValue, entity.DecimalValue);
}
PerformTest<decimal, DecimalEntity>(from, to, decimalValue, (expected, actual) => Assert.AreEqual(expected, actual));
}

[Test, TestCaseSource(nameof(GetTestCases))]
public void TestDouble(CultureInfo from, CultureInfo to)
{
double doubleValue = 12.3d;
object id;

CurrentCulture = from;
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = new LocaleEntity()
{
DoubleValue = doubleValue
};

id = session.Save(entity);
tx.Commit();
}

CurrentCulture = to;
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = session.Get<LocaleEntity>(id);

Assert.True(Math.Abs(doubleValue - entity.DoubleValue) < double.Epsilon, $"Expected: {doubleValue}\nBut was: {entity.DoubleValue}\n");
}
PerformTest<double, DoubleEntity>(from, to, doubleValue,
(expected, actual) => Assert.True(Math.Abs(expected - actual) < double.Epsilon, $"Expected: {expected}\nBut was: {actual}\n")
);
}

[Test, TestCaseSource(nameof(GetTestCases))]

public void TestInteger(CultureInfo from, CultureInfo to)
{
int integerValue = 123;
object id;

CurrentCulture = from;
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = new LocaleEntity()
{
IntegerValue = integerValue
};

id = session.Save(entity);
tx.Commit();
}

CurrentCulture = to;
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var entity = session.Get<LocaleEntity>(id);

Assert.AreEqual(integerValue, entity.IntegerValue);
}
PerformTest<int, IntegerEntity>(from, to, integerValue, (expected, actual) => Assert.AreEqual(expected, actual));
}

private CultureInfo CurrentCulture
Expand Down
19 changes: 14 additions & 5 deletions src/NHibernate.Test/NHSpecificTest/GH3530/Mappings.hbm.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test"
namespace="NHibernate.Test.NHSpecificTest.GH3530">
<class name="LocaleEntity">
<class name="IntegerEntity">
<id name="Id" generator="guid.comb" />
<property name="IntegerValue" column="IntegerValue"/>
<property name="DateTimeValue" column="DateTimeValue"/>
<property name="DoubleValue" column="DoubleValue"/>
<property name="DecimalValue" column="DecimalValue"/>
<property name="Value" column="Value"/>
</class>
<class name="DateTimeEntity">
<id name="Id" generator="guid.comb" />
<property name="Value" column="Value"/>
</class>
<class name="DoubleEntity">
<id name="Id" generator="guid.comb" />
<property name="Value" column="Value"/>
</class>
<class name="DecimalEntity">
<id name="Id" generator="guid.comb" />
<property name="Value" column="Value"/>
</class>
</hibernate-mapping>

0 comments on commit 6f7c2e9

Please sign in to comment.