Skip to content

Commit 1a5e896

Browse files
NH-3919 - Use DateTime2 for dialects supporting it.
* NHibernate date time types (datetime, timestamp, localdatetime, utcdatetime, dbtimestamp, timestamputc) use db type datetime2 if dialect supports it. * NHibernate type datetime2 is obsolete.
1 parent 97052bb commit 1a5e896

33 files changed

+693
-77
lines changed

src/NHibernate.Test/Async/TypesTest/DateTime2TypeFixture.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace NHibernate.Test.TypesTest
2020
/// TestFixtures for the <see cref="DateTimeType"/>.
2121
/// </summary>
2222
[TestFixture]
23+
[Obsolete]
2324
public class DateTime2TypeFixtureAsync
2425
{
2526
[Test]
@@ -39,4 +40,4 @@ public async Task SeedAsync()
3940
Assert.IsTrue(await (type.SeedAsync(null, CancellationToken.None)) is DateTime, "seed should be DateTime");
4041
}
4142
}
42-
}
43+
}

src/NHibernate.Test/Async/TypesTest/DateTimeTypeFixture.cs

Lines changed: 191 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,18 @@
99

1010

1111
using System;
12+
using System.Collections.Generic;
13+
using System.Data;
14+
using System.Data.Common;
15+
using System.Linq;
16+
using NHibernate.Cfg;
17+
using NHibernate.Driver;
18+
using NHibernate.Engine;
19+
using NHibernate.SqlCommand;
20+
using NHibernate.SqlTypes;
21+
using NHibernate.Tool.hbm2ddl;
1222
using NHibernate.Type;
23+
using NHibernate.Util;
1324
using NUnit.Framework;
1425

1526
namespace NHibernate.Test.TypesTest
@@ -25,20 +36,193 @@ public class DateTimeTypeFixtureAsync
2536
[Test]
2637
public async Task NextAsync()
2738
{
28-
DateTimeType type = (DateTimeType) NHibernateUtil.DateTime;
39+
var type = NHibernateUtil.DateTime;
2940
object current = DateTime.Parse("2004-01-01");
3041
object next = await (type.NextAsync(current, null, CancellationToken.None));
3142

32-
Assert.IsTrue(next is DateTime, "Next should be DateTime");
33-
Assert.IsTrue((DateTime) next > (DateTime) current,
34-
"next should be greater than current (could be equal depending on how quickly this occurs)");
43+
Assert.That(next, Is.TypeOf<DateTime>(), "next should be DateTime");
44+
Assert.That(next, Is.GreaterThan(current), "next should be greater than current");
3545
}
3646

