Skip to content

Commit ad4c2ef

Browse files
fredericDelaportehazzik
authored andcommitted
NH-4026 - Upgrade Firebird driver and use server (#639)
1 parent 71d5e2e commit ad4c2ef

29 files changed

+152
-19192
lines changed

ShowBuildMenu.bat

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,12 @@ goto test-setup-generic
9191
set CONFIG_NAME=FireBird
9292
set PLATFORM=x86
9393
set LIB_FILES=lib\teamcity\firebird\*.dll
94-
set LIB_FILES2=lib\teamcity\firebird\x86\*
9594
goto test-setup-generic
9695

9796
:test-setup-firebirdx64
9897
set CONFIG_NAME=FireBird
9998
set PLATFORM=x64
10099
set LIB_FILES=lib\teamcity\firebird\*.dll
101-
set LIB_FILES2=lib\teamcity\firebird\x64\*
102100
goto test-setup-generic
103101

104102
:test-setup-sqlitex86
Binary file not shown.

lib/teamcity/firebird/NHibernate.Test.last-results.xml

Lines changed: 0 additions & 19131 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
Installation steps for Firebird for NH TeamCity:
3+
4+
1. Download Firebird (Firebird-3.0.2.32703_0_x64): https://www.firebirdsql.org/en/server-packages/;
5+
2. Run the installer AS ADMINISTRATOR... Use the default firebird password when prompted: masterkey.
6+
3. Leave other settings with their defaults.
7+
4. The setup should install Firebird on the machine;
8+
5. Go into Firebird folder (c:\program files\firebird\) and create a folder named Data;
9+
6. Go in Firebird installation directory and open databases.conf.
10+
7. Add in "Live Databases" section:
11+
nhibernate = D:\nhibernate.fdb
12+
Firebird is particularly sensitive to disk performances, and D: is supposed to be local to the
13+
Teamcity host, thus this choice. Content of this drive may be lost. But the TestDatabaseSetup will
14+
instruct Firebird to recreate the database. It is put on the root because Firebird will not create
15+
the folder, and the TestDatabaseSetup should not try to do that because it is used by other hosts
16+
which may not want to do anything on D:.
17+
8. Open firebird.conf.
18+
9. Ensure AuthClient, AuthServer and UserManager are set to Srp only:
19+
AuthServer = Srp
20+
AuthClient = Srp
21+
UserManager = Srp
22+
10. Ensure WireCrypt is set to Enabled.
23+
WireCrypt = Enabled
24+
11. Restart Firebird service.
25+
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.
29+
30+
For tests performances, and since it is just an expandable test database, better disable forced writes.
31+
Since those tests drop/create schema constantly, they are quite heavy on writes and this single setting
32+
can have a six fold impact on their duration. For changing it, do:
33+
a. Stop Firebird service.
34+
b. From Firebird installation folder, run:
35+
gfix -w async nhibernate -user SYSDBA
36+
(Change "nhibernate" to your own alias or path as appropriate for your setup)
37+
c. Restart Firebird service.
38+
Note that the TestDatabaseSetup will drop and recreate the database when run, with forced writes disabled.

lib/teamcity/firebird/x64/fbembed.dll

-5.25 MB
Binary file not shown.
-145 KB
Binary file not shown.

lib/teamcity/firebird/x64/ib_util.dll

-8 KB
Binary file not shown.

lib/teamcity/firebird/x64/icudt30.dll

-1.49 MB
Binary file not shown.

lib/teamcity/firebird/x64/icuin30.dll

-562 KB
Binary file not shown.

lib/teamcity/firebird/x64/icuuc30.dll

-914 KB
Binary file not shown.

lib/teamcity/firebird/x64/msvcp80.dll

-1.05 MB
Binary file not shown.

lib/teamcity/firebird/x64/msvcr80.dll

-804 KB
Binary file not shown.

lib/teamcity/firebird/x86/fbembed.dll

-3.58 MB
Binary file not shown.
-145 KB
Binary file not shown.

lib/teamcity/firebird/x86/ib_util.dll

-7.5 KB
Binary file not shown.

lib/teamcity/firebird/x86/icudt30.dll

-1.5 MB
Binary file not shown.

lib/teamcity/firebird/x86/icuin30.dll

-408 KB
Binary file not shown.

lib/teamcity/firebird/x86/icuuc30.dll

-660 KB
Binary file not shown.

lib/teamcity/firebird/x86/msvcp80.dll

-536 KB
Binary file not shown.

lib/teamcity/firebird/x86/msvcr80.dll

-612 KB
Binary file not shown.

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ for your own use before compile tests in VisualStudio.
1818
<session-factory name="NHibernate.Test">
1919
<property name="connection.driver_class">NHibernate.Driver.FirebirdClientDriver</property>
2020
<property name="connection.connection_string">
21-
Server=localhost;
22-
Database=C:\nhibernate.fdb;
23-
User=SYSDBA;Password=masterkey
21+
DataSource=localhost;
22+
Database=nhibernate;
23+
User ID=SYSDBA;Password=masterkey;
24+
MaxPoolSize=200;
2425
</property>
2526
<property name="show_sql">false</property>
2627
<property name="dialect">NHibernate.Dialect.FirebirdDialect</property>

src/NHibernate.Test/DriverTest/FirebirdClientDriverFixture.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Data;
1+
using System;
2+
using System.Data;
23
using System.Data.Common;
34
using NHibernate.Driver;
45
using NHibernate.SqlCommand;
@@ -17,48 +18,58 @@ public class FirebirdClientDriverFixture
1718
public void ConnectionPooling_OpenThenCloseThenOpenAnotherOne_OnlyOneConnectionIsPooled()
1819
{
1920
MakeDriver();
21+
22+
_driver.ClearPool(_connectionString);
23+
24+
var allreadyEstablished = GetEstablishedConnections();
25+
2026
var connection1 = MakeConnection();
2127
var connection2 = MakeConnection();
2228

2329
//open first connection
2430
connection1.Open();
25-
VerifyCountOfEstablishedConnectionsIs(1);
31+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first open");
2632

2733
//return it to the pool
2834
connection1.Close();
29-
VerifyCountOfEstablishedConnectionsIs(1);
35+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first close");
3036

3137
//open the second connection
3238
connection2.Open();
33-
VerifyCountOfEstablishedConnectionsIs(1);
39+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After second open");
3440

3541
//return it to the pool
3642
connection2.Close();
37-
VerifyCountOfEstablishedConnectionsIs(1);
43+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After second close");
3844
}
3945

4046
[Test]
4147
public void ConnectionPooling_OpenThenCloseTwoAtTheSameTime_TowConnectionsArePooled()
4248
{
4349
MakeDriver();
50+
51+
_driver.ClearPool(_connectionString);
52+
53+
var allreadyEstablished = GetEstablishedConnections();
54+
4455
var connection1 = MakeConnection();
4556
var connection2 = MakeConnection();
4657

4758
//open first connection
4859
connection1.Open();
49-
VerifyCountOfEstablishedConnectionsIs(1);
60+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first open");
5061

5162
//open second one
5263
connection2.Open();
53-
VerifyCountOfEstablishedConnectionsIs(2);
64+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After second open");
5465

5566
//return connection1 to the pool
5667
connection1.Close();
57-
VerifyCountOfEstablishedConnectionsIs(2);
68+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After first close");
5869

5970
//return connection2 to the pool
6071
connection2.Close();
61-
VerifyCountOfEstablishedConnectionsIs(2);
72+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After second close");
6273
}
6374

6475
[Test]
@@ -163,10 +174,10 @@ private DbConnection MakeConnection()
163174
return result;
164175
}
165176

