1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-03 14:03:33 +01:00

Add variable for production migration transaction level (#4702)

* Addd variable for production migration transaction level

* Added variable for production migration transaction level with default value

* Clean up comments

* Removed uneeded directive

* Changed time format for timeout on migration

* white space formatting

* white space formatting again

* white space formatting once again

* white space formatting once again

* clean up

* CHnaged to builder.WithoutTransaction()

* Changed to optyion flag from n to nt for notransaction

* Changed to optyion flag from n to no-transaction for  without transaction

* Change desription of option

---------

Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
(cherry picked from commit b38b537ed1)
This commit is contained in:
rkac-bw 2024-10-09 08:48:19 -06:00 committed by Vince Grassia
parent d22b5e84d9
commit ad8aec9756
No known key found for this signature in database
GPG Key ID: 9AD7505E8448CC08
2 changed files with 27 additions and 11 deletions

View File

@ -14,13 +14,15 @@ public class DbMigrator
private readonly string _connectionString; private readonly string _connectionString;
private readonly ILogger<DbMigrator> _logger; private readonly ILogger<DbMigrator> _logger;
private readonly bool _skipDatabasePreparation; private readonly bool _skipDatabasePreparation;
private readonly bool _noTransactionMigration;
public DbMigrator(string connectionString, ILogger<DbMigrator> logger = null, public DbMigrator(string connectionString, ILogger<DbMigrator> logger = null,
bool skipDatabasePreparation = false) bool skipDatabasePreparation = false, bool noTransactionMigration = false)
{ {
_connectionString = connectionString; _connectionString = connectionString;
_logger = logger ?? CreateLogger(); _logger = logger ?? CreateLogger();
_skipDatabasePreparation = skipDatabasePreparation; _skipDatabasePreparation = skipDatabasePreparation;
_noTransactionMigration = noTransactionMigration;
} }
public bool MigrateMsSqlDatabaseWithRetries(bool enableLogging = true, public bool MigrateMsSqlDatabaseWithRetries(bool enableLogging = true,
@ -30,6 +32,7 @@ public class DbMigrator
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var attempt = 1; var attempt = 1;
while (attempt < 10) while (attempt < 10)
{ {
try try
@ -69,6 +72,7 @@ public class DbMigrator
using (var connection = new SqlConnection(masterConnectionString)) using (var connection = new SqlConnection(masterConnectionString))
{ {
var databaseName = new SqlConnectionStringBuilder(_connectionString).InitialCatalog; var databaseName = new SqlConnectionStringBuilder(_connectionString).InitialCatalog;
if (string.IsNullOrWhiteSpace(databaseName)) if (string.IsNullOrWhiteSpace(databaseName))
{ {
databaseName = "vault"; databaseName = "vault";
@ -121,8 +125,17 @@ public class DbMigrator
.SqlDatabase(_connectionString) .SqlDatabase(_connectionString)
.WithScriptsAndCodeEmbeddedInAssembly(Assembly.GetExecutingAssembly(), .WithScriptsAndCodeEmbeddedInAssembly(Assembly.GetExecutingAssembly(),
s => s.Contains($".{folderName}.") && !s.Contains(".Archive.")) s => s.Contains($".{folderName}.") && !s.Contains(".Archive."))
.WithTransaction() .WithExecutionTimeout(TimeSpan.FromMinutes(5));
.WithExecutionTimeout(new TimeSpan(0, 5, 0));
if (_noTransactionMigration)
{
builder = builder.WithoutTransaction()
.WithExecutionTimeout(TimeSpan.FromMinutes(60));
}
else
{
builder = builder.WithTransaction();
}
if (repeatable) if (repeatable)
{ {
@ -144,6 +157,7 @@ public class DbMigrator
{ {
var scriptsToExec = upgrader.GetScriptsToExecute(); var scriptsToExec = upgrader.GetScriptsToExecute();
var stringBuilder = new StringBuilder("Scripts that will be applied:"); var stringBuilder = new StringBuilder("Scripts that will be applied:");
foreach (var script in scriptsToExec) foreach (var script in scriptsToExec)
{ {
stringBuilder.AppendLine(script.Name); stringBuilder.AppendLine(script.Name);

View File

@ -17,13 +17,15 @@ internal class Program
[Option('f', "folder", Description = "Folder name of database scripts")] [Option('f', "folder", Description = "Folder name of database scripts")]
string folderName = MigratorConstants.DefaultMigrationsFolderName, string folderName = MigratorConstants.DefaultMigrationsFolderName,
[Option('d', "dry-run", Description = "Print the scripts that will be applied without actually executing them")] [Option('d', "dry-run", Description = "Print the scripts that will be applied without actually executing them")]
bool dryRun = false bool dryRun = false,
) => MigrateDatabase(databaseConnectionString, repeatable, folderName, dryRun); [Option("no-transaction", Description = "Run without adding transaction per script or all scripts")]
bool noTransactionMigration = false
) => MigrateDatabase(databaseConnectionString, repeatable, folderName, dryRun, noTransactionMigration);
private static bool MigrateDatabase(string databaseConnectionString, private static bool MigrateDatabase(string databaseConnectionString,
bool repeatable = false, string folderName = "", bool dryRun = false) bool repeatable = false, string folderName = "", bool dryRun = false, bool noTransactionMigration = false)
{ {
var migrator = new DbMigrator(databaseConnectionString); var migrator = new DbMigrator(databaseConnectionString, noTransactionMigration: noTransactionMigration);
bool success; bool success;
if (!string.IsNullOrWhiteSpace(folderName)) if (!string.IsNullOrWhiteSpace(folderName))
{ {