1- using DbUp . Builder ;
1+ using System ;
2+ using System . IO ;
3+ using DbUp ;
4+ using DbUp . Builder ;
5+ using DbUp . Engine . Output ;
26using DbUp . Engine . Transactions ;
37using 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