166-
private void VerifyCountOfEstablishedConnectionsIs(int expectedCount)
177+
private void VerifyCountOfEstablishedConnectionsIs(int expectedCount, string step)
167178
{
168179
var physicalConnections = GetEstablishedConnections();
169-
Assert.That(physicalConnections, Is.EqualTo(expectedCount));
180+
Assert.That(physicalConnections, Is.EqualTo(expectedCount), step);
170181
}
171182

172183
private int GetEstablishedConnections()
@@ -178,7 +189,7 @@ private int GetEstablishedConnections()
178189
using (var cmd = conn.CreateCommand())
179190
{
180191
cmd.CommandText = "select count(*) from mon$attachments where mon$attachment_id <> current_connection";
181-
return (int)cmd.ExecuteScalar();
192+
return Convert.ToInt32(cmd.ExecuteScalar());
182193
}
183194
}
184195
}

src/NHibernate.Test/Hql/HQLFunctions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,14 @@ public void Cast()
733733
if (!ex.InnerException.Message.StartsWith("ORA-00979"))
734734
throw;
735735
}
736+
else if (Dialect is FirebirdDialect)
737+
{
738+
string msgToCheck =
739+
"not contained in either an aggregate function or the GROUP BY clause";
740+
// This test raises an exception in Firebird for an unknown reason.
741+
if (!ex.InnerException.Message.Contains(msgToCheck))
742+
throw;
743+
}
736744
else
737745
{
738746
string msgToCheck =

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

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading;
5-
using NHibernate.Util;
5+
using NHibernate.Dialect;
66
using NUnit.Framework;
77

88
namespace NHibernate.Test.NHSpecificTest.NH1908ThreadSafety
@@ -12,29 +12,12 @@ public class Fixture : BugTestCase
1212
{
1313
protected override bool AppliesTo(Dialect.Dialect dialect)
1414
{
15-
return !(dialect is Dialect.Oracle8iDialect);
15+
return !(dialect is Oracle8iDialect);
1616
// Oracle sometimes causes: ORA-12520: TNS:listener could not find available handler for requested type of server
1717
// Following links bizarrely suggest it's an Oracle limitation under load:
1818
// http://www.orafaq.com/forum/t/60019/2/ & http://www.ispirer.com/wiki/sqlways/troubleshooting-guide/oracle/import/tns_listener
1919
}
2020

21-
protected override void OnTearDown()
22-
{
23-
base.OnTearDown();
24-
25-
if (!(Dialect is Dialect.FirebirdDialect))
26-
return;
27-
28-
// Firebird will pool each connection created during the test and will not drop the created tables
29-
// which will result in other tests failing when they try to create tables with same name
30-
// By clearing the connection pool the tables will get dropped. This is done by the following code.
31-
var fbConnectionType = ReflectHelper.TypeFromAssembly("FirebirdSql.Data.FirebirdClient.FbConnection", "FirebirdSql.Data.FirebirdClient", false);
32-
var clearPool = fbConnectionType.GetMethod("ClearPool");
33-
var sillyConnection = Sfi.ConnectionProvider.GetConnection();
34-
clearPool.Invoke(null, new object[] { sillyConnection });
35-
Sfi.ConnectionProvider.CloseConnection(sillyConnection);
36-
}
37-
3821
[Test]
3922
public void UsingFiltersIsThreadSafe()
4023
{

src/NHibernate.Test/NHSpecificTest/NH3374/FixtureByCode.cs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System.Linq;
2-
using NHibernate.Cfg.MappingSchema;
3-
using NHibernate.Linq;
1+
using NHibernate.Cfg.MappingSchema;
42
using NHibernate.Mapping.ByCode;
53
using NUnit.Framework;
64

@@ -15,9 +13,11 @@ protected override HbmMapping GetMappings()
1513
mapper.Class<Document>(rc =>
1614
{
1715
rc.Id(x => x.Id, idMapper => idMapper.Generator(Generators.Identity));
18-
rc.ManyToOne(x => x.Blob, m =>
16+
rc.ManyToOne(x => x.Blob,
17+
m =>
1918
{
2019
m.Cascade(Mapping.ByCode.Cascade.All);
20+
m.Column("`Blob`");
2121
});
2222
rc.Property(x => x.Name);
2323
});
@@ -30,21 +30,31 @@ protected override HbmMapping GetMappings()
3030
y.Length(int.MaxValue);
3131
y.Lazy(true);
3232
});
33+
map.Table("`Blob`");
3334
});
3435

