Skip to content
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

NH-4088 - Dialect.GetCastTypeName is buggy #709

Merged
merged 3 commits into from
Oct 9, 2017
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
61 changes: 61 additions & 0 deletions src/NHibernate.Test/Async/Criteria/ProjectionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
//------------------------------------------------------------------------------


using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using NHibernate.Criterion;
using NHibernate.Dialect;
using NHibernate.SqlTypes;
using NHibernate.Type;
using NUnit.Framework;

namespace NHibernate.Test.Criteria
Expand Down Expand Up @@ -100,6 +104,63 @@ public async Task UsingSqlFunctions_Concat_WithCastAsync()
}
}

[Test]
public async Task CastWithLengthAsync()
{
if (Regex.IsMatch(Dialect.GetCastTypeName(SqlTypeFactory.GetString(3)), @"^[^(]*$"))
{
Assert.Ignore($"Dialect {Dialect} does not seem to handle string length in cast");
}

using (var s = OpenSession())
{
try
{
var shortName = await (s
.CreateCriteria<Student>()
.SetProjection(
Projections.Cast(
TypeFactory.GetStringType(3),
Projections.Property("Name")))
.UniqueResultAsync<string>());
Assert.That(shortName, Is.EqualTo("aye"));
}
catch (Exception e)
{
if (e.InnerException == null || !e.InnerException.Message.Contains("truncation"))
throw;
}
}
}

[Test]
public async Task CastWithPrecisionScaleAsync()
{
if (TestDialect.HasBrokenDecimalType)
Assert.Ignore("Dialect does not correctly handle decimal.");

using (var s = OpenSession())
{
var value = await (s
.CreateCriteria<Student>()
.SetProjection(
Projections.Cast(
TypeFactory.Basic("decimal(18,9)"),
Projections.Constant(123456789.123456789m, TypeFactory.Basic("decimal(18,9)"))))
.UniqueResultAsync<decimal>());
Assert.That(value, Is.EqualTo(123456789.123456789m), "Same type cast");

value = await (s
.CreateCriteria<Student>()
.SetProjection(
Projections.Cast(
TypeFactory.Basic("decimal(18,7)"),
Projections.Constant(123456789.987654321m, TypeFactory.Basic("decimal(18,9)"))))
.UniqueResultAsync<decimal>());
Assert.That(value, Is.EqualTo(123456789.9876543m), "Reduced scale cast");
}
}

[Test]
public async Task CanUseParametersWithProjectionsAsync()
{
Expand Down
3 changes: 1 addition & 2 deletions src/NHibernate.Test/Async/DialectTest/DialectFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Engine;
Expand Down Expand Up @@ -79,4 +78,4 @@ public async Task CurrentTimestampSelectionAsync()
}
}
}
}
}
130 changes: 66 additions & 64 deletions src/NHibernate.Test/Async/DriverTest/FirebirdClientDriverFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,73 +26,74 @@ public class FirebirdClientDriverFixtureAsync
private string _connectionString;
private FirebirdClientDriver _driver;

[OneTimeSetUp]
public void OneTimeSetup()
{
var cfg = TestConfigurationHelper.GetDefaultConfiguration();

var dlct = cfg.GetProperty("dialect");
if (!dlct.Contains("Firebird"))
Assert.Ignore("Applies only to Firebird");

_driver = new FirebirdClientDriver();
_driver.Configure(cfg.Properties);
_connectionString = cfg.GetProperty("connection.connection_string");
}

[Test]
public async Task ConnectionPooling_OpenThenCloseThenOpenAnotherOne_OnlyOneConnectionIsPooledAsync()
{
MakeDriver();

_driver.ClearPool(_connectionString);

var allreadyEstablished = await (GetEstablishedConnectionsAsync());

var connection1 = MakeConnection();
var connection2 = MakeConnection();

//open first connection
await (connection1.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After first open"));
using (var connection1 = MakeConnection())
using (var connection2 = MakeConnection())
{
//open first connection
await (connection1.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After first open"));

//return it to the pool
connection1.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After first close"));
//return it to the pool
connection1.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After first close"));

//open the second connection
await (connection2.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After second open"));
//open the second connection
await (connection2.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After second open"));

//return it to the pool
connection2.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After second close"));
//return it to the pool
connection2.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After second close"));
}
}

[Test]
public async Task ConnectionPooling_OpenThenCloseTwoAtTheSameTime_TowConnectionsArePooledAsync()
{
MakeDriver();

_driver.ClearPool(_connectionString);

var allreadyEstablished = await (GetEstablishedConnectionsAsync());

var connection1 = MakeConnection();
var connection2 = MakeConnection();

//open first connection
await (connection1.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After first open"));

//open second one
await (connection2.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 2, "After second open"));

//return connection1 to the pool
connection1.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 2, "After first close"));
using (var connection1 = MakeConnection())
using (var connection2 = MakeConnection())
{
//open first connection
await (connection1.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 1, "After first open"));

//return connection2 to the pool
connection2.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 2, "After second close"));
}
//open second one
await (connection2.OpenAsync());
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 2, "After second open"));

