Skip to content

Commit 59ff1df

Browse files
Test Unicode string. (#1511)
* Test Unicode string * Support Unicode in Firebird tests * Support Unicode in Oracle tests
1 parent 909fac2 commit 59ff1df

File tree

11 files changed

+124
-27
lines changed

11 files changed

+124
-27
lines changed

build-common/teamcity-hibernate.cfg.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@
2424
<property name="adonet.wrap_result_sets">false</property>
2525

2626
<property name="odbc.explicit_datetime_scale"></property>
27+
<property name="oracle.use_n_prefixed_types_for_unicode"></property>
28+
<property name="query.default_cast_length"></property>
2729
</session-factory>
2830
</hibernate-configuration>

default.build

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,26 @@
133133
<namespace prefix="hbm" uri="urn:nhibernate-configuration-2.2" />
134134
</namespaces>
135135
</xmlpoke>
136+
137+
<!-- Make sure the property exists - it's only set for some scenarios. -->
138+
<property name="nhibernate.oracle.use_n_prefixed_types_for_unicode" value="" unless="${property::exists('nhibernate.oracle.use_n_prefixed_types_for_unicode')}"/>
139+
<xmlpoke file="${app.config}"
140+
xpath="//*/hbm:property[@name='oracle.use_n_prefixed_types_for_unicode']"
141+
value="${nhibernate.oracle.use_n_prefixed_types_for_unicode}">
142+
<namespaces>
143+
<namespace prefix="hbm" uri="urn:nhibernate-configuration-2.2" />
144+
</namespaces>
145+
</xmlpoke>
146+
147+
<!-- Make sure the property exists - it's only set for some scenarios. -->
148+
<property name="nhibernate.query.default_cast_length" value="" unless="${property::exists('nhibernate.query.default_cast_length')}"/>
149+
<xmlpoke file="${app.config}"
150+
xpath="//*/hbm:property[@name='query.default_cast_length']"
151+
value="${nhibernate.query.default_cast_length}">
152+
<namespaces>
153+
<namespace prefix="hbm" uri="urn:nhibernate-configuration-2.2" />
154+
</namespaces>
155+
</xmlpoke>
136156
</target>
137157

138158
<target name="put-connection-settings-into-app-config">

lib/teamcity/firebird/firebird_installation.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ UserManager = Srp
2323
WireCrypt = Enabled
2424
11. Restart Firebird service.
2525

26-
For manual testing, take care of not creating it with inadequate acl on the file. This may happen
27-
if you use ISQL with a connection string causing it to create it in embedded mode, without actually
28-
using the server. Prefixing your path with "localhost:" should avoid that.
26+
For manual testing, take care of not creating the NHibernate database with inadequate acl on the file.
27+
This may happen if you use ISQL with a connection string causing it to create it in embedded mode,
28+
without actually using the server. Prefixing your path with "localhost:" should avoid that.
29+
Due to test constraints, make sure you create the database with a 16384 page size.
2930

3031
For tests performances, and since it is just an expandable test database, better disable forced writes.
3132
Since those tests drop/create schema constantly, they are quite heavy on writes and this single setting
@@ -35,4 +36,6 @@ b. From Firebird installation folder, run:
3536
gfix -w async nhibernate -user SYSDBA
3637
(Change "nhibernate" to your own alias or path as appropriate for your setup)
3738
c. Restart Firebird service.
38-
Note that the TestDatabaseSetup will drop and recreate the database when run, with forced writes disabled.
39+
Note that the TestDatabaseSetup will drop and recreate the database when run, with forced writes disabled
40+
and with a 16384 page size. So you may consider running the TestDatabaseSetup test instead for creating the
41+
NHibernate database.

lib/teamcity/oracle/oracle_installation.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ Installation steps for Oracle for NH TeamCity:
77

88
2. Run the installer ...
99
3. Choose any HTTP port for the listener if asked (it may automatically choose the default 8080 if available);
10-
4. Choose the ASCII character set. You will have to ensure nhibernate.oracle.use_n_prefixed_types_for_unicode
11-
parameter is set to true; Choosing instead the Unicode character set will cause some NHibernate tests to fail.
10+
4. Choose the ASCII character set. You will have to ensure oracle.use_n_prefixed_types_for_unicode
11+
parameter is set to true and that query.default_cast_length is set to 2000. Choosing instead the Unicode
12+
character set will cause some NHibernate tests to fail.
1213
5. Enter 'password' as the password for the SYS and SYSTEM accounts;
1314
6. The setup should install Oracle on the machine.
1415

src/NHibernate.Config.Templates/FireBird.cfg.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ for your own use before compile tests in VisualStudio.
2222
Database=nhibernate;
2323
User ID=SYSDBA;Password=masterkey;
2424
MaxPoolSize=200;
25+
charset=utf8;
2526
</property>
2627
<property name="show_sql">false</property>
2728
<property name="dialect">NHibernate.Dialect.FirebirdDialect</property>

src/NHibernate.Config.Templates/Oracle-Managed.cfg.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,12 @@ for your own use before compile tests in VisualStudio.
1414
<property name="show_sql">false</property>
1515
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
1616
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
17+
<!-- If your database setup use an ASCII charset, switch following property to true. -->
18+
<property name="oracle.use_n_prefixed_types_for_unicode">false</property>
19+
<!-- Depending on your database setup, the default cast length of 4000 may be too big.
20+
By example, if previous setting is true, NHibernate may try to use nvarchar2(4000),
21+
which will be rejected if its underlying charset is UTF16 and the database
22+
MAX_STRING_SIZE is not extended. In such case, reduce it to 2000. -->
23+
<property name="query.default_cast_length"></property>
1724
</session-factory>
1825
</hibernate-configuration>

src/NHibernate.Config.Templates/Oracle.cfg.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,12 @@ for your own use before compile tests in VisualStudio.
1414
<property name="show_sql">false</property>
1515
<property name="dialect">NHibernate.Dialect.OracleDialect</property>
1616
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
17+
<!-- If your database setup use an ASCII charset, switch following property to true. -->
18+
<property name="oracle.use_n_prefixed_types_for_unicode">false</property>
19+
<!-- Depending on your database setup, the default cast length of 4000 may be too big.
20+
By example, if previous setting is true, NHibernate may try to use nvarchar2(4000),
21+
which will be rejected if its underlying charset is UTF16 and the database
22+
MAX_STRING_SIZE is not extended. In such case, reduce it to 2000. -->
23+
<property name="query.default_cast_length"></property>
1724
</session-factory>
1825
</hibernate-configuration>

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

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
//------------------------------------------------------------------------------
99

1010

11-
using System;
11+
using System.Linq;
1212
using NUnit.Framework;
13+
using NHibernate.Linq;
1314

1415
namespace NHibernate.Test.TypesTest
1516
{
1617
using System.Threading.Tasks;
17-
/// <summary>
18-
/// Summary description for StringTypeFixture.
19-
/// </summary>
2018
[TestFixture]
2119
public class StringTypeFixtureAsync : TypeFixtureBase
2220
{
@@ -25,6 +23,14 @@ protected override string TypeName
2523
get { return "String"; }
2624
}
2725

26+
protected override void OnTearDown()
27+
{
28+
using (var s = OpenSession())
29+
{
30+
s.CreateQuery("delete from StringClass").ExecuteUpdate();
31+
}
32+
}
33+
2834
[Test]
2935
public async Task InsertNullValueAsync()
3036
{
@@ -38,12 +44,27 @@ public async Task InsertNullValueAsync()
3844

3945
using (ISession s = OpenSession())
4046
{
41-
StringClass b = (StringClass) await (s.CreateCriteria(
42-
typeof(StringClass)).UniqueResultAsync());
43-
Assert.IsNull(b.StringValue);
44-
await (s.DeleteAsync(b));
47+
StringClass b = (StringClass) await (s.CreateCriteria(typeof(StringClass)).UniqueResultAsync());
48+
Assert.That(b.StringValue, Is.Null);
49+
}
50+
}
51+
52+
[Test]
53+
public async Task InsertUnicodeValueAsync()
54+
{
55+
const string unicode = "길동 최고 新闻 地图 ます プル éèêëîïôöõàâäåãçùûü бджзй αβ ខគឃ ضذخ";
56+
using (var s = OpenSession())
57+
{
58+
var b = new StringClass { StringValue = unicode };
59+
await (s.SaveAsync(b));
4560
await (s.FlushAsync());
4661
}
62+
63+
using (var s = OpenSession())
64+
{
65+
var b = await (s.Query<StringClass>().SingleAsync());
66+
Assert.That(b.StringValue, Is.EqualTo(unicode));
67+
}
4768
}
4869
}
49-
}
70+
}
Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
using System;
1+
using System.Linq;
22
using NUnit.Framework;
33