3747
[Test]
3848
public async Task SeedAsync()
3949
{
40-
DateTimeType type = (DateTimeType) NHibernateUtil.DateTime;
41-
Assert.IsTrue(await (type.SeedAsync(null, CancellationToken.None)) is DateTime, "seed should be DateTime");
50+
var type = NHibernateUtil.DateTime;
51+
Assert.That(await (type.SeedAsync(null, CancellationToken.None)), Is.TypeOf<DateTime>(), "seed should be DateTime");
4252
}
4353
}
44-
}
54+
55+
[TestFixture]
56+
public class DateTimeSqlTypeFixtureAsync : TypeFixtureBase
57+
{
58+
protected override string TypeName => "DateTime";
59+
private const int _dateId = 1;
60+
61+
protected override void Configure(Configuration configuration)
62+
{
63+
base.Configure(configuration);
64+
65+
var driverClass = ReflectHelper.ClassForName(configuration.GetProperty(Cfg.Environment.ConnectionDriver));
66+
ClientDriverWithParamsStats.DriverClass = driverClass;
67+
68+
configuration.SetProperty(
69+
Cfg.Environment.ConnectionDriver,
70+
typeof(ClientDriverWithParamsStats).AssemblyQualifiedName);
71+
}
72+
73+
protected override void OnSetUp()
74+
{
75+
base.OnSetUp();
76+
77+
using (var s = OpenSession())
78+
using (var t = s.BeginTransaction())
79+
{
80+
var d = new DateTimeClass
81+
{
82+
Id = _dateId,
83+
LocalDateTimeValue = DateTime.Now.AddDays(-1),
84+
UtcDateTimeValue = DateTime.UtcNow.AddDays(-1),
85+
NormalDateTimeValue = DateTime.Now.AddDays(-1)
86+
};
87+
s.Save(d);
88+
t.Commit();
89+
}
90+
}
91+
92+
protected override void OnTearDown()
93+
{
94+
base.OnTearDown();
95+
96+
using (var s = OpenSession())
97+
using (var t = s.BeginTransaction())
98+
{
99+
s.CreateQuery("delete from DateTimeClass").ExecuteUpdate();
100+
t.Commit();
101+
}
102+
}
103+
104+
protected override void DropSchema()
105+
{
106+
(Sfi.ConnectionProvider.Driver as ClientDriverWithParamsStats)?.CleanUp();
107+
base.DropSchema();
108+
}
109+
110+
[Test]
111+
public Task DbHasExpectedTypeAsync()
112+
{
113+
try
114+
{
115+
var validator = new SchemaValidator(cfg);
116+
return validator.ValidateAsync();
117+
}
118+
catch (Exception ex)
119+
{
120+
return Task.FromException<object>(ex);
121+
}
122+
}
123+
124+
[Test]
125+
public async Task SaveUseExpectedSqlTypeAsync()
126+
{
127+
var driver = (ClientDriverWithParamsStats) Sfi.ConnectionProvider.Driver;
128+
129+
using (var s = OpenSession())
130+
using (var t = s.BeginTransaction())
131+
{
132+
var d = new DateTimeClass
133+
{
134+
Id = 2,
135+
LocalDateTimeValue = DateTime.Now,
136+
UtcDateTimeValue = DateTime.UtcNow,
137+
NormalDateTimeValue = DateTime.Now
138+
};
139+
driver.ClearStats();
140+
await (s.SaveAsync(d));
141+
await (t.CommitAsync());
142+
}
143+
144+
AssertSqlType(driver, 3);
145+
}
146+
147+
[Test]
148+
public async Task UpdateUseExpectedSqlTypeAsync()
149+
{
150+
var driver = (ClientDriverWithParamsStats) Sfi.ConnectionProvider.Driver;
151+
152+
using (var s = OpenSession())
153+
using (var t = s.BeginTransaction())
154+
{
155+
var d = await (s.GetAsync<DateTimeClass>(_dateId));
156+
d.LocalDateTimeValue = DateTime.Now;
157+
d.UtcDateTimeValue = DateTime.UtcNow;
158+
d.NormalDateTimeValue = DateTime.Now;
159+
driver.ClearStats();
160+
await (t.CommitAsync());
161+
}
162+
163+
AssertSqlType(driver, 3);
164+
}
165+
166+
[Test]
167+
public async Task QueryUseExpectedSqlTypeAsync()
168+
{
169+
if (!TestDialect.SupportsNonDataBoundCondition)
170+
Assert.Ignore("Dialect does not support the test query");
171+
172+
var driver = (ClientDriverWithParamsStats) Sfi.ConnectionProvider.Driver;
173+
174+
using (var s = OpenSession())
175+
using (var t = s.BeginTransaction())
176+
{
177+
var q = s
178+
.CreateQuery(
179+
"from DateTimeClass d where d.LocalDateTimeValue = :local and " +
180+
"d.UtcDateTimeValue = :utc and d.NormalDateTimeValue = :normal and " +
181+
":other1 = :other2")
182+
.SetDateTime("local", DateTime.Now)
183+
.SetDateTime("utc", DateTime.UtcNow)
184+
.SetDateTime("normal", DateTime.Now)
185+
.SetDateTime("other1", DateTime.Now)
186+
.SetDateTime("other2", DateTime.Now);
187+
driver.ClearStats();
188+
await (q.ListAsync<DateTimeClass>());
189+
await (t.CommitAsync());
190+
}
191+
192+
AssertSqlType(driver, 5);
193+
}
194+
195+
private void AssertSqlType(ClientDriverWithParamsStats driver, int expectedCount)
196+
{
197+
if (NHibernateUtil.DateTime.SqlTypes(Sfi).Any(t => Equals(t, SqlTypeFactory.DateTime2)))
198+
{
199+
Assert.That(
200+
driver.GetCount(SqlTypeFactory.DateTime),
201+
Is.EqualTo(0),
202+
"Found unexpected SqlTypeFactory.DateTime usages.");
203+
Assert.That(
204+
driver.GetCount(SqlTypeFactory.DateTime2),
205+
Is.GreaterThan(0),
206+
"Missing SqlTypeFactory.DateTime2 usages.");
207+
Assert.That(driver.GetCount(DbType.DateTime), Is.EqualTo(0), "Found unexpected DbType.DateTime usages.");
208+
Assert.That(
209+
driver.GetCount(DbType.DateTime2),
210+
Is.EqualTo(expectedCount),
211+
"Unexpected DbType.DateTime2 usage count.");
212+
}
213+
else
214+
{
215+
Assert.That(
216+
driver.GetCount(SqlTypeFactory.DateTime2),
217+
Is.EqualTo(0),
218+
"Found unexpected SqlTypeFactory.DateTime2 usages.");
219+
Assert.That(
220+
driver.GetCount(SqlTypeFactory.DateTime),
221+
Is.GreaterThan(0),
222+
"Missing SqlTypeFactory.DateTime usages.");
223+
Assert.That(driver.GetCount(DbType.DateTime2), Is.EqualTo(0), "Found unexpected DbType.DateTime2 usages.");
224+
Assert.That(driver.GetCount(DbType.DateTime), Is.EqualTo(expectedCount), "Unexpected DbType.DateTime usage count.");
225+
}
226+
}
227+
}
228+
}

