- Created expected JSON files for Go modules and workspaces. - Added go.mod and go.sum files for example projects. - Implemented private module structure with expected JSON output. - Introduced vendored dependencies with corresponding expected JSON. - Developed PostgresGraphJobStore for managing graph jobs. - Established SQL migration scripts for graph jobs schema. - Implemented GraphJobRepository for CRUD operations on graph jobs. - Created IGraphJobRepository interface for repository abstraction. - Added unit tests for GraphJobRepository to ensure functionality.
124 lines
4.3 KiB
C#
124 lines
4.3 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
using StellaOps.Infrastructure.Postgres.Migrations;
|
|
|
|
namespace StellaOps.Cli.Services;
|
|
|
|
/// <summary>
|
|
/// Helper for running, verifying, and querying PostgreSQL migrations from the CLI.
|
|
/// </summary>
|
|
internal sealed class MigrationCommandService
|
|
{
|
|
private readonly IConfiguration _configuration;
|
|
private readonly ILoggerFactory _loggerFactory;
|
|
|
|
public MigrationCommandService(IConfiguration configuration, ILoggerFactory loggerFactory)
|
|
{
|
|
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
|
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
|
|
}
|
|
|
|
public Task<MigrationResult> RunAsync(
|
|
MigrationModuleInfo module,
|
|
string? connectionOverride,
|
|
MigrationCategory? category,
|
|
bool dryRun,
|
|
int? timeoutSeconds,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var connectionString = ResolveConnectionString(module, connectionOverride);
|
|
var runner = CreateRunner(module, connectionString);
|
|
|
|
var options = new MigrationRunOptions
|
|
{
|
|
CategoryFilter = category,
|
|
DryRun = dryRun,
|
|
TimeoutSeconds = timeoutSeconds.GetValueOrDefault(300),
|
|
ValidateChecksums = true,
|
|
FailOnChecksumMismatch = true
|
|
};
|
|
|
|
return runner.RunFromAssemblyAsync(module.MigrationsAssembly, module.ResourcePrefix, options, cancellationToken);
|
|
}
|
|
|
|
public async Task<MigrationStatus> GetStatusAsync(
|
|
MigrationModuleInfo module,
|
|
string? connectionOverride,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var connectionString = ResolveConnectionString(module, connectionOverride);
|
|
var logger = _loggerFactory.CreateLogger($"migrationstatus.{module.Name}");
|
|
var statusService = new MigrationStatusService(
|
|
connectionString,
|
|
module.SchemaName,
|
|
module.Name,
|
|
module.MigrationsAssembly,
|
|
logger);
|
|
|
|
return await statusService.GetStatusAsync(cancellationToken).ConfigureAwait(false);
|
|
}
|
|
|
|
public Task<IReadOnlyList<string>> VerifyAsync(
|
|
MigrationModuleInfo module,
|
|
string? connectionOverride,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var connectionString = ResolveConnectionString(module, connectionOverride);
|
|
var runner = CreateRunner(module, connectionString);
|
|
return runner.ValidateChecksumsAsync(module.MigrationsAssembly, module.ResourcePrefix, cancellationToken);
|
|
}
|
|
|
|
private MigrationRunner CreateRunner(MigrationModuleInfo module, string connectionString) =>
|
|
new(connectionString, module.SchemaName, module.Name, _loggerFactory.CreateLogger($"migration.{module.Name}"));
|
|
|
|
private string ResolveConnectionString(MigrationModuleInfo module, string? connectionOverride)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(connectionOverride))
|
|
{
|
|
return connectionOverride;
|
|
}
|
|
|
|
var envCandidates = new[]
|
|
{
|
|
$"STELLAOPS_POSTGRES_{module.Name.ToUpperInvariant()}_CONNECTION",
|
|
$"STELLAOPS_POSTGRES_{module.SchemaName.ToUpperInvariant()}_CONNECTION",
|
|
"STELLAOPS_POSTGRES_CONNECTION",
|
|
"STELLAOPS_DB_CONNECTION"
|
|
};
|
|
|
|
foreach (var key in envCandidates)
|
|
{
|
|
var value = Environment.GetEnvironmentVariable(key);
|
|
if (!string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return value;
|
|
}
|
|
}
|
|
|
|
var configCandidates = new[]
|
|
{
|
|
$"StellaOps:Database:{module.Name}:ConnectionString",
|
|
$"Database:{module.Name}:ConnectionString",
|
|
$"StellaOps:Postgres:ConnectionString",
|
|
$"Postgres:ConnectionString",
|
|
"Database:ConnectionString"
|
|
};
|
|
|
|
foreach (var key in configCandidates)
|
|
{
|
|
var value = _configuration[key];
|
|
if (!string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return value;
|
|
}
|
|
}
|
|
|
|
throw new InvalidOperationException(
|
|
$"No PostgreSQL connection string found for module '{module.Name}'. " +
|
|
"Provide --connection or set STELLAOPS_POSTGRES_CONNECTION.");
|
|
}
|
|
}
|