3536
return mapper.CompileMappingForAllExplicitlyAddedEntities();
3637
}
3738

39+
private int _blobId;
40+
private int _docId;
41+
3842
protected override void OnSetUp()
3943
{
4044
using (ISession session = OpenSession())
4145
using (ITransaction transaction = session.BeginTransaction())
4246
{
43-
var e1 = new Document { Name = "Bob" };
44-
e1.Blob = new Blob { Bytes = new byte[] { 1, 2, 3 } };
47+
var e1 = new Document
48+
{
49+
Name = "Bob",
50+
Blob = new Blob {Bytes = new byte[] {1, 2, 3}}
51+
};
52+
4553
session.Save(e1);
46-
4754
session.Flush();
55+
56+
_blobId = e1.Blob.Id;
57+
_docId = e1.Id;
4858
transaction.Commit();
4959
}
5060
}
@@ -71,7 +81,7 @@ public void TestNoTargetException()
7181
document.Blob = blob;
7282

7383
using (ISession session = OpenSession())
74-
using (ITransaction transaction = session.BeginTransaction())
84+
using (session.BeginTransaction())
7585
{
7686
session.Merge(document);
7787
}
@@ -82,7 +92,7 @@ private Blob LoadDetachedBlob()
8292
using (ISession session = OpenSession())
8393
using (session.BeginTransaction())
8494
{
85-
var blob = session.Get<Blob>(1);
95+
var blob = session.Get<Blob>(_blobId);
8696
NHibernateUtil.Initialize(blob.Bytes);
8797
return blob;
8898
}
@@ -93,7 +103,7 @@ private Document LoadDetachedEntity()
93103
using (ISession session = OpenSession())
94104
using (session.BeginTransaction())
95105
{
96-
return session.Get<Document>(1);
106+
return session.Get<Document>(_docId);
97107
}
98108
}
99109
}