src/NHibernate.Test/DebugSessionFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ bool IMapping.HasNonIdentifierPropertyNamedId(string className)
179179
return ActualFactory.HasNonIdentifierPropertyNamedId(className);
180180
}
181181

182+
Dialect.Dialect IMapping.Dialect => ActualFactory.Dialect;
183+
182184
void IDisposable.Dispose()
183185
{
184186
ActualFactory.Dispose();
@@ -270,8 +272,6 @@ ISession ISessionFactory.GetCurrentSession()
270272

271273
ICollection<string> ISessionFactory.DefinedFilterNames => ActualFactory.DefinedFilterNames;
272274

273-
Dialect.Dialect ISessionFactoryImplementor.Dialect => ActualFactory.Dialect;
274-
275275
IInterceptor ISessionFactoryImplementor.Interceptor => ActualFactory.Interceptor;
276276

277277
QueryPlanCache ISessionFactoryImplementor.QueryPlanCache => ActualFactory.QueryPlanCache;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.Reflection;
2+
using NHibernate.Cfg;
3+
using NHibernate.Dialect;
4+
using NHibernate.Engine;
5+
using NHibernate.SqlTypes;
6+
using NHibernate.Type;
7+
using NUnit.Framework;
8+
9+
namespace NHibernate.Test.DialectTest
10+
{
11+
[TestFixture]
12+
public class MsSql2008DialectFixture
13+
{
14+
[Test]
15+
public void CheckSql2005DateTimeTypes()
16+
{
17+
var cfg = TestConfigurationHelper.GetDefaultConfiguration();
18+
cfg.SetProperty(Environment.Dialect, typeof(MsSql2005Dialect).FullName);
19+
var mapping = GetMapping(cfg);
20+
AssertSqlType(NHibernateUtil.DateTime, SqlTypeFactory.DateTime, mapping);
21+
AssertSqlType(NHibernateUtil.Timestamp, SqlTypeFactory.DateTime, mapping);
22+
AssertSqlType(NHibernateUtil.TimestampUtc, SqlTypeFactory.DateTime, mapping);
23+
AssertSqlType(NHibernateUtil.DbTimestamp, SqlTypeFactory.DateTime, mapping);
24+
AssertSqlType(NHibernateUtil.LocalDateTime, SqlTypeFactory.DateTime, mapping);
25+
AssertSqlType(NHibernateUtil.UtcDateTime, SqlTypeFactory.DateTime, mapping);
26+
#pragma warning disable 618 // DateTime2 is obsolete
27+
AssertSqlType(NHibernateUtil.DateTime2, SqlTypeFactory.DateTime2, mapping);
28+
#pragma warning restore 618
29+
}
30+
31+
[Test]
32+
public void CheckSql2008DateTimeTypes()
33+
{
34+
var cfg = TestConfigurationHelper.GetDefaultConfiguration();
35+
cfg.SetProperty(Environment.Dialect, typeof(MsSql2008Dialect).FullName);
36+
var mapping = GetMapping(cfg);
37+
AssertSqlType(NHibernateUtil.DateTime, SqlTypeFactory.DateTime2, mapping);
38+
AssertSqlType(NHibernateUtil.Timestamp, SqlTypeFactory.DateTime2, mapping);
39+
AssertSqlType(NHibernateUtil.TimestampUtc, SqlTypeFactory.DateTime2, mapping);
40+
AssertSqlType(NHibernateUtil.DbTimestamp, SqlTypeFactory.DateTime2, mapping);
41+
AssertSqlType(NHibernateUtil.LocalDateTime, SqlTypeFactory.DateTime2, mapping);
42+
AssertSqlType(NHibernateUtil.UtcDateTime, SqlTypeFactory.DateTime2, mapping);
43+
#pragma warning disable 618 // DateTime2 is obsolete
44+
AssertSqlType(NHibernateUtil.DateTime2, SqlTypeFactory.DateTime2, mapping);
45+
#pragma warning restore 618
46+
}
47+
48+
private static readonly FieldInfo _mappingField =
49+
typeof(Configuration).GetField("mapping", BindingFlags.Instance | BindingFlags.NonPublic);
50+
51+
private static IMapping GetMapping(Configuration cfg)
52+
{
53+
Assert.That(_mappingField, Is.Not.Null, "Unable to find field mapping");
54+
var mapping = _mappingField.GetValue(cfg) as IMapping;
55+
Assert.That(mapping, Is.Not.Null, "Unable to find mapping object");
56+
return mapping;
57+
}
58+
59+
private static void AssertSqlType(IType type, SqlType sqlType, IMapping mapping)
60+
{
61+
Assert.That(type.SqlTypes(mapping), Has.Length.EqualTo(1).And.Contain(sqlType));
62+
}
63+
}
64+
}

src/NHibernate.Test/NHSpecificTest/NH283/Fixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ public void ForeignKeyNames()
2121

2222

2323
string script = string.Join("\n",
24-
cfg.GenerateSchemaCreationScript(new MsSql2000Dialect()));
24+
cfg.GenerateSchemaCreationScript(new MsSql2008Dialect()));
2525

