netmash/infrastructure/NDB.Infrastructure.Database.../Services/MigrationService.cs

99 lines
4.1 KiB
C#
Raw Normal View History

2022-01-21 11:19:51 +02:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NDB.Infrastructure.DatabaseMigration.Models;
using NDB.Infrastructure.DatabaseMigration.Repositories;
using NDB.Infrastructure.DatabaseMigration.Services.Abstractions;
2022-01-21 11:19:51 +02:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
2022-01-22 01:54:19 +02:00
using System.Threading.Tasks;
2022-01-21 11:19:51 +02:00
namespace NDB.Infrastructure.DatabaseMigration.Services
{
internal class MigrationService : IMigrationService
{
private readonly ILogger<MigrationService> _logger;
private readonly IServiceProvider _serviceProvider;
private readonly ServiceConfiguration _configuration;
private readonly IMetadataLocationService _metadataLocationService;
private readonly IMigrationSignaturesService _migrationSignaturesService;
2022-01-21 11:19:51 +02:00
public MigrationService(ILogger<MigrationService> logger, IServiceProvider serviceProvider, ServiceConfiguration configuration, IMetadataLocationService metadataLocationService, IMigrationSignaturesService migrationSignaturesService)
2022-01-21 11:19:51 +02:00
{
_logger = logger;
_serviceProvider = serviceProvider;
_configuration = configuration;
_metadataLocationService = metadataLocationService;
_migrationSignaturesService = migrationSignaturesService;
2022-01-21 11:19:51 +02:00
}
public void Execute() => ExecuteAsync().GetAwaiter().GetResult();
2022-01-21 11:19:51 +02:00
private async Task ExecuteAsync()
2022-01-21 11:19:51 +02:00
{
_logger.LogInformation("Starting migration...");
await _metadataLocationService.Check();
2022-01-21 11:19:51 +02:00
var lastSignature = await _migrationSignaturesService.GetLastMigrationSignature();
var lastInstalledVersion = lastSignature?.LastVersion ?? "0.0.0";
2022-01-21 11:19:51 +02:00
var targetVersion = new Version(lastInstalledVersion);
var scriptPacks = GetScriptPacks();
var packsToInstall = scriptPacks.Where(p => p.Version > targetVersion);
if (!packsToInstall.Any())
{
_logger.LogInformation("Nothing to migrate.");
return;
}
var signature = new MigrationSignature() { MachineName = System.Environment.MachineName, MigrationDate = DateTime.Now };
var migratedVersions = new List<MigratedVersion>();
foreach (var pack in packsToInstall.OrderBy(p => p.Version))
{
var scripts = Directory.GetFiles(pack.Path);
if (!scripts.Any())
continue;
2022-02-18 23:46:43 +02:00
_logger.LogInformation($"Running script pack '{pack.Version}' with {scripts.Length} scripts:");
2022-01-21 11:19:51 +02:00
2022-02-19 00:14:37 +02:00
scripts = scripts.OrderBy(f => f).ToArray();
foreach (var script in scripts)
await RunScript(script);
2022-01-21 11:19:51 +02:00
var migratedVersion = new MigratedVersion() { Version = pack.Version.ToString(), Scripts = scripts.Select(z => Path.GetFileName(z)).ToArray() };
migratedVersions.Add(migratedVersion);
}
signature.MigratedVersions = migratedVersions.ToArray();
signature.LastVersion = packsToInstall.OrderByDescending(z => z.Version).First().Version.ToString();
await _migrationSignaturesService.SaveMigrationSignature(signature);
2022-01-21 11:19:51 +02:00
}
private ScriptPack[] GetScriptPacks()
{
var scripts = Directory.GetDirectories(_configuration.ScriptsDirectory);
var packs = scripts.Select(z => new ScriptPack() { Path = z, Version = new Version(new DirectoryInfo(z).Name) });
return packs.ToArray();
}
private async Task RunScript(string path)
2022-01-21 11:19:51 +02:00
{
_logger.LogInformation($"Running sql script: '{path}'");
var sqlContent = File.ReadAllText(path);
if (string.IsNullOrEmpty(sqlContent))
return;
using (var scope = _serviceProvider.CreateScope())
{
var _repository = scope.ServiceProvider.GetRequiredService<IMigrationRepository>();
2022-01-22 01:54:19 +02:00
await _repository.ExecuteSqlRaw(sqlContent);
2022-01-21 11:19:51 +02:00
}
}
}
}