using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NDB.Infrastructure.DatabaseMigration.Constants; using NDB.Infrastructure.DatabaseMigration.Models; using NDB.Infrastructure.DatabaseMigration.Repositories; using NDB.Infrastructure.DatabaseMigration.Services.Abstractions; using System; using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; namespace NDB.Infrastructure.DatabaseMigration.Services { internal class MetadataLocationService : IMetadataLocationService { private readonly ServiceConfiguration _configuration; private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; public MetadataLocationService(ServiceConfiguration configuration, IServiceProvider serviceProvider, ILogger logger) { _configuration=configuration; _serviceProvider=serviceProvider; _logger=logger; } public async Task Check() { switch (_configuration.MetadataLocation) { case MetadataLocation.XmlFile: CheckWorkspace(); break; case MetadataLocation.Database: await CheckMigrationTables(); break; default: throw new NotImplementedException($"Metadata location {_configuration.MetadataLocation} is not implemented."); } } private void CheckWorkspace() { if (string.IsNullOrEmpty(_configuration.Workspace)) throw new Exception($"Workspace path is empty! Check 'Workspace' parameter."); if (!Directory.Exists(_configuration.Workspace)) Directory.CreateDirectory(_configuration.Workspace); } private async Task CheckMigrationTables() { using (var scope = _serviceProvider.CreateScope()) { var _repository = scope.ServiceProvider.GetRequiredService(); var migrationTablesAreSet = await _repository.MigrationTablesAreSet(_configuration.DatabaseType); if (migrationTablesAreSet) return; var assembly = Assembly.GetExecutingAssembly(); var allEmbeddedResources = assembly.GetManifestResourceNames(); var sqlResources = GetSqlResources(); foreach (var resource in sqlResources) { if (!allEmbeddedResources.Contains(resource)) { _logger.LogWarning($"Manifest resource {resource} does not exists in assembly {assembly.FullName} and will be ignored."); continue; } var resourceContent = GetManifestResourceContent(assembly, resource); await _repository.ExecuteSqlRaw(resourceContent); } } } private string[] GetSqlResources() { var result = _configuration.DatabaseType switch { DatabaseType.SQLServer => ManifestResources.SqlServer.Select(resource => $"{ManifestResourcesPath.SqlServer}{resource}"), DatabaseType.SQLite => ManifestResources.Sqlite.Select(resource => $"{ManifestResourcesPath.Sqlite}{resource}"), _ => throw new NotImplementedException($"DatabaseMigration type {_configuration.DatabaseType} is not implemented"), }; return result.ToArray(); } private string GetManifestResourceContent(Assembly assembly, string resourceName) { using (Stream stream = assembly.GetManifestResourceStream(resourceName)) using (StreamReader reader = new StreamReader(stream)) { string result = reader.ReadToEnd(); return result; } } } }