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

126 lines
5.1 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using NDB.Infrastructure.DatabaseMigration.Constants;
using NDB.Infrastructure.DatabaseMigration.Extensions;
using NDB.Infrastructure.DatabaseMigration.Models;
using NDB.Infrastructure.DatabaseMigration.Repositories;
using NDB.Infrastructure.DatabaseMigration.Services.Abstractions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace NDB.Infrastructure.DatabaseMigration.Services
{
internal class MigrationSignaturesService : IMigrationSignaturesService
{
private const string _migrationSignaturesFileName = "MigrationSignatures.xml";
private readonly string _migrationSignaturesFilePath;
private readonly ServiceConfiguration _configuration;
private readonly IServiceProvider _serviceProvider;
private MigrationThumbprint Thumbprint;
public MigrationSignaturesService(ServiceConfiguration configuration, IServiceProvider serviceProvider)
{
_migrationSignaturesFilePath = Path.Combine(configuration.Workspace, _migrationSignaturesFileName);
_configuration = configuration;
_serviceProvider = serviceProvider;
}
public async Task<MigrationSignature> GetLastMigrationSignature()
{
switch (_configuration.MetadataLocation)
{
case MetadataLocation.XmlFile:
return GetLastMigrationSignatureFromFile();
case MetadataLocation.Database:
return await GetLastMigrationSignatureFromDatabase();
default:
throw new NotImplementedException($"Metadata location {_configuration.MetadataLocation} is not implemented.");
}
}
public async Task SaveMigrationSignature(MigrationSignature migrationSignature)
{
switch (_configuration.MetadataLocation)
{
case MetadataLocation.XmlFile:
SaveMigrationSignatureToFile(migrationSignature);
break;
case MetadataLocation.Database:
await SaveMigrationSignatureToDatabase(migrationSignature);
break;
default:
throw new NotImplementedException($"Metadata location {_configuration.MetadataLocation} is not implemented.");
}
}
private MigrationSignature GetLastMigrationSignatureFromFile()
{
Thumbprint = GetMigrationThumbprintFromFile();
var lastSignature = Thumbprint?.MigrationSignatures?.OrderByDescending(z => z.MigrationDate).FirstOrDefault();
return lastSignature;
}
private MigrationThumbprint GetMigrationThumbprintFromFile()
{
if (!File.Exists(_migrationSignaturesFilePath))
return null;
var serializer = new XmlSerializer(typeof(MigrationThumbprint));
using (var reader = XmlReader.Create(_migrationSignaturesFilePath))
{
var migrationSignatureRoot = (MigrationThumbprint)serializer.Deserialize(reader);
return migrationSignatureRoot;
}
}
private void SaveMigrationSignatureToFile(MigrationSignature migrationSignature)
{
if (Thumbprint != null)
{
var migrationSignatures = new List<MigrationSignature>(Thumbprint.MigrationSignatures) { migrationSignature };
Thumbprint.MigrationSignatures = migrationSignatures.ToArray();
}
else
{
Thumbprint = new MigrationThumbprint()
{
MigrationSignatures = new List<MigrationSignature>() { migrationSignature }.ToArray()
};
}
var serializer = new XmlSerializer(Thumbprint.GetType());
var settings = new XmlWriterSettings() { Indent = true };
using (var writer = XmlWriter.Create(_migrationSignaturesFilePath, settings))
{
serializer.Serialize(writer, Thumbprint);
}
}
private async Task<MigrationSignature> GetLastMigrationSignatureFromDatabase()
{
using (var scope = _serviceProvider.CreateScope())
{
var _repository = scope.ServiceProvider.GetRequiredService<IMigrationRepository>();
var lastMigrationSignature = await _repository.GetLastMigrationSignature();
if (lastMigrationSignature == null)
return null;
return lastMigrationSignature.ToModel();
}
}
private async Task SaveMigrationSignatureToDatabase(MigrationSignature migrationSignature)
{
using (var scope = _serviceProvider.CreateScope())
{
var _repository = scope.ServiceProvider.GetRequiredService<IMigrationRepository>();
await _repository.AddMigrationSignature(migrationSignature.ToEntity());
}
}
}
}