2626
Assert.IsTrue(script.IndexOf("add constraint AA") >= 0);
2727
Assert.IsTrue(script.IndexOf("add constraint BB") >= 0);
2828
Assert.IsTrue(script.IndexOf("add constraint CC") >= 0);
2929
}
3030
}
31-
}
31+
}
Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<Import Project="../../build-common/NHibernate.props" />
3-
43
<PropertyGroup>
54
<Description>The Unit Tests for NHibernate.</Description>
6-
75
<TargetFramework>net461</TargetFramework>
86
<NoWarn>$(NoWarn);3001;3002;3003;3005</NoWarn>
97
</PropertyGroup>
10-
118
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
129
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
1310
<TreatSpecificWarningsAsErrors />
1411
</PropertyGroup>
15-
1612
<ItemGroup>
1713
<None Remove="**\*.hbm.xml" />
1814
<None Remove="**\*.jpg" />
1915
<None Update="DbScripts\*.sql">
2016
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
2117
</None>
2218
</ItemGroup>
23-
2419
<ItemGroup>
2520
<EmbeddedResource Include="**\*.hbm.xml" Exclude="bin\**\*.*" />
2621
<EmbeddedResource Include="**\*.jpg" />
@@ -32,13 +27,11 @@
3227
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
3328
</EmbeddedResource>
3429
</ItemGroup>
35-
3630
<ItemGroup>
3731
<Content Include="..\NHibernate.DomainModel\ABC.hbm.xml" Link="ABC.hbm.xml">
3832
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
3933
</Content>
4034
</ItemGroup>
41-
4235
<ItemGroup>
4336
<PackageReference Include="Antlr3.Runtime" Version="3.5.1" />
4437
<PackageReference Include="Iesi.Collections" Version="4.0.2" />
@@ -51,20 +44,16 @@
5144
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
5245
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
5346
</ItemGroup>
54-
5547
<ItemGroup>
5648
<ProjectReference Include="..\NHibernate.DomainModel\NHibernate.DomainModel.csproj" />
5749
<ProjectReference Include="..\NHibernate\NHibernate.csproj" />
5850
</ItemGroup>
59-
6051
<ItemGroup>
6152
<Reference Include="System.Configuration" />
6253
<Reference Include="System.Data.OracleClient" />
6354
<Reference Include="System.Transactions" />
6455
</ItemGroup>
65-
6656
<ItemGroup>
6757
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
6858
</ItemGroup>
69-
70-
</Project>
59+
</Project>

0 commit comments

Comments
 (0)