44
namespace NHibernate.Test.TypesTest
55
{
6-
/// <summary>
7-
/// Summary description for StringTypeFixture.
8-
/// </summary>
96
[TestFixture]
107
public class StringTypeFixture : TypeFixtureBase
118
{
@@ -14,6 +11,14 @@ protected override string TypeName
1411
get { return "String"; }
1512
}
1613

14+
protected override void OnTearDown()
15+
{
16+
using (var s = OpenSession())
17+
{
18+
s.CreateQuery("delete from StringClass").ExecuteUpdate();
19+
}
20+
}
21+
1722
[Test]
1823
public void InsertNullValue()
1924
{
@@ -27,12 +32,27 @@ public void InsertNullValue()
2732

2833
using (ISession s = OpenSession())
2934
{
30-
StringClass b = (StringClass) s.CreateCriteria(
31-
typeof(StringClass)).UniqueResult();
32-
Assert.IsNull(b.StringValue);
33-
s.Delete(b);
35+
StringClass b = (StringClass) s.CreateCriteria(typeof(StringClass)).UniqueResult();
36+
Assert.That(b.StringValue, Is.Null);
37+
}
38+
}
39+
40+
[Test]
41+
public void InsertUnicodeValue()
42+
{
43+
const string unicode = "길동 최고 新闻 地图 ます プル éèêëîïôöõàâäåãçùûü бджзй αβ ខគឃ ضذخ";
44+
using (var s = OpenSession())
45+
{
46+
var b = new StringClass { StringValue = unicode };
47+
s.Save(b);
3448
s.Flush();
3549
}
50+
51+
using (var s = OpenSession())
52+
{
53+
var b = s.Query<StringClass>().Single();
54+
Assert.That(b.StringValue, Is.EqualTo(unicode));
55+
}
3656
}
3757
}
38-
}
58+
}