src/NHibernate.Test/TestCase.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
using NHibernate.Tool.hbm2ddl;
1212
using NHibernate.Type;
1313
using NUnit.Framework;
14-
using NHibernate.Hql.Ast.ANTLR;
1514
using NUnit.Framework.Interfaces;
1615
using System.Text;
16+
using NHibernate.Driver;
1717

1818
namespace NHibernate.Test
1919
{
@@ -269,6 +269,17 @@ protected virtual void CreateSchema()
269269

270270
protected virtual void DropSchema()
271271
{
272+
if (Sfi.ConnectionProvider.Driver is FirebirdClientDriver fbDriver)
273+
{
274+
// Firebird will pool each connection created during the test and will marked as used any table
275+
// referenced by queries. It will at best delays those tables drop until connections are actually
276+
// closed, or immediately fail dropping them.
277+
// This results in other tests failing when they try to create tables with same name.
278+
// By clearing the connection pool the tables will get dropped. This is done by the following code.
279+
// Moved from NH1908 test case, contributed by Amro El-Fakharany.
280+
fbDriver.ClearPool(null);
281+
}
282+
272283
new SchemaExport(cfg).Drop(OutputDdl, true);
273284
}
274285

src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,16 @@ private static void SetupSqlServerOdbc(Cfg.Configuration cfg)
102102

103103
private static void SetupFirebird(Cfg.Configuration cfg)
104104
{
105+
var connStr = cfg.Properties[Cfg.Environment.ConnectionString];
105106
try
106107
{
107-
if (File.Exists("NHibernate.fdb"))
108-
File.Delete("NHibernate.fdb");
108+
FbConnection.DropDatabase(connStr);
109109
}
110110
catch (Exception e)
111111
{
112112
Console.WriteLine(e);
113113
}
114-
115-
FbConnection.CreateDatabase("Database=NHibernate.fdb;ServerType=1");
114+
FbConnection.CreateDatabase(connStr, forcedWrites:false);
116115
}
117116

118117
private static void SetupSqlServerCe(Cfg.Configuration cfg)

0 commit comments

Comments
 (0)