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

Issue/1 createdatabase #9

Merged
merged 3 commits into from
Aug 2, 2024
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
6 changes: 6 additions & 0 deletions src/Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ static int Main()
var config = GetConfig();
string connectionString = config.GetConnectionString("SampleFirebird");

// If you used `docker compose up` for creating a server and a database, the database already exists.
// You can see that a new database can be created using EnsureDatabase.For.FirebirdDatabase(connectionString) by changing the Database parameter (the fdb filename)
// in the connectionString in appsettings.json
// You can also try to drop a database by using DropDatabase.For.FirebirdDatabase(connectionString);
EnsureDatabase.For.FirebirdDatabase(connectionString);

var upgrader =
DeployChanges.To
.FirebirdDatabase(connectionString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public static class FirebirdExtensions
public static DbUp.Builder.UpgradeEngineBuilder FirebirdDatabase(DbUp.Engine.Transactions.IConnectionManager connectionManager) { }
public static DbUp.Builder.UpgradeEngineBuilder FirebirdDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString) { }
public static DbUp.Builder.UpgradeEngineBuilder FirebirdDatabase(this DbUp.Builder.SupportedDatabases supported, DbUp.Engine.Transactions.IConnectionManager connectionManager) { }
public static void FirebirdDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger = null) { }
public static void FirebirdDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger = null) { }
}
namespace DbUp.Firebird
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public static class FirebirdExtensions
public static DbUp.Builder.UpgradeEngineBuilder FirebirdDatabase(DbUp.Engine.Transactions.IConnectionManager connectionManager) { }
public static DbUp.Builder.UpgradeEngineBuilder FirebirdDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString) { }
public static DbUp.Builder.UpgradeEngineBuilder FirebirdDatabase(this DbUp.Builder.SupportedDatabases supported, DbUp.Engine.Transactions.IConnectionManager connectionManager) { }
public static void FirebirdDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger = null) { }
public static void FirebirdDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger = null) { }
}
namespace DbUp.Firebird
{
Expand Down
129 changes: 127 additions & 2 deletions src/dbup-firebird/FirebirdExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
using DbUp.Builder;
using System;
using System.IO;
using DbUp;
using DbUp.Builder;
using DbUp.Engine.Output;
using DbUp.Engine.Transactions;
using DbUp.Firebird;
using FirebirdSql.Data.FirebirdClient;

// ReSharper disable once CheckNamespace

Expand Down Expand Up @@ -49,4 +54,124 @@ public static UpgradeEngineBuilder FirebirdDatabase(IConnectionManager connectio
builder.WithPreprocessor(new FirebirdPreprocessor());
return builder;
}
}


//The code below concerning EnsureDatabase and DropDatabase is a modified version from a PR from Github user @hhindriks. Thank you for your contribution.

//Error codes from Firebird (see https://www.firebirdsql.org/pdfrefdocs/Firebird-2.1-ErrorCodes.pdf)
const int FbIoError = 335544344;
const int FbNetworkError = 335544721;
const int FbLockTimeout = 335544510;

/// <summary>
/// Ensures that the database specified in the connection string exists.
/// </summary>
/// <param name="supported">Fluent helper type.</param>
/// <param name="connectionString">The connection string.</param>
/// <param name="logger">The <see cref="DbUp.Engine.Output.IUpgradeLog"/> used to record actions.</param>
/// <returns></returns>
public static void FirebirdDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, IUpgradeLog logger = null)
{
logger ??= new ConsoleUpgradeLog();
var builder = new FbConnectionStringBuilder(connectionString);

if (builder.ServerType == FbServerType.Embedded)
{
//The code for the embedded servertype is currently not tested.
//Comes from the original PR from @hhindriks
if (!File.Exists(builder.Database))
{
FbConnection.CreateDatabase(builder.ToString());
logger.WriteInformation("Created database {0}", builder.Database);
}
else
{
logger.WriteInformation("Database {0} already exists", builder.Database);
}
}
else
{
using var conn = new FbConnection(builder.ToString());
try
{
conn.Open();
conn.Close();
logger.WriteInformation("Database {0} already exists", builder.Database);
}
catch (FbException ex) when (ex.ErrorCode == FbIoError)
{
FbConnection.CreateDatabase(builder.ToString());
logger.WriteInformation("Created database {0}", builder.Database);
}
catch (FbException ex) when (ex.ErrorCode == FbNetworkError)
{
logger.WriteError("Could not access server. The server: {0} is probably not started.", builder.DataSource);
throw;
}
catch (FbException)
{
logger.WriteError("Ensure Database: Unknown firebird error when trying to access the server: {0}.", builder.DataSource);
throw;
}
catch (Exception)
{
logger.WriteError("Ensure Database: Unknown error when trying to access the server: {0}.", builder.DataSource);
throw;
}
}
}

/// <summary>
/// Drop the database specified in the connection string.
/// </summary>
/// <param name="supported">Fluent helper type.</param>
/// <param name="connectionString">The connection string.</param>
/// <param name="logger">The <see cref="DbUp.Engine.Output.IUpgradeLog"/> used to record actions.</param>
/// <returns></returns>
public static void FirebirdDatabase(this SupportedDatabasesForDropDatabase supported, string connectionString, IUpgradeLog logger = null)
{
logger ??= new ConsoleUpgradeLog();
var builder = new FbConnectionStringBuilder(connectionString);

if (builder.ServerType == FbServerType.Embedded)
{
//The code for the embedded servertype is currently not tested.
//Comes from the original PR from @hhindriks
if (File.Exists(builder.Database))
{
FbConnection.DropDatabase(builder.ToString());
logger.WriteInformation("Dropped database {0}", builder.Database);
}
}
else
{
try
{
//There seems to be an error in the FirebirdClient when trying to drop a database that does not exist.
//It gives a NullRefException instead of the expected FbException.
FbConnection.DropDatabase(builder.ToString());
logger.WriteInformation("Dropped database {0}", builder.Database);
}
catch (FbException ex) when (ex.ErrorCode == FbIoError)
{
logger.WriteWarning("Nothing to Drop. No database found.");
}
catch (FbException ex) when (ex.ErrorCode == FbLockTimeout)
{
logger.WriteError("Can't drop database. Are there still an active connection?");
throw;
}
catch (FbException)
{
logger.WriteError("Drop Database: Unknown firebird error when trying to access the server: {0}.", builder.DataSource);
throw;
}
catch (Exception)
{
logger.WriteError("Drop Database: Unknown error when trying to access the server: {0}.", builder.DataSource);
throw;
}
}
}

}
Loading