diff --git a/src/.editorconfig b/src/.editorconfig
index 3f25e8c..dceccb2 100644
--- a/src/.editorconfig
+++ b/src/.editorconfig
@@ -121,3 +121,11 @@ csharp_preserve_single_line_blocks = true
[*.vb]
# Modifier preferences
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
+###############################
+# XML and csproj #
+###############################
+[*.{xml,csproj}]
+max_line_length = off
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_size = 2
\ No newline at end of file
diff --git a/src/Sample/Program.cs b/src/Sample/Program.cs
new file mode 100644
index 0000000..9bcb7ee
--- /dev/null
+++ b/src/Sample/Program.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using Microsoft.Extensions.Configuration;
+using DbUp;
+
+namespace FirebirdSampleApplication
+{
+ class Program
+ {
+ static int Main()
+ {
+ var config = GetConfig();
+ string connectionString = config.GetConnectionString("SampleFirebird");
+
+ var upgrader =
+ DeployChanges.To
+ .FirebirdDatabase(connectionString)
+ .WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
+ .WithTransactionPerScript()
+ .LogToConsole()
+ .Build();
+
+ var result = upgrader.PerformUpgrade();
+
+ if (!result.Successful)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine(result.Error);
+ Console.ResetColor();
+
+ WaitIfDebug();
+ return -1;
+ }
+
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine("Success!");
+ Console.ResetColor();
+ WaitIfDebug();
+ return 0;
+ }
+
+ private static IConfiguration GetConfig()
+ {
+ IConfiguration config = new ConfigurationBuilder()
+ .AddJsonFile("appsettings.json", true, true)
+ .Build();
+ return config;
+ }
+
+ [Conditional("DEBUG")]
+ public static void WaitIfDebug()
+ {
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/src/Sample/Sample.csproj b/src/Sample/Sample.csproj
new file mode 100644
index 0000000..be407ce
--- /dev/null
+++ b/src/Sample/Sample.csproj
@@ -0,0 +1,22 @@
+
+
+ net7.0
+ Exe
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
diff --git a/src/Sample/Scripts/Script0001.sql b/src/Sample/Scripts/Script0001.sql
new file mode 100644
index 0000000..024d19e
--- /dev/null
+++ b/src/Sample/Scripts/Script0001.sql
@@ -0,0 +1 @@
+CREATE TABLE Testing1 (ID integer NOT NULL)
\ No newline at end of file
diff --git a/src/Sample/Scripts/Script0002.sql b/src/Sample/Scripts/Script0002.sql
new file mode 100644
index 0000000..b50f004
--- /dev/null
+++ b/src/Sample/Scripts/Script0002.sql
@@ -0,0 +1,4 @@
+CREATE TABLE Testing2 (ID integer NOT NULL)
+;
+CREATE TABLE Testing3 (ID integer NOT NULL)
+;
diff --git a/src/Sample/Scripts/Script0003.sql b/src/Sample/Scripts/Script0003.sql
new file mode 100644
index 0000000..6dd7814
--- /dev/null
+++ b/src/Sample/Scripts/Script0003.sql
@@ -0,0 +1,4 @@
+CREATE TABLE Testing4 (ID integer NOT NULL)
+;
+CREATE TABLE Testing5 (ID integer NOT NULL)
+;
diff --git a/src/Sample/Scripts/Script0004.sql b/src/Sample/Scripts/Script0004.sql
new file mode 100644
index 0000000..45bd4d5
--- /dev/null
+++ b/src/Sample/Scripts/Script0004.sql
@@ -0,0 +1,4 @@
+CREATE TABLE Testing6 (ID integer NOT NULL)
+;
+CREATE TABLE Testing7 (ID integer NOT NULL)
+;
diff --git a/src/Sample/appsettings.json b/src/Sample/appsettings.json
new file mode 100644
index 0000000..b40a501
--- /dev/null
+++ b/src/Sample/appsettings.json
@@ -0,0 +1,5 @@
+{
+ "ConnectionStrings": {
+ "SampleFirebird": "User=SOMEUSER;Password=SOMEPWD;Database=c:\\somedb.fdb;DataSource=SOMESERVERNAME;Port=SOMEPORT;Dialect=3;Charset=ISO8859_1;ServerType=0;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;"
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.verified.txt b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.verified.txt
new file mode 100644
index 0000000..dc21488
--- /dev/null
+++ b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.verified.txt
@@ -0,0 +1,38 @@
+DB Operation: Open connection
+Info: Beginning database upgrade
+Info: Checking whether journal table exists..
+DB Operation: Execute scalar command: select 1 from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0 and RDB$RELATION_NAME = 'schemaversions'
+DB Operation: Dispose command
+Info: Journal table does not exist
+Info: Executing Database Server script 'Script0001.sql'
+Info: Checking whether journal table exists..
+DB Operation: Execute scalar command: select 1 from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0 and RDB$RELATION_NAME = 'schemaversions'
+DB Operation: Dispose command
+Info: Creating the "schemaversions" table
+DB Operation: Execute non query command: CREATE TABLE "schemaversions"
+(
+ schemaversionsid INTEGER NOT NULL,
+ scriptname VARCHAR(255) NOT NULL,
+ applied TIMESTAMP NOT NULL,
+ CONSTRAINT pk_schemaversions_id PRIMARY KEY (schemaversionsid)
+)
+DB Operation: Dispose command
+Info: The "schemaversions" table has been created
+DB Operation: Execute non query command: CREATE SEQUENCE GEN_schemaversionsID
+DB Operation: Dispose command
+Info: The GEN_schemaversionsID generator has been created
+DB Operation: Execute non query command: CREATE TRIGGER BI_schemaversionsID FOR "schemaversions" ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
+ if (new.schemaversionsid is null or (new.schemaversionsid = 0)) then new.schemaversionsid = gen_id(GEN_schemaversionsID,1);
+END;
+DB Operation: Dispose command
+Info: The BI_schemaversionsID trigger has been created
+DB Operation: Execute non query command: script1contents
+DB Operation: Dispose command
+DB Operation: Create parameter
+Info: DB Operation: Add parameter to command: scriptName=Script0001.sql
+DB Operation: Create parameter
+Info: DB Operation: Add parameter to command: applied=
+DB Operation: Execute non query command: insert into "schemaversions" (ScriptName, Applied) values (@scriptName, @applied)
+DB Operation: Dispose command
+Info: Upgrade successful
+DB Operation: Dispose connection
diff --git a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.verified.txt b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.verified.txt
new file mode 100644
index 0000000..c0696bf
--- /dev/null
+++ b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.verified.txt
@@ -0,0 +1,38 @@
+DB Operation: Open connection
+Info: Beginning database upgrade
+Info: Checking whether journal table exists..
+DB Operation: Execute scalar command: select 1 from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0 and RDB$RELATION_NAME = 'TestSchemaVersions'
+DB Operation: Dispose command
+Info: Journal table does not exist
+Info: Executing Database Server script 'Script0001.sql'
+Info: Checking whether journal table exists..
+DB Operation: Execute scalar command: select 1 from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0 and RDB$RELATION_NAME = 'TestSchemaVersions'
+DB Operation: Dispose command
+Info: Creating the "TestSchemaVersions" table
+DB Operation: Execute non query command: CREATE TABLE "TestSchemaVersions"
+(
+ schemaversionsid INTEGER NOT NULL,
+ scriptname VARCHAR(255) NOT NULL,
+ applied TIMESTAMP NOT NULL,
+ CONSTRAINT pk_TestSchemaVersions_id PRIMARY KEY (schemaversionsid)
+)
+DB Operation: Dispose command
+Info: The "TestSchemaVersions" table has been created
+DB Operation: Execute non query command: CREATE SEQUENCE GEN_TestSchemaVersionsID
+DB Operation: Dispose command
+Info: The GEN_TestSchemaVersionsID generator has been created
+DB Operation: Execute non query command: CREATE TRIGGER BI_TestSchemaVersionsID FOR "TestSchemaVersions" ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
+ if (new.schemaversionsid is null or (new.schemaversionsid = 0)) then new.schemaversionsid = gen_id(GEN_TestSchemaVersionsID,1);
+END;
+DB Operation: Dispose command
+Info: The BI_TestSchemaVersionsID trigger has been created
+DB Operation: Execute non query command: script1contents
+DB Operation: Dispose command
+DB Operation: Create parameter
+Info: DB Operation: Add parameter to command: scriptName=Script0001.sql
+DB Operation: Create parameter
+Info: DB Operation: Add parameter to command: applied=
+DB Operation: Execute non query command: insert into "TestSchemaVersions" (ScriptName, Applied) values (@scriptName, @applied)
+DB Operation: Dispose command
+Info: Upgrade successful
+DB Operation: Dispose connection
diff --git a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.verified.txt b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.verified.txt
new file mode 100644
index 0000000..1cbac5a
--- /dev/null
+++ b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.verified.txt
@@ -0,0 +1,38 @@
+DB Operation: Open connection
+Info: Beginning database upgrade
+Info: Checking whether journal table exists..
+DB Operation: Execute scalar command: select 1 from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0 and RDB$RELATION_NAME = 'schemaversions'
+DB Operation: Dispose command
+Info: Journal table does not exist
+Info: Executing Database Server script 'Script0001.sql'
+Info: Checking whether journal table exists..
+DB Operation: Execute scalar command: select 1 from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0 and RDB$RELATION_NAME = 'schemaversions'
+DB Operation: Dispose command
+Info: Creating the "schemaversions" table
+DB Operation: Execute non query command: CREATE TABLE "schemaversions"
+(
+ schemaversionsid INTEGER NOT NULL,
+ scriptname VARCHAR(255) NOT NULL,
+ applied TIMESTAMP NOT NULL,
+ CONSTRAINT pk_schemaversions_id PRIMARY KEY (schemaversionsid)
+)
+DB Operation: Dispose command
+Info: The "schemaversions" table has been created
+DB Operation: Execute non query command: CREATE SEQUENCE GEN_schemaversionsID
+DB Operation: Dispose command
+Info: The GEN_schemaversionsID generator has been created
+DB Operation: Execute non query command: CREATE TRIGGER BI_schemaversionsID FOR "schemaversions" ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
+ if (new.schemaversionsid is null or (new.schemaversionsid = 0)) then new.schemaversionsid = gen_id(GEN_schemaversionsID,1);
+END;
+DB Operation: Dispose command
+Info: The BI_schemaversionsID trigger has been created
+DB Operation: Execute non query command: print SubstitutedValue
+DB Operation: Dispose command
+DB Operation: Create parameter
+Info: DB Operation: Add parameter to command: scriptName=Script0001.sql
+DB Operation: Create parameter
+Info: DB Operation: Add parameter to command: applied=
+DB Operation: Execute non query command: insert into "schemaversions" (ScriptName, Applied) values (@scriptName, @applied)
+DB Operation: Dispose command
+Info: Upgrade successful
+DB Operation: Dispose connection
diff --git a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.DotNet.verified.cs b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.DotNet.verified.cs
new file mode 100644
index 0000000..797159c
--- /dev/null
+++ b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.DotNet.verified.cs
@@ -0,0 +1,43 @@
+[assembly: System.CLSCompliantAttribute(true)]
+[assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)]
+
+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) { }
+}
+namespace DbUp.Firebird
+{
+ public class FirebirdConnectionManager : DbUp.Engine.Transactions.DatabaseConnectionManager, DbUp.Engine.Transactions.IConnectionManager
+ {
+ public FirebirdConnectionManager(string connectionString) { }
+ protected override DbUp.Engine.Transactions.AllowedTransactionMode AllowedTransactionModes { get; }
+ public override System.Collections.Generic.IEnumerable SplitScriptIntoCommands(string scriptContents) { }
+ }
+ public class FirebirdObjectParser : DbUp.Support.SqlObjectParser, DbUp.Engine.ISqlObjectParser
+ {
+ public FirebirdObjectParser() { }
+ }
+ public class FirebirdPreprocessor : DbUp.Engine.IScriptPreprocessor
+ {
+ public FirebirdPreprocessor() { }
+ public string Process(string contents) { }
+ }
+ public class FirebirdScriptExecutor : DbUp.Support.ScriptExecutor, DbUp.Engine.IScriptExecutor
+ {
+ public FirebirdScriptExecutor(System.Func connectionManagerFactory, System.Func log, string schema, System.Func variablesEnabled, System.Collections.Generic.IEnumerable scriptPreprocessors, System.Func journal) { }
+ protected override bool UseTheSameTransactionForJournalTableAndScripts { get; }
+ protected override void ExecuteCommandsWithinExceptionHandler(int index, DbUp.Engine.SqlScript script, System.Action executeCommand) { }
+ protected override string GetVerifySchemaSql(string schema) { }
+ }
+ public class FirebirdTableJournal : DbUp.Support.TableJournal, DbUp.Engine.IJournal
+ {
+ public FirebirdTableJournal(System.Func connectionManager, System.Func logger, string tableName) { }
+ protected override string CreateSchemaTableSql(string quotedPrimaryKeyName) { }
+ protected override string DoesTableExistSql() { }
+ protected override string GetInsertJournalEntrySql(string scriptName, string applied) { }
+ protected override string GetJournalEntriesSql() { }
+ protected override void OnTableCreated(System.Func dbCommandFactory) { }
+ }
+}
diff --git a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs
new file mode 100644
index 0000000..797159c
--- /dev/null
+++ b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs
@@ -0,0 +1,43 @@
+[assembly: System.CLSCompliantAttribute(true)]
+[assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)]
+
+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) { }
+}
+namespace DbUp.Firebird
+{
+ public class FirebirdConnectionManager : DbUp.Engine.Transactions.DatabaseConnectionManager, DbUp.Engine.Transactions.IConnectionManager
+ {
+ public FirebirdConnectionManager(string connectionString) { }
+ protected override DbUp.Engine.Transactions.AllowedTransactionMode AllowedTransactionModes { get; }
+ public override System.Collections.Generic.IEnumerable SplitScriptIntoCommands(string scriptContents) { }
+ }
+ public class FirebirdObjectParser : DbUp.Support.SqlObjectParser, DbUp.Engine.ISqlObjectParser
+ {
+ public FirebirdObjectParser() { }
+ }
+ public class FirebirdPreprocessor : DbUp.Engine.IScriptPreprocessor
+ {
+ public FirebirdPreprocessor() { }
+ public string Process(string contents) { }
+ }
+ public class FirebirdScriptExecutor : DbUp.Support.ScriptExecutor, DbUp.Engine.IScriptExecutor
+ {
+ public FirebirdScriptExecutor(System.Func connectionManagerFactory, System.Func log, string schema, System.Func variablesEnabled, System.Collections.Generic.IEnumerable scriptPreprocessors, System.Func journal) { }
+ protected override bool UseTheSameTransactionForJournalTableAndScripts { get; }
+ protected override void ExecuteCommandsWithinExceptionHandler(int index, DbUp.Engine.SqlScript script, System.Action executeCommand) { }
+ protected override string GetVerifySchemaSql(string schema) { }
+ }
+ public class FirebirdTableJournal : DbUp.Support.TableJournal, DbUp.Engine.IJournal
+ {
+ public FirebirdTableJournal(System.Func connectionManager, System.Func logger, string tableName) { }
+ protected override string CreateSchemaTableSql(string quotedPrimaryKeyName) { }
+ protected override string DoesTableExistSql() { }
+ protected override string GetInsertJournalEntrySql(string scriptName, string applied) { }
+ protected override string GetJournalEntriesSql() { }
+ protected override void OnTableCreated(System.Func dbCommandFactory) { }
+ }
+}
diff --git a/src/Tests/DatabaseSupportTests.cs b/src/Tests/DatabaseSupportTests.cs
new file mode 100644
index 0000000..e6a40ef
--- /dev/null
+++ b/src/Tests/DatabaseSupportTests.cs
@@ -0,0 +1,23 @@
+#if !NETCORE
+using DbUp.Builder;
+using DbUp.Firebird;
+using DbUp.Tests.Common;
+
+namespace DbUp.Tests.Providers.Firebird;
+
+public class DatabaseSupportTests : DatabaseSupportTestsBase
+{
+ public DatabaseSupportTests() : base()
+ {
+ }
+
+ protected override UpgradeEngineBuilder DeployTo(SupportedDatabases to)
+ => to.FirebirdDatabase("");
+
+ protected override UpgradeEngineBuilder AddCustomNamedJournalToBuilder(UpgradeEngineBuilder builder, string schema, string tableName)
+ => builder.JournalTo(
+ (connectionManagerFactory, logFactory)
+ => new FirebirdTableJournal(connectionManagerFactory, logFactory, tableName)
+ );
+}
+#endif
diff --git a/src/Tests/NoPublicApiChanges.cs b/src/Tests/NoPublicApiChanges.cs
new file mode 100644
index 0000000..3f3da54
--- /dev/null
+++ b/src/Tests/NoPublicApiChanges.cs
@@ -0,0 +1,13 @@
+#if !NETCORE
+using DbUp.Tests.Common;
+
+namespace DbUp.Tests.Providers.Firebird;
+
+public class NoPublicApiChanges : NoPublicApiChangesBase
+{
+ public NoPublicApiChanges()
+ : base(typeof(FirebirdExtensions).Assembly)
+ {
+ }
+}
+#endif
diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj
index eaedade..ddb89dc 100644
--- a/src/Tests/Tests.csproj
+++ b/src/Tests/Tests.csproj
@@ -1,30 +1,27 @@
-
- net462;net8
- Tests
- DbUp.Firebird.Tests
- true
-
- enable
- $(NoWarn);NETSDK1138
- latest
-
+
+ net462;net8
+ Tests
+ DbUp.Firebird.Tests
+
+ enable
+
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
-
-
-
-
-
diff --git a/src/dbup-firebird.sln b/src/dbup-firebird.sln
index 70826eb..b813ad0 100644
--- a/src/dbup-firebird.sln
+++ b/src/dbup-firebird.sln
@@ -25,6 +25,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{77157734-01D
dbup-firebird.sln.DotSettings = dbup-firebird.sln.DotSettings
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{E4279382-206F-4CB7-8B75-D8D7A501EF34}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -39,6 +41,10 @@ Global
{8CE634FE-6772-408E-9340-909F6218F8F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CE634FE-6772-408E-9340-909F6218F8F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CE634FE-6772-408E-9340-909F6218F8F7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4279382-206F-4CB7-8B75-D8D7A501EF34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4279382-206F-4CB7-8B75-D8D7A501EF34}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4279382-206F-4CB7-8B75-D8D7A501EF34}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4279382-206F-4CB7-8B75-D8D7A501EF34}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{62E5FE92-E288-4E09-964D-F92AF0E49131} = {5DA19CA9-8039-46D6-B474-021943582785}
diff --git a/src/dbup-firebird/FirebirdConnectionManager.cs b/src/dbup-firebird/FirebirdConnectionManager.cs
new file mode 100644
index 0000000..39f51fc
--- /dev/null
+++ b/src/dbup-firebird/FirebirdConnectionManager.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using DbUp.Engine.Transactions;
+using FirebirdSql.Data.FirebirdClient;
+
+namespace DbUp.Firebird
+{
+ ///
+ /// Manages Firebird database connections.
+ ///
+ public class FirebirdConnectionManager : DatabaseConnectionManager
+ {
+ ///
+ /// Creates a new Firebird database connection.
+ ///
+ /// The Firebird connection string.
+ public FirebirdConnectionManager(string connectionString) : base(new DelegateConnectionFactory(l => new FbConnection(connectionString)))
+ {
+ }
+
+ ///
+ /// Splits the statements in the script using the ";" character.
+ ///
+ /// The contents of the script to split.
+ public override IEnumerable SplitScriptIntoCommands(string scriptContents)
+ {
+ // TODO: Possible Change - this is the PostGres version
+ var scriptStatements =
+ Regex.Split(scriptContents, "^\\s*;\\s*$", RegexOptions.IgnoreCase | RegexOptions.Multiline)
+ .Select(x => x.Trim())
+ .Where(x => x.Length > 0)
+ .ToArray();
+
+ return scriptStatements;
+ }
+
+ protected override AllowedTransactionMode AllowedTransactionModes => AllowedTransactionMode.TransactionPerScript;
+ }
+}
diff --git a/src/dbup-firebird/FirebirdExtensions.cs b/src/dbup-firebird/FirebirdExtensions.cs
new file mode 100644
index 0000000..60481e5
--- /dev/null
+++ b/src/dbup-firebird/FirebirdExtensions.cs
@@ -0,0 +1,52 @@
+using DbUp.Builder;
+using DbUp.Engine.Transactions;
+using DbUp.Firebird;
+
+// ReSharper disable once CheckNamespace
+
+///
+/// Configuration extension methods for Firebird.
+///
+public static class FirebirdExtensions
+{
+ ///
+ /// Creates an upgrader for Firebird databases.
+ ///
+ /// Fluent helper type.
+ /// Firebird database connection string.
+ ///
+ /// A builder for a database upgrader designed for Firebird databases.
+ ///
+ public static UpgradeEngineBuilder FirebirdDatabase(this SupportedDatabases supported, string connectionString)
+ {
+ return FirebirdDatabase(new FirebirdConnectionManager(connectionString));
+ }
+
+ ///
+ /// Creates an upgrader for Firebird databases.
+ ///
+ /// Fluent helper type.
+ /// The to be used during a database upgrade.
+ ///
+ /// A builder for a database upgrader designed for Firebird databases.
+ ///
+ public static UpgradeEngineBuilder FirebirdDatabase(this SupportedDatabases supported, IConnectionManager connectionManager)
+ => FirebirdDatabase(connectionManager);
+
+ ///
+ /// Creates an upgrader for Firebird databases.
+ ///
+ /// The to be used during a database upgrade.
+ ///
+ /// A builder for a database upgrader designed for Firebird databases.
+ ///
+ public static UpgradeEngineBuilder FirebirdDatabase(IConnectionManager connectionManager)
+ {
+ var builder = new UpgradeEngineBuilder();
+ builder.Configure(c => c.ConnectionManager = connectionManager);
+ builder.Configure(c => c.ScriptExecutor = new FirebirdScriptExecutor(() => c.ConnectionManager, () => c.Log, null, () => c.VariablesEnabled, c.ScriptPreprocessors, () => c.Journal));
+ builder.Configure(c => c.Journal = new FirebirdTableJournal(() => c.ConnectionManager, () => c.Log, "schemaversions"));
+ builder.WithPreprocessor(new FirebirdPreprocessor());
+ return builder;
+ }
+}
\ No newline at end of file
diff --git a/src/dbup-firebird/FirebirdObjectParser.cs b/src/dbup-firebird/FirebirdObjectParser.cs
new file mode 100644
index 0000000..42e0ba5
--- /dev/null
+++ b/src/dbup-firebird/FirebirdObjectParser.cs
@@ -0,0 +1,14 @@
+using DbUp.Support;
+
+namespace DbUp.Firebird
+{
+ ///
+ /// Parses Sql Objects and performs quoting functions
+ ///
+ public class FirebirdObjectParser : SqlObjectParser
+ {
+ public FirebirdObjectParser() : base("\"", "\"")
+ {
+ }
+ }
+}
diff --git a/src/dbup-firebird/FirebirdPreprocessor.cs b/src/dbup-firebird/FirebirdPreprocessor.cs
new file mode 100644
index 0000000..48fdac6
--- /dev/null
+++ b/src/dbup-firebird/FirebirdPreprocessor.cs
@@ -0,0 +1,15 @@
+using DbUp.Engine;
+
+namespace DbUp.Firebird
+{
+ ///
+ /// This preprocessor makes adjustments to your sql to make it compatible with Firebird.
+ ///
+ public class FirebirdPreprocessor : IScriptPreprocessor
+ {
+ ///
+ /// Performs some preprocessing step on a Firebird script.
+ ///
+ public string Process(string contents) => contents;
+ }
+}
diff --git a/src/dbup-firebird/FirebirdScriptExecutor.cs b/src/dbup-firebird/FirebirdScriptExecutor.cs
new file mode 100644
index 0000000..b336e7d
--- /dev/null
+++ b/src/dbup-firebird/FirebirdScriptExecutor.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using DbUp.Engine;
+using DbUp.Engine.Output;
+using DbUp.Engine.Transactions;
+using DbUp.Support;
+using FirebirdSql.Data.FirebirdClient;
+
+namespace DbUp.Firebird
+{
+ ///
+ /// An implementation of that executes against a Firebird database.
+ ///
+ public class FirebirdScriptExecutor : ScriptExecutor
+ {
+ ///
+ /// Initializes an instance of the class.
+ ///
+ ///
+ /// The logging mechanism.
+ /// The schema that contains the table.
+ /// Function that returns true if variables should be replaced, false otherwise.
+ /// Script Preprocessors in addition to variable substitution
+ /// Database journal
+ public FirebirdScriptExecutor(Func connectionManagerFactory, Func log, string schema, Func variablesEnabled,
+ IEnumerable scriptPreprocessors, Func journal)
+ : base(connectionManagerFactory, new FirebirdObjectParser(), log, schema, variablesEnabled, scriptPreprocessors, journal)
+ {
+ }
+
+ protected override string GetVerifySchemaSql(string schema)
+ {
+ throw new NotSupportedException();
+ }
+
+ ///
+ /// We have to run the JournalTable creation and updating of the Journal table in different transactions.
+ /// See this: https://stackoverflow.com/questions/66537195/i-cant-run-inserts-in-firebird-2-5-table-unknown
+ ///
+ protected override bool UseTheSameTransactionForJournalTableAndScripts => false;
+
+ protected override void ExecuteCommandsWithinExceptionHandler(int index, SqlScript script, Action executeCommand)
+ {
+ try
+ {
+ executeCommand();
+ }
+ catch (FbException fbException)
+ {
+ Log().WriteInformation("Firebird exception has occured in script: '{0}'", script.Name);
+ Log().WriteError("Script block number: {0}; Firebird error code: {1}; SQLSTATE {2}; Message: {3}", index, fbException.ErrorCode, fbException.SQLSTATE, fbException.Message);
+ Log().WriteError(fbException.ToString());
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/dbup-firebird/FirebirdTableJournal.cs b/src/dbup-firebird/FirebirdTableJournal.cs
new file mode 100644
index 0000000..9bcb5e2
--- /dev/null
+++ b/src/dbup-firebird/FirebirdTableJournal.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Data;
+using DbUp.Engine;
+using DbUp.Engine.Output;
+using DbUp.Engine.Transactions;
+using DbUp.Support;
+
+namespace DbUp.Firebird
+{
+ ///
+ /// An implementation of the interface which tracks version numbers for a
+ /// Firebird database using a table called SchemaVersions.
+ ///
+ public class FirebirdTableJournal : TableJournal
+ {
+ ///
+ /// Creates a new Firebird table journal.
+ ///
+ /// The Firebird connection manager.
+ /// The upgrade logger.
+ /// The name of the journal table.
+ public FirebirdTableJournal(Func connectionManager, Func logger, string tableName)
+ : base(connectionManager, logger, new FirebirdObjectParser(), null, tableName)
+ {
+ }
+
+ static string CreateGeneratorSql(string tableName)
+ {
+ return $@"CREATE SEQUENCE {GeneratorName(tableName)}";
+ }
+
+ string CreateTriggerSql(string tableName)
+ {
+ return
+$@"CREATE TRIGGER {TriggerName(tableName)} FOR {FqSchemaTableName} ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
+ if (new.schemaversionsid is null or (new.schemaversionsid = 0)) then new.schemaversionsid = gen_id({GeneratorName(tableName)},1);
+END;";
+ }
+
+ static string GeneratorName(string tableName) => $"GEN_{tableName}ID";
+
+ static string TriggerName(string tableName) => $"BI_{tableName}ID";
+
+ void ExecuteCommand(Func dbCommandFactory, string sql)
+ {
+ using (var command = dbCommandFactory())
+ {
+ command.CommandText = sql;
+ command.CommandType = CommandType.Text;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ protected override void OnTableCreated(Func dbCommandFactory)
+ {
+ var unquotedTableName = UnquoteSqlObjectName(FqSchemaTableName);
+ ExecuteCommand(dbCommandFactory, CreateGeneratorSql(unquotedTableName));
+ Log().WriteInformation($"The {GeneratorName(unquotedTableName)} generator has been created");
+ ExecuteCommand(dbCommandFactory, CreateTriggerSql(unquotedTableName));
+ Log().WriteInformation($"The {TriggerName(unquotedTableName)} trigger has been created");
+ }
+
+ protected override string DoesTableExistSql()
+ {
+ return $"select 1 from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0 and RDB$RELATION_NAME = '{UnquotedSchemaTableName}'";
+ }
+
+ protected override string GetInsertJournalEntrySql(string @scriptName, string @applied)
+ {
+ return $"insert into {FqSchemaTableName} (ScriptName, Applied) values ({scriptName}, {applied})";
+ }
+
+ protected override string GetJournalEntriesSql()
+ {
+ return $"select ScriptName from {FqSchemaTableName} order by ScriptName";
+ }
+
+ protected override string CreateSchemaTableSql(string quotedPrimaryKeyName)
+ {
+ return
+$@"CREATE TABLE {FqSchemaTableName}
+(
+ schemaversionsid INTEGER NOT NULL,
+ scriptname VARCHAR(255) NOT NULL,
+ applied TIMESTAMP NOT NULL,
+ CONSTRAINT pk_{UnquotedSchemaTableName}_id PRIMARY KEY (schemaversionsid)
+)";
+ }
+ }
+}
diff --git a/src/dbup-firebird/Properties/AssemblyInfo.cs b/src/dbup-firebird/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..8293719
--- /dev/null
+++ b/src/dbup-firebird/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System;
+using System.Runtime.InteropServices;
+
+[assembly: ComVisible(false)]
+[assembly: CLSCompliant(true)]
+
diff --git a/src/dbup-firebird/dbup-firebird.csproj b/src/dbup-firebird/dbup-firebird.csproj
index 80b0075..f83dc8c 100644
--- a/src/dbup-firebird/dbup-firebird.csproj
+++ b/src/dbup-firebird/dbup-firebird.csproj
@@ -3,35 +3,26 @@
DbUp makes it easy to deploy and upgrade SQL Server databases. This package adds Firebird support.
DbUp Firebird Support
- netstandard1.3;netstandard2.0;net35;net45
+ DbUp Contributors
+ DbUp
+ Copyright © DbUp Contributors 2015
+ net462;netstandard2.0
dbup-firebird
DbUp.Firebird
+ dbup-firebird
../dbup.snk
true
https://github.com/DbUp/dbup-firebird.git
- dbup_firebird
- dbup-firebird
dbup-icon.png
-
-
-
- $(DefineConstants);NPGSQLv2
+ true
-
-
-
-
-
-
-
-
-
+
+
-
+
-