using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Logging; using CredentialManager.Models; using DataConnection.Interfaces; using Data_Coupler.Services; namespace Data_Coupler.Pages; /// /// Partial class per la gestione di un database come destinazione dati. /// Consente di selezionare un database di destinazione, scoprirne le tabelle /// e configurare il mapping dei campi verso la tabella di destinazione. /// public partial class DataCoupler : ComponentBase { // ===== PROPRIETÀ TIPO DESTINAZIONE ===== /// /// Tipo di destinazione: "rest" (default) oppure "database". /// Controlla quale sezione UI viene mostrata nella card di destra. /// protected string selectedDestinationType = "rest"; // ===== PROPRIETÀ DATABASE DESTINAZIONE ===== /// Credenziale database selezionata come destinazione protected string selectedDestinationDatabaseCredential = ""; /// Stato connessione in corso protected bool isConnectingDestinationDatabase = false; /// Database di destinazione connesso con successo protected bool isDestinationDatabaseConnected = false; /// Messaggio di errore connessione database destinazione protected string destinationDatabaseErrorMessage = ""; /// Nomi delle tabelle disponibili nel database di destinazione protected List destAvailableTableNames = new(); /// Schema dettagliato per tabella di destinazione (caricato on-demand) protected Dictionary> destDatabaseTables = new(); /// Tabella di destinazione selezionata protected string selectedDestinationTable = ""; /// Termine di ricerca per filtrare le tabelle di destinazione protected string destDatabaseSearchTerm = ""; /// Database manager per il database di destinazione protected IDatabaseManager? currentDestinationDatabaseManager = null; // ===== METODI DATABASE DESTINAZIONE ===== /// /// Gestisce il cambio del tipo di destinazione (rest / database) /// protected void OnDestinationTypeChanged(ChangeEventArgs e) { var newType = e.Value?.ToString() ?? "rest"; if (newType == selectedDestinationType) return; selectedDestinationType = newType; // Reset lo stato della destinazione precedente ResetDestinationState(); if (newType == "database") { ResetDestinationDatabaseState(); } // Pulisce i mapping configurati (dipendono dal tipo di destinazione) ClearAllMappings(); StateHasChanged(); } /// /// Gestisce il cambio della credenziale database di destinazione /// protected void OnDestinationDatabaseCredentialChanged(ChangeEventArgs e) { selectedDestinationDatabaseCredential = e.Value?.ToString() ?? ""; ResetDestinationDatabaseState(); } /// /// Resetta lo stato del database di destinazione /// protected void ResetDestinationDatabaseState() { isDestinationDatabaseConnected = false; destAvailableTableNames.Clear(); destDatabaseTables.Clear(); selectedDestinationTable = ""; destDatabaseSearchTerm = ""; destinationDatabaseErrorMessage = ""; // Rilascia il database manager if (currentDestinationDatabaseManager != null) { try { currentDestinationDatabaseManager.Dispose(); } catch { /* ignore */ } currentDestinationDatabaseManager = null; } } /// /// Si connette al database di destinazione e carica le tabelle disponibili /// protected async Task ConnectToDestinationDatabase() { if (string.IsNullOrEmpty(selectedDestinationDatabaseCredential)) return; isConnectingDestinationDatabase = true; destinationDatabaseErrorMessage = ""; try { // Verifica credenziale var credential = databaseCredentials.FirstOrDefault(c => c.Name == selectedDestinationDatabaseCredential); if (credential == null) { destinationDatabaseErrorMessage = "Credenziale database non trovata"; return; } // Crea il database manager currentDestinationDatabaseManager = await ConnectionFactory.CreateDatabaseManagerAsync(selectedDestinationDatabaseCredential); // Verifica la connessione var canConnect = await currentDestinationDatabaseManager.TestConnectionAsync(); if (!canConnect) { destinationDatabaseErrorMessage = "Impossibile connettersi al database di destinazione. Verificare le credenziali."; currentDestinationDatabaseManager.Dispose(); currentDestinationDatabaseManager = null; return; } // Carica i nomi delle tabelle var tableNames = await currentDestinationDatabaseManager.GetTableNamesAsync(); destAvailableTableNames = tableNames.OrderBy(t => t).ToList(); isDestinationDatabaseConnected = true; Logger.LogInformation("Database destinazione connesso: {Credential}, {Count} tabelle trovate", selectedDestinationDatabaseCredential, destAvailableTableNames.Count); } catch (Exception ex) { destinationDatabaseErrorMessage = $"Errore di connessione: {ex.Message}"; Logger.LogError(ex, "Errore nella connessione al database destinazione: {Credential}", selectedDestinationDatabaseCredential); if (currentDestinationDatabaseManager != null) { try { currentDestinationDatabaseManager.Dispose(); } catch { /* ignore */ } currentDestinationDatabaseManager = null; } } finally { isConnectingDestinationDatabase = false; StateHasChanged(); } } /// /// Seleziona la tabella di destinazione e carica il suo schema /// protected async Task SelectDestinationTable(string tableName) { selectedDestinationTable = tableName; // Carica lo schema della tabella se non è già disponibile if (currentDestinationDatabaseManager != null && !destDatabaseTables.ContainsKey(tableName)) { try { Logger.LogInformation("Caricamento schema tabella destinazione: {TableName}", tableName); var schema = await currentDestinationDatabaseManager.GetTableSchemaAsync(tableName); destDatabaseTables[tableName] = schema; Logger.LogInformation("Schema tabella destinazione caricato: {ColumnCount} colonne", schema.Count()); } catch (Exception ex) { Logger.LogError(ex, "Errore nel caricamento schema tabella destinazione {TableName}", tableName); destinationDatabaseErrorMessage = $"Errore nel caricamento schema: {ex.Message}"; } } // Pulisce i mapping quando si cambia tabella ClearAllMappings(); StateHasChanged(); } /// /// Restituisce la lista filtrata delle tabelle di destinazione /// protected IEnumerable GetFilteredDestinationTables() { if (string.IsNullOrEmpty(destDatabaseSearchTerm)) return destAvailableTableNames; return destAvailableTableNames .Where(t => t.Contains(destDatabaseSearchTerm, StringComparison.OrdinalIgnoreCase)); } /// /// Aggiorna il termine di ricerca per le tabelle di destinazione /// protected void FilterDestinationTables(ChangeEventArgs e) { destDatabaseSearchTerm = e.Value?.ToString() ?? ""; StateHasChanged(); } /// /// Pulisce il termine di ricerca per le tabelle di destinazione /// protected void ClearDestinationTableSearch() { destDatabaseSearchTerm = ""; StateHasChanged(); } /// /// Indica se la configurazione corrente è pronta per il trasferimento verso database /// protected bool IsDestinationDatabaseReady => isDestinationDatabaseConnected && !string.IsNullOrEmpty(selectedDestinationTable) && currentDestinationDatabaseManager != null; }