private void MakeDriver()
{
var cfg = TestConfigurationHelper.GetDefaultConfiguration();
var dlct = cfg.GetProperty("dialect");
if (!dlct.Contains("Firebird"))
Assert.Ignore("Applies only to Firebird");
//return connection1 to the pool
connection1.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 2, "After first close"));

_driver = new FirebirdClientDriver();
_connectionString = cfg.GetProperty("connection.connection_string");
//return connection2 to the pool
connection2.Close();
await (VerifyCountOfEstablishedConnectionsIsAsync(allreadyEstablished + 2, "After second close"));
}
}

private DbConnection MakeConnection()
Expand Down Expand Up @@ -125,38 +126,38 @@ private DbConnection MakeConnection()
private DbCommand BuildSelectCaseCommand(SqlType paramType)
{
var sqlString = new SqlStringBuilder()
.Add("select (case when col = ")
.AddParameter()
.Add(" then ")
.AddParameter()
.Add(" else ")
.AddParameter()
.Add(" end) from table")
.ToSqlString();
.Add("select (case when col = ")
.AddParameter()
.Add(" then ")
.AddParameter()
.Add(" else ")
.AddParameter()
.Add(" end) from table")
.ToSqlString();

return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType, paramType, paramType });
}

private DbCommand BuildSelectConcatCommand(SqlType paramType)
{
var sqlString = new SqlStringBuilder()
.Add("select col || ")
.AddParameter()
.Add(" || ")
.Add("col ")
.Add("from table")
.ToSqlString();
.Add("select col || ")
.AddParameter()
.Add(" || ")
.Add("col ")
.Add("from table")
.ToSqlString();

return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
}

private DbCommand BuildSelectAddCommand(SqlType paramType)
{
var sqlString = new SqlStringBuilder()
.Add("select col + ")
.AddParameter()
.Add(" from table")
.ToSqlString();
.Add("select col + ")
.AddParameter()
.Add(" from table")
.ToSqlString();

return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
}
Expand All @@ -172,6 +173,7 @@ private DbCommand BuildInsertWithParamsInSelectCommand(SqlType paramType)

return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
}

private DbCommand BuildInsertWithParamsInSelectCommandWithSelectInColumnName(SqlType paramType)
{
var sqlString = new SqlStringBuilder()
Expand All @@ -184,7 +186,7 @@ private DbCommand BuildInsertWithParamsInSelectCommandWithSelectInColumnName(Sql
return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
}

private DbCommand BuildInsertWithParamsInSelectCommandWithWhereInColumnName(SqlType paramType)
private DbCommand BuildInsertWithParamsInSelectCommandWithWhereInColumnName(SqlType paramType)
{
var sqlString = new SqlStringBuilder()
.Add("insert into table1 (col1_where_aaa) ")
Expand Down
61 changes: 61 additions & 0 deletions src/NHibernate.Test/Criteria/ProjectionsTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using NHibernate.Criterion;
using NHibernate.Dialect;
using NHibernate.SqlTypes;
using NHibernate.Type;
using NUnit.Framework;

namespace NHibernate.Test.Criteria
Expand Down Expand Up @@ -89,6 +93,63 @@ public void UsingSqlFunctions_Concat_WithCast()
}
}

[Test]
public void CastWithLength()
{
if (Regex.IsMatch(Dialect.GetCastTypeName(SqlTypeFactory.GetString(3)), @"^[^(]*$"))
{
Assert.Ignore($"Dialect {Dialect} does not seem to handle string length in cast");
}

using (var s = OpenSession())
{
try
{
var shortName = s
.CreateCriteria<Student>()
.SetProjection(
Projections.Cast(
TypeFactory.GetStringType(3),
Projections.Property("Name")))
.UniqueResult<string>();
Assert.That(shortName, Is.EqualTo("aye"));
}
catch (Exception e)
{
if (e.InnerException == null || !e.InnerException.Message.Contains("truncation"))
throw;
}
}
}

[Test]
public void CastWithPrecisionScale()
{
if (TestDialect.HasBrokenDecimalType)
Assert.Ignore("Dialect does not correctly handle decimal.");

using (var s = OpenSession())
{
var value = s
.CreateCriteria<Student>()
.SetProjection(
Projections.Cast(
TypeFactory.Basic("decimal(18,9)"),
Projections.Constant(123456789.123456789m, TypeFactory.Basic("decimal(18,9)"))))
.UniqueResult<decimal>();
Assert.That(value, Is.EqualTo(123456789.123456789m), "Same type cast");

value = s
.CreateCriteria<Student>()
.SetProjection(
Projections.Cast(
TypeFactory.Basic("decimal(18,7)"),
Projections.Constant(123456789.987654321m, TypeFactory.Basic("decimal(18,9)"))))
.UniqueResult<decimal>();
Assert.That(value, Is.EqualTo(123456789.9876543m), "Reduced scale cast");
}
}

[Test]
public void CanUseParametersWithProjections()
{
Expand Down
Loading