Skip to content

Commit 94b22cb

Browse files
committed
EnsureDatabase and DropDatabase implemented
1 parent a79be9c commit 94b22cb

File tree

2 files changed

+133
-2
lines changed

2 files changed

+133
-2
lines changed

src/Sample/Program.cs

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ static int Main()
1313
var config = GetConfig();
1414
string connectionString = config.GetConnectionString("SampleFirebird");
1515

16+
// If you used `docker compose up` for creating a server and a database, the database already exists.
17+
// You can see that a new database can be created using EnsureDatabase.For.FirebirdDatabase(connectionString) by changing the Database parameter (the fdb filename)
18+
// in the connectionString in appsettings.json
19+
// You can also try to drop a database by using DropDatabase.For.FirebirdDatabase(connectionString);
20+
EnsureDatabase.For.FirebirdDatabase(connectionString);
21+
1622
var upgrader =
1723
DeployChanges.To
1824
.FirebirdDatabase(connectionString)

src/dbup-firebird/FirebirdExtensions.cs

+127-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
using DbUp.Builder;
1+
using System;
2+
using System.IO;
3+
using DbUp;
4+
using DbUp.Builder;
5+
using DbUp.Engine.Output;
26
using DbUp.Engine.Transactions;
37
using DbUp.Firebird;
8+
using FirebirdSql.Data.FirebirdClient;
49

510
// ReSharper disable once CheckNamespace
611

@@ -49,4 +54,124 @@ public static UpgradeEngineBuilder FirebirdDatabase(IConnectionManager connectio
4954
builder.WithPreprocessor(new FirebirdPreprocessor());
5055
return builder;
5156
}
52-
}
57+
58+
59+
//The code below concerning EnsureDatabase and DropDatabase is a modified version from a PR from Github user @hhindriks. Thank you for your contribution.
60+
61+
//Error codes from Firebird (see https://www.firebirdsql.org/pdfrefdocs/Firebird-2.1-ErrorCodes.pdf)
62+
const int FbIoError = 335544344;
63+
const int FbNetworkError = 335544721;
64+
const int FbLockTimeout = 335544510;
65+
66+
/// <summary>
67+
/// Ensures that the database specified in the connection string exists.
68+
/// </summary>
69+
/// <param name="supported">Fluent helper type.</param>
70+
/// <param name="connectionString">The connection string.</param>
71+
/// <param name="logger">The <see cref="DbUp.Engine.Output.IUpgradeLog"/> used to record actions.</param>
72+
/// <returns></returns>
73+
public static void FirebirdDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, IUpgradeLog logger = null)
74+
{
75+
logger ??= new ConsoleUpgradeLog();
76+
var builder = new FbConnectionStringBuilder(connectionString);
77+
78+
if (builder.ServerType == FbServerType.Embedded)
79+
{
80+
//The code for the embedded servertype is currently not tested.
81+
//Comes from the original PR from @hhindriks
82+
if (!File.Exists(builder.Database))
83+
{
84+
FbConnection.CreateDatabase(builder.ToString());
85+
logger.WriteInformation("Created database {0}", builder.Database);
86+
}
87+
else
88+
{
89+
logger.WriteInformation("Database {0} already exists", builder.Database);
90+
}
91+
}
92+
else
93+
{
94+
using var conn = new FbConnection(builder.ToString());
95+
try
96+
{
97+
conn.Open();
98+
conn.Close();
99+
logger.WriteInformation("Database {0} already exists", builder.Database);
100+
}
101+
catch (FbException ex) when (ex.ErrorCode == FbIoError)
102+
{
103+
FbConnection.CreateDatabase(builder.ToString());
104+
logger.WriteInformation("Created database {0}", builder.Database);
105+
}
106+
catch (FbException ex) when (ex.ErrorCode == FbNetworkError)
107+
{
108+
logger.WriteError("Could not access server. The server: {0} is probably not started.", builder.DataSource);
109+
throw;
110+
}
111+
catch (FbException)
112+
{
113+
logger.WriteError("Ensure Database: Unknown firebird error when trying to access the server: {0}.", builder.DataSource);
114+
throw;
115+
}
116+
catch (Exception)
117+
{
118+
logger.WriteError("Ensure Database: Unknown error when trying to access the server: {0}.", builder.DataSource);
119+
throw;
120+
}
121+
}
122+
}
123+
124+
/// <summary>
125+
/// Drop the database specified in the connection string.
126+
/// </summary>
127+
/// <param name="supported">Fluent helper type.</param>
128+
/// <param name="connectionString">The connection string.</param>
129+
/// <param name="logger">The <see cref="DbUp.Engine.Output.IUpgradeLog"/> used to record actions.</param>
130+
/// <returns></returns>
131+
public static void FirebirdDatabase(this SupportedDatabasesForDropDatabase supported, string connectionString, IUpgradeLog logger = null)
132+
{
133+
logger ??= new ConsoleUpgradeLog();
134+
var builder = new FbConnectionStringBuilder(connectionString);
135+
136+
if (builder.ServerType == FbServerType.Embedded)
137+
{
138+
//The code for the embedded servertype is currently not tested.
139+
//Comes from the original PR from @hhindriks
140+
if (File.Exists(builder.Database))
141+
{
142+
FbConnection.DropDatabase(builder.ToString());
143+
logger.WriteInformation("Dropped database {0}", builder.Database);
144+
}
145+
}
146+
else
147+
{
148+
try
149+
{
150+
//There seems to be an error in the FirebirdClient when trying to drop a database that does not exist.
151+
//It gives a NullRefException instead of the expected FbException.
152+
FbConnection.DropDatabase(builder.ToString());
153+
logger.WriteInformation("Dropped database {0}", builder.Database);
154+
}
155+
catch (FbException ex) when (ex.ErrorCode == FbIoError)
156+
{
157+
logger.WriteWarning("Nothing to Drop. No database found.");
158+
}
159+
catch (FbException ex) when (ex.ErrorCode == FbLockTimeout)
160+
{
161+
logger.WriteError("Can't drop database. Are there still an active connection?");
162+
throw;
163+
}
164+
catch (FbException)
165+
{
166+
logger.WriteError("Drop Database: Unknown firebird error when trying to access the server: {0}.", builder.DataSource);
167+
throw;
168+
}
169+
catch (Exception)
170+
{
171+
logger.WriteError("Drop Database: Unknown error when trying to access the server: {0}.", builder.DataSource);
172+
throw;
173+
}
174+
}
175+
}
176+
177+
}

0 commit comments

Comments
 (0)