src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ private static void SetupFirebird(Cfg.Configuration cfg)
112112
{
113113
Console.WriteLine(e);
114114
}
115-
FbConnection.CreateDatabase(connStr, forcedWrites:false);
115+
// With UTF8 charset, string takes up to four times as many space, causing the
116+
// default page-size of 4096 to no more be enough for index key sizes. (Index key
117+
// size is limited to a quarter of the page size.)
118+
FbConnection.CreateDatabase(connStr, pageSize:16384, forcedWrites:false);
116119
}
117120

118121
private static void SetupSqlServerCe(Cfg.Configuration cfg)

teamcity.build

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,14 @@
7676
<target name="setup-teamcity-firebird32">
7777
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.FirebirdClientDriver" />
7878
<property name="nhibernate.dialect" value="NHibernate.Dialect.FirebirdDialect" />
79-
<property name="nhibernate.connection.connection_string" value="DataSource=localhost;Database=nhibernate;User ID=SYSDBA;Password=masterkey;MaxPoolSize=200;" />
79+
<property name="nhibernate.connection.connection_string" value="DataSource=localhost;Database=nhibernate;User ID=SYSDBA;Password=masterkey;MaxPoolSize=200;charset=utf8;" />
8080
</target>
8181

8282
<target name="setup-teamcity-firebird64">
8383
<property name="nunit-x64" value="true" />
8484
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.FirebirdClientDriver" />
8585
<property name="nhibernate.dialect" value="NHibernate.Dialect.FirebirdDialect" />
86-
<property name="nhibernate.connection.connection_string" value="DataSource=localhost;Database=nhibernate;User ID=SYSDBA;Password=masterkey;MaxPoolSize=200;" />
86+
<property name="nhibernate.connection.connection_string" value="DataSource=localhost;Database=nhibernate;User ID=SYSDBA;Password=masterkey;MaxPoolSize=200;charset=utf8;" />
8787
</target>
8888

8989
<target name="setup-teamcity-sqlite32">
@@ -127,6 +127,9 @@
127127
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Metadata Pooling=false;Self Tuning=false;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
128128
<!-- Teamcity Oracle test database is configured with a non-Unicode encoding -->
129129
<property name="nhibernate.oracle.use_n_prefixed_types_for_unicode" value="true" />
130+
<!-- The default value of 4000 is too big for nvarchar2 with default database settings.
131+
nvarchar2 may be used due to use_n_prefixed_types_for_unicode -->
132+
<property name="nhibernate.query.default_cast_length" value="2000" />
130133
<copy todir="${bin.dir}">
131134
<fileset basedir="${root.dir}/lib/teamcity/oracle/x86">
132135
<include name="*.dll"/>
@@ -143,6 +146,9 @@
143146
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Metadata Pooling=false;Self Tuning=false;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
144147
<!-- Teamcity Oracle test database is configured with a non-Unicode encoding -->
145148
<property name="nhibernate.oracle.use_n_prefixed_types_for_unicode" value="true" />
149+
<!-- The default value of 4000 is too big for nvarchar2 with default database settings.
150+
nvarchar2 may be used due to use_n_prefixed_types_for_unicode -->
151+
<property name="nhibernate.query.default_cast_length" value="2000" />
146152
<copy todir="${bin.dir}">
147153
<fileset basedir="${root.dir}/lib/teamcity/oracle/x64">
148154
<include name="*.dll"/>
@@ -158,6 +164,9 @@
158164
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Metadata Pooling=false;Self Tuning=false;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
159165
<!-- Teamcity Oracle test database is configured with a non-Unicode encoding -->
160166
<property name="nhibernate.oracle.use_n_prefixed_types_for_unicode" value="true" />
167+
<!-- The default value of 4000 is too big for nvarchar2 with default database settings.
168+
nvarchar2 may be used due to use_n_prefixed_types_for_unicode -->
169+
<property name="nhibernate.query.default_cast_length" value="2000" />
161170
</target>
162171

163172
<target name="setup-teamcity-oracle-managed64">
@@ -167,6 +176,9 @@
167176
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Metadata Pooling=false;Self Tuning=false;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
168177
<!-- Teamcity Oracle test database is configured with a non-Unicode encoding -->
169178
<property name="nhibernate.oracle.use_n_prefixed_types_for_unicode" value="true" />
179+
<!-- The default value of 4000 is too big for nvarchar2 with default database settings.
180+
nvarchar2 may be used due to use_n_prefixed_types_for_unicode -->
181+
<property name="nhibernate.query.default_cast_length" value="2000" />
170182
</target>
171183

172184
<target name="setup-teamcity-mysql">

0 commit comments

Comments
 (0)