feat: import messages from go version
This commit is contained in:
parent
b56a71e105
commit
a50a8567dd
15 changed files with 503 additions and 769 deletions
|
|
@ -19,6 +19,9 @@ using NodaTime;
|
|||
|
||||
namespace Catalogger.Backend.Database;
|
||||
|
||||
/// <summary>
|
||||
/// Manages database migrations.
|
||||
/// </summary>
|
||||
public class DatabaseMigrator(ILogger logger, IClock clock, DatabaseConnection conn)
|
||||
: IDisposable,
|
||||
IAsyncDisposable
|
||||
|
|
@ -26,7 +29,10 @@ public class DatabaseMigrator(ILogger logger, IClock clock, DatabaseConnection c
|
|||
private const string RootPath = "Catalogger.Backend.Database";
|
||||
private static readonly int MigrationsPathLength = $"{RootPath}.Migrations.".Length;
|
||||
|
||||
public async Task Migrate()
|
||||
/// <summary>
|
||||
/// Migrates the database to the latest version.
|
||||
/// </summary>
|
||||
public async Task MigrateUp()
|
||||
{
|
||||
var migrations = GetMigrationNames().ToArray();
|
||||
logger.Debug("Getting current database migration");
|
||||
|
|
@ -65,6 +71,43 @@ public class DatabaseMigrator(ILogger logger, IClock clock, DatabaseConnection c
|
|||
await tx.CommitAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Migrates the database to a previous version.
|
||||
/// </summary>
|
||||
/// <param name="count">The number of migrations to revert. If higher than the number of applied migrations,
|
||||
/// reverts the database to a clean slate.</param>
|
||||
public async Task MigrateDown(int count = 1)
|
||||
{
|
||||
await using var tx = await conn.BeginTransactionAsync();
|
||||
|
||||
var migrationCount = 0;
|
||||
var totalStartTime = clock.GetCurrentInstant();
|
||||
for (var i = count; i > 0; i--)
|
||||
{
|
||||
var migration = await GetCurrentMigration();
|
||||
if (migration == null)
|
||||
{
|
||||
logger.Information(
|
||||
"More down migrations requested than were in the database, finishing early"
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
logger.Debug("Reverting migration {Migration}", migration);
|
||||
var startTime = clock.GetCurrentInstant();
|
||||
await ExecuteMigration(tx, migration.MigrationName, up: false);
|
||||
var took = clock.GetCurrentInstant() - startTime;
|
||||
logger.Debug("Reverted migration {Migration} in {Took}", migration, took);
|
||||
migrationCount++;
|
||||
}
|
||||
|
||||
var totalTook = clock.GetCurrentInstant() - totalStartTime;
|
||||
logger.Information("Reverted {Count} migrations in {Took}", migrationCount, totalTook);
|
||||
|
||||
// Finally, commit the transaction
|
||||
await tx.CommitAsync();
|
||||
}
|
||||
|
||||
private async Task ExecuteMigration(DbTransaction tx, string migrationName, bool up = true)
|
||||
{
|
||||
var query = await GetResource(
|
||||
|
|
@ -73,11 +116,17 @@ public class DatabaseMigrator(ILogger logger, IClock clock, DatabaseConnection c
|
|||
|
||||
// Run the migration
|
||||
await conn.ExecuteAsync(query, transaction: tx);
|
||||
// Store that we ran the migration
|
||||
await conn.ExecuteAsync(
|
||||
"INSERT INTO migrations (migration_name, applied_at) VALUES (@MigrationName, @AppliedAt)",
|
||||
new { MigrationName = migrationName, AppliedAt = clock.GetCurrentInstant() }
|
||||
);
|
||||
// Store that we ran the migration (or reverted it)
|
||||
if (up)
|
||||
await conn.ExecuteAsync(
|
||||
"INSERT INTO migrations (migration_name, applied_at) VALUES (@MigrationName, now())",
|
||||
new { MigrationName = migrationName }
|
||||
);
|
||||
else
|
||||
await conn.ExecuteAsync(
|
||||
"DELETE FROM migrations WHERE migration_name = @MigrationName",
|
||||
new { MigrationName = migrationName }
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the current migration. If no migrations have been applied, returns null
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue