feat: Corregge la logica di rilevamento database specificato nella connection string

- Modifica IsDatabaseSpecifiedInConnectionString per verificare prima il campo DatabaseName della credenziale
- Aggiunge logging dettagliato per debugging del processo di connessione database
- Corregge il flusso di connessione per evitare il modale quando il database è già specificato
- Migliora la gestione degli errori nel caricamento tabelle dal database specificato
- Rimuove codice non raggiungibile nella logica di connessione database

Il bug precedente mostrava sempre il modale di selezione database anche quando
il database era specificato nel campo DatabaseName della credenziale, ora la
verifica segue la logica corretta:
1. Controlla se DatabaseName è valorizzato nella credenziale
2. Solo se vuoto, verifica i parametri Database=/Initial Catalog= nella connection string
This commit is contained in:
Alessio Dal Santo
2025-07-02 15:32:11 +02:00
parent 61883c3467
commit 77efe986a0
7 changed files with 728 additions and 337 deletions
+60 -59
View File
@@ -234,11 +234,11 @@
}
</div>
}
else if (databaseTables.Any())
else if (availableTableNames.Any())
{
<!-- Sezione Tabelle (modalità standard) -->
<div class="mb-3">
<h6>Tabelle Database (@databaseTables.Count disponibili):</h6>
<h6>Tabelle Database (@availableTableNames.Count disponibili):</h6>
<!-- Campo di ricerca -->
<div class="mb-2">
@@ -1131,7 +1131,7 @@
<div class="col-12">
<ProfileSaver CanSave="CanSaveProfile()"
SourceType="selectedSourceType"
SourceSchema="@(databaseTables.Keys.FirstOrDefault()?.Split('.').FirstOrDefault())"
SourceSchema="@(availableTableNames.FirstOrDefault()?.Split('.').FirstOrDefault())"
SourceTable="selectedTable"
DestinationType="rest"
DestinationEndpoint="@(selectedRestEntity?.Name)"
@@ -1149,62 +1149,6 @@
OnProfileDeleted="OnProfileDeleted"
IsLoading="isLoadingProfiles" />
<!-- Modal per la selezione del database -->
@if (showDatabaseSelectionModal)
{
<div class="modal fade show d-block" style="background-color: rgba(0,0,0,0.5);">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-database"></i> Seleziona Database
</h5>
</div>
<div class="modal-body">
<p class="text-muted">
<i class="fas fa-info-circle"></i>
Sono stati trovati più database nel server. Seleziona il database da utilizzare:
</p>
@if (availableDatabases != null && availableDatabases.Any())
{
<div class="mb-3">
<label for="databaseSelect" class="form-label">Database disponibili:</label>
<select id="databaseSelect" class="form-select" @bind="selectedDatabase">
<option value="">-- Seleziona un database --</option>
@foreach (var db in availableDatabases)
{
<option value="@db">@db</option>
}
</select>
<small class="form-text text-muted">
<i class="fas fa-lightbulb"></i>
Il database determina quali tabelle e viste saranno disponibili per il mapping.
</small>
</div>
}
else
{
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle"></i>
Nessun database trovato o errore nel caricamento.
</div>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @onclick="CancelDatabaseSelection">
<i class="fas fa-times"></i> Annulla
</button>
<button type="button" class="btn btn-primary" @onclick="OnDatabaseSelected"
disabled="@string.IsNullOrEmpty(selectedDatabase)">
<i class="fas fa-check"></i> Connetti al Database
</button>
</div>
</div>
</div>
</div>
}
<!-- Modal per la selezione dello schema -->
@if (showSchemaSelectionModal)
{
@@ -1267,3 +1211,60 @@
</div>
</div>
}
<!-- Modal per la selezione del database -->
@if (showDatabaseSelectionModal)
{
<div class="modal fade show d-block" style="background-color: rgba(0,0,0,0.5);">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-database"></i> Seleziona Database
</h5>
</div>
<div class="modal-body">
<p class="text-muted">
<i class="fas fa-info-circle"></i>
La connessione non specifica un database. Seleziona il database da esplorare:
</p>
@if (isLoadingDatabases)
{
<div class="text-center">
<div class="spinner-border spinner-border-sm me-2"></div>
Caricamento database...
</div>
}
else if (availableDatabases != null && availableDatabases.Any())
{
<div class="mb-3">
<label for="databaseSelect" class="form-label">Database disponibili:</label>
<select id="databaseSelect" class="form-select" @bind="selectedDatabase">
<option value="">-- Seleziona un database --</option>
@foreach (var db in availableDatabases)
{
<option value="@db">@db</option>
}
</select>
</div>
}
else
{
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle"></i>
Nessun database trovato o errore nel caricamento.
</div>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @onclick="CancelDatabaseSelection">
<i class="fas fa-times"></i> Annulla
</button>
<button type="button" class="btn btn-primary" @onclick="OnDatabaseSelected" disabled="@string.IsNullOrEmpty(selectedDatabase)">
<i class="fas fa-check"></i> Connetti con Database
</button>
</div>
</div>
</div>
</div>
}
+301 -234
View File
@@ -57,19 +57,21 @@ public partial class DataCoupler : ComponentBase
private string restErrorMessage = "";
// Database discovery
private Dictionary<string, IEnumerable<DbColumnInfo>> databaseTables = new();
private List<string> availableTableNames = new(); // Solo nomi delle tabelle
private Dictionary<string, IEnumerable<DbColumnInfo>> databaseTables = new(); // Schema dettagliato per tabelle caricate
private string selectedTable = "";
private string databaseSearchTerm = "";
// Database selection
// Database selection - per gestire la selezione del database quando non specificato nella connection string
private List<string> availableDatabases = new();
private List<string> availableSchemas = new();
private string selectedDatabase = "";
private string selectedSchema = "";
private bool showDatabaseSelection = false;
private bool showDatabaseSelectionModal = false;
private bool showSchemaSelectionModal = false;
private bool isLoadingDatabases = false;
// Database selection (schemas only)
private List<string> availableSchemas = new();
private string selectedSchema = "";
private bool showSchemaSelectionModal = false;
private bool isLoadingSchemas = false;
// Custom query functionality
@@ -110,7 +112,6 @@ public partial class DataCoupler : ComponentBase
private string sourceKeyField = ""; // Campo che identifica univocamente il record sorgente
private string suggestedPrimaryKey = ""; // Campo PK suggerito per database
private bool requiresManualKeySelection = false; // Flag per indicare se è richiesta selezione manuale
private Dictionary<string, string> sourceKeyMappings = new(); // Per CSV: mapppatura colonna -> nome campo chiave
private bool useRecordAssociations = true; // Se utilizzare il sistema di associazioni
// Trasferimento dati
@@ -745,6 +746,12 @@ public partial class DataCoupler : ComponentBase
databaseSearchTerm = "";
databaseErrorMessage = "";
// Reset database selection
availableDatabases.Clear();
selectedDatabase = "";
showDatabaseSelectionModal = false;
isLoadingDatabases = false;
// Reset custom query state
useCustomQuery = false;
customQuery = "";
@@ -774,7 +781,7 @@ public partial class DataCoupler : ComponentBase
// Clear mappings when resetting REST state
ClearAllMappings();
}private async Task ConnectToDatabase()
} private async Task ConnectToDatabase()
{
if (string.IsNullOrEmpty(selectedDatabaseCredential))
return;
@@ -783,7 +790,8 @@ public partial class DataCoupler : ComponentBase
databaseErrorMessage = "";
try
{ // Trova la credenziale
{
// Trova la credenziale
var credential = databaseCredentials.FirstOrDefault(c => c.Name == selectedDatabaseCredential);
if (credential == null)
{
@@ -797,42 +805,51 @@ public partial class DataCoupler : ComponentBase
{
databaseErrorMessage = $"Connessione fallita: {message}";
return;
} // Crea il database manager usando il factory con le credenziali complete
}
// Crea il database manager usando il factory con le credenziali complete
Logger.LogInformation("Creando database manager per credenziale: {CredentialName}", selectedDatabaseCredential);
currentDatabaseManager = await ConnectionFactory.CreateDatabaseManagerAsync(selectedDatabaseCredential);
Logger.LogInformation("Database manager creato con successo");
Logger.LogInformation("Iniziando discovery dello schema per database {DatabaseType} con credenziale: {CredentialName}", credential.DatabaseType, selectedDatabaseCredential);
// Discovery dello schema con try-catch specifico
try
// Verifica se il database è specificato nella connection string
bool isDatabaseSpecified = await IsDatabaseSpecifiedInConnectionString(credential);
if (isDatabaseSpecified)
{
var schema = await currentDatabaseManager.GetDatabaseSchemaAsync();
Logger.LogInformation("Schema discovery completato. Tipo restituito: {SchemaType}, Numero elementi: {Count}",
schema?.GetType().Name ?? "null",
schema?.Count() ?? 0);
databaseTables = schema as Dictionary<string, IEnumerable<DbColumnInfo>> ??
(schema != null ? new Dictionary<string, IEnumerable<DbColumnInfo>>(schema) : new Dictionary<string, IEnumerable<DbColumnInfo>>());
Logger.LogInformation("Database tables dopo conversione: {Count} tabelle", databaseTables.Count);
if (databaseTables.Count == 0)
Logger.LogInformation("Database specificato nella connection string. Procedendo con discovery tabelle.");
try
{
// Se non ci sono tabelle, potrebbe essere perché non è stato selezionato un database specifico
HandleDatabaseSelectionRequired();
await LoadTablesFromConnectedDatabase();
isDatabaseConnected = true;
Logger.LogInformation("Tabelle caricate con successo, database connesso");
return; // Importante: usciamo qui se tutto va bene
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nel caricamento tabelle dal database specificato");
databaseErrorMessage = $"Errore nel caricamento tabelle: {ex.Message}";
return;
}
}
catch (Exception schemaEx)
else
{
Logger.LogError(schemaEx, "Errore specifico durante lo schema discovery");
databaseErrorMessage = $"Errore nello schema discovery: {schemaEx.Message}";
throw;
Logger.LogInformation("Database non specificato nella connection string. Caricando database disponibili.");
await LoadAvailableDatabases();
if (availableDatabases.Any())
{
Logger.LogInformation("Trovati {DatabaseCount} database disponibili", availableDatabases.Count);
showDatabaseSelectionModal = true;
StateHasChanged();
return; // Non procediamo fino alla selezione del database
}
else
{
databaseErrorMessage = "Nessun database disponibile trovato";
return;
}
}
isDatabaseConnected = true;
}
catch (Exception ex)
{
@@ -842,8 +859,9 @@ public partial class DataCoupler : ComponentBase
finally
{
isConnectingDatabase = false;
StateHasChanged();
}
} private async Task ConnectToRestApi()
}private async Task ConnectToRestApi()
{
if (string.IsNullOrEmpty(selectedRestCredential))
return;
@@ -926,6 +944,21 @@ public partial class DataCoupler : ComponentBase
suggestedPrimaryKey = "";
requiresManualKeySelection = false;
// Carica i dettagli della tabella se non sono già stati caricati
if (!databaseTables.ContainsKey(tableName) && currentDatabaseManager != null)
{
try
{
var tableSchema = await currentDatabaseManager.GetTableSchemaAsync(tableName);
databaseTables[tableName] = tableSchema;
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nel caricamento dello schema della tabella {TableName}", tableName);
databaseErrorMessage = $"Errore nel caricamento della tabella: {ex.Message}";
}
}
// If it's a database source, try to detect the primary key
if (selectedSourceType == "database" && currentDatabaseManager != null)
{
@@ -987,9 +1020,9 @@ public partial class DataCoupler : ComponentBase
private IEnumerable<string> GetFilteredDatabaseTables()
{
if (string.IsNullOrEmpty(databaseSearchTerm))
return databaseTables.Keys;
return availableTableNames;
return databaseTables.Keys.Where(table =>
return availableTableNames.Where(table =>
table.Contains(databaseSearchTerm, StringComparison.OrdinalIgnoreCase));
}
@@ -1864,7 +1897,8 @@ public partial class DataCoupler : ComponentBase
if (databaseTables.Count == 0)
{
// Se non ci sono tabelle, potrebbe essere necessario selezionare un database specifico
HandleDatabaseSelectionRequired();
// Schema discovery completato senza successo
databaseErrorMessage = "Impossibile rilevare le tabelle del database. Verificare le credenziali di connessione.";
}
else
{
@@ -1923,50 +1957,6 @@ public partial class DataCoupler : ComponentBase
}
}
/// <summary>
/// Gestisce la situazione quando è richiesta la selezione di un database o schema specifico
/// </summary>
private async void HandleDatabaseSelectionRequired()
{
try
{
Logger.LogInformation("Schema discovery non ha restituito risultati. Tentativo di scoprire database disponibili...");
// Prima prova a ottenere la lista dei database disponibili
await LoadAvailableDatabases();
if (availableDatabases.Any())
{
// Se abbiamo database disponibili, mostra il modal per la selezione del database
Logger.LogInformation("Trovati {DatabaseCount} database disponibili", availableDatabases.Count);
showDatabaseSelectionModal = true;
StateHasChanged();
}
else
{
// Se non ci sono database, prova con gli schemi
await LoadAvailableSchemas();
if (availableSchemas.Any())
{
Logger.LogInformation("Trovati {SchemaCount} schemi disponibili", availableSchemas.Count);
showSchemaSelectionModal = true;
StateHasChanged();
}
else
{
// Nessuna opzione disponibile
databaseErrorMessage = "Impossibile rilevare database o schemi. Verificare le credenziali di connessione o il tipo di database.";
}
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nella gestione della selezione database/schema");
databaseErrorMessage = $"Errore nella rilevazione di database/schemi: {ex.Message}";
}
}
/// <summary>
/// Estrae lo schema dal nome completo di una tabella
/// </summary>
@@ -2195,7 +2185,7 @@ public partial class DataCoupler : ComponentBase
{
return databaseType switch
{
DatabaseType.SqlServer => $"SELECT TOP {limit} * FROM ({baseQuery}) AS subquery",
DatabaseType.SqlServer => $"SELECT TOP {limit} * FROM ({baseQuery}) AS subquery",
DatabaseType.Oracle => $"SELECT * FROM ({baseQuery}) WHERE ROWNUM <= {limit}",
DatabaseType.MySql => $"{baseQuery} LIMIT {limit}",
DatabaseType.PostgreSql => $"{baseQuery} LIMIT {limit}",
@@ -2235,16 +2225,6 @@ public partial class DataCoupler : ComponentBase
return null;
}
/// <summary>
/// Annulla la selezione del database
/// </summary>
private void CancelDatabaseSelection()
{
showDatabaseSelectionModal = false;
selectedDatabase = "";
StateHasChanged();
}
/// <summary>
/// Annulla la selezione dello schema
/// </summary>
@@ -2255,106 +2235,6 @@ public partial class DataCoupler : ComponentBase
StateHasChanged();
}
/// <summary>
/// Conferma la selezione del database
/// </summary>
private async Task OnDatabaseSelected()
{
if (string.IsNullOrEmpty(selectedDatabase))
return;
showDatabaseSelectionModal = false;
try
{
Logger.LogInformation("Database selezionato: {Database}. Tentativo di connessione diretta...", selectedDatabase);
// Trova la credenziale corrente
var credential = databaseCredentials.FirstOrDefault(c => c.Name == selectedDatabaseCredential);
if (credential == null)
{
databaseErrorMessage = "Credenziale database non trovata";
return;
}
isConnectingDatabase = true;
databaseErrorMessage = "";
// Disponi il manager precedente
currentDatabaseManager?.Dispose();
currentDatabaseManager = null;
// Per ora, proviamo a usare il database manager esistente e cercare le tabelle con query dirette
// TODO: In futuro, modificare il ConnectionFactory per supportare database specifici
currentDatabaseManager = await ConnectionFactory.CreateDatabaseManagerAsync(selectedDatabaseCredential);
// Prova a ottenere le tabelle del database specifico usando query dirette
var tablesQuery = credential.DatabaseType switch
{
DatabaseType.SqlServer => $"SELECT TABLE_NAME FROM {selectedDatabase}.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'",
DatabaseType.MySql => $"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{selectedDatabase}' AND TABLE_TYPE = 'BASE TABLE'",
DatabaseType.PostgreSql => $"SELECT tablename as TABLE_NAME FROM pg_tables WHERE schemaname = '{selectedDatabase}'",
DatabaseType.Oracle => $"SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = '{selectedDatabase.ToUpper()}'",
_ => $"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{selectedDatabase}' AND TABLE_TYPE = 'BASE TABLE'"
};
Logger.LogInformation("Eseguendo query per tabelle del database {Database}: {Query}", selectedDatabase, tablesQuery);
var tableResults = await currentDatabaseManager.ExecuteRawQueryAsync(tablesQuery);
if (tableResults != null && tableResults.Any())
{
// Converte i risultati in un dizionario di tabelle
databaseTables.Clear();
foreach (var row in tableResults)
{
var tableName = row.Values.FirstOrDefault()?.ToString();
if (!string.IsNullOrEmpty(tableName))
{
// Per ogni tabella, prova a ottenere le colonne
try
{
var fullTableName = credential.DatabaseType == DatabaseType.SqlServer
? $"{selectedDatabase}.dbo.{tableName}"
: $"{selectedDatabase}.{tableName}";
var columns = await GetTableColumns(fullTableName, selectedDatabase, tableName);
databaseTables[fullTableName] = columns;
}
catch (Exception colEx)
{
Logger.LogWarning(colEx, "Impossibile ottenere colonne per la tabella {TableName}", tableName);
// Aggiungi la tabella anche senza colonne specifiche
databaseTables[tableName] = new List<DbColumnInfo>();
}
}
}
isDatabaseConnected = true;
Logger.LogInformation("Connessione completata con successo. Database: {Database}, Tabelle: {TableCount}",
selectedDatabase, databaseTables.Count);
databaseErrorMessage = "";
}
else
{
databaseErrorMessage = $"Nessuna tabella trovata nel database {selectedDatabase}";
Logger.LogWarning("Nessuna tabella trovata nel database {Database}", selectedDatabase);
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nella connessione con il database selezionato: {Database}", selectedDatabase);
databaseErrorMessage = $"Errore nella connessione con database {selectedDatabase}: {ex.Message}";
isDatabaseConnected = false;
}
finally
{
isConnectingDatabase = false;
StateHasChanged();
}
}
/// <summary>
/// Ottiene le colonne di una tabella specifica
/// </summary>
@@ -2583,62 +2463,249 @@ public partial class DataCoupler : ComponentBase
}
}
/// <summary>
/// Carica la lista dei database disponibili
/// </summary>
private async Task LoadAvailableDatabases()
// Gestione selezione database quando la discovery restituisce dizionario vuoto
private async Task HandleDatabaseSelectionRequired()
{
if (currentDatabaseManager == null)
return;
isLoadingDatabases = true;
showDatabaseSelectionModal = true;
availableDatabases.Clear();
selectedDatabase = "";
try
{
var credential = databaseCredentials.FirstOrDefault(c => c.Name == selectedDatabaseCredential);
if (credential == null) return;
string? databaseQuery = credential.DatabaseType switch
if (currentDatabaseManager != null)
{
DatabaseType.SqlServer => "SELECT name FROM sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb')",
DatabaseType.PostgreSql => "SELECT datname FROM pg_database WHERE datistemplate = false AND datname NOT IN ('postgres', 'template0', 'template1')",
DatabaseType.MySql => "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')",
_ => null
};
if (!string.IsNullOrEmpty(databaseQuery))
{
var results = await currentDatabaseManager.ExecuteRawQueryAsync(databaseQuery);
if (results != null && results.Any())
{
var databases = results.Select(row =>
{
var firstValue = row.Values.FirstOrDefault();
return firstValue?.ToString() ?? "";
})
.Where(db => !string.IsNullOrEmpty(db))
.OrderBy(db => db)
.ToList();
if (databases.Any())
{
availableDatabases.AddRange(databases);
Logger.LogInformation("Caricati {DatabaseCount} database per {DatabaseType}: {Databases}",
databases.Count, credential.DatabaseType, string.Join(", ", databases));
}
}
var dbs = await currentDatabaseManager.GetAvailableDatabasesAsync();
availableDatabases = dbs ?? new List<string>();
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nel caricamento dei database disponibili");
databaseErrorMessage = $"Errore nel caricamento dei database: {ex.Message}";
}
finally
{
isLoadingDatabases = false;
}
}
private async Task OnDatabaseSelected()
{
try
{
if (string.IsNullOrEmpty(selectedDatabase))
{
databaseErrorMessage = "Nessun database selezionato";
return;
}
showDatabaseSelectionModal = false;
Logger.LogInformation("Database selezionato: {DatabaseName}. Riconnessione in corso...", selectedDatabase);
// Riconnessione al database selezionato
await ConnectToDatabaseWithSpecificDatabase(selectedDatabase);
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nella selezione del database: {DatabaseName}", selectedDatabase);
databaseErrorMessage = $"Errore nella connessione al database {selectedDatabase}: {ex.Message}";
}
}
private void CancelDatabaseSelection()
{
showDatabaseSelectionModal = false;
selectedDatabase = "";
databaseErrorMessage = "Selezione database annullata";
Logger.LogInformation("Selezione database annullata dall'utente");
}
// Metodi helper per la connessione database
private Task<bool> IsDatabaseSpecifiedInConnectionString(DatabaseCredential credential)
{
try
{
Logger.LogInformation("Verifica database specificato - Tipo: {DatabaseType}, DatabaseName: '{DatabaseName}', Connection: {ConnectionString}",
credential.DatabaseType, credential.DatabaseName, credential.ConnectionString?.Substring(0, Math.Min(100, credential.ConnectionString?.Length ?? 0)));
// Prima verifica se c'è un database specificato nel campo DatabaseName della credenziale
if (!string.IsNullOrEmpty(credential.DatabaseName))
{
Logger.LogInformation("Database specificato nel campo DatabaseName: '{DatabaseName}' - RESULT: TRUE", credential.DatabaseName);
return Task.FromResult(true);
}
// Per SQL Server verifica se Initial Catalog o Database è specificato nella connection string
if (credential.DatabaseType == DatabaseType.SqlServer)
{
var connectionString = credential.ConnectionString ?? "";
var hasInitialCatalog = connectionString.Contains("Initial Catalog=", StringComparison.OrdinalIgnoreCase);
var hasDatabase = connectionString.Contains("Database=", StringComparison.OrdinalIgnoreCase);
var result = hasInitialCatalog || hasDatabase;
Logger.LogInformation("SQL Server - HasInitialCatalog: {HasInitialCatalog}, HasDatabase: {HasDatabase}, Result: {Result}",
hasInitialCatalog, hasDatabase, result);
return Task.FromResult(result);
}
// TODO: Implementare per altri tipi di database
// MySQL: Database=
// PostgreSQL: Database=
// Oracle: più complesso con SID/Service Name
Logger.LogWarning("Verifica database specificato non implementata per tipo database: {DatabaseType}", credential.DatabaseType);
return Task.FromResult(true); // Default: assume database specificato per tipi non implementati
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nella verifica database specificato in connection string");
return Task.FromResult(true); // Default: assume database specificato in caso di errore
}
}
private async Task LoadTablesFromConnectedDatabase()
{
try
{
if (currentDatabaseManager == null)
{
databaseErrorMessage = "Database manager non disponibile";
return;
}
Logger.LogInformation("Caricando tabelle dal database connesso");
var tableNames = await currentDatabaseManager.GetTableNamesAsync();
availableTableNames = tableNames.ToList();
Logger.LogInformation("Caricate {Count} tabelle dal database", availableTableNames.Count);
// Resetta i dettagli delle tabelle - verranno caricati solo quando selezionati
databaseTables.Clear();
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nel caricamento delle tabelle dal database connesso");
databaseErrorMessage = $"Errore nel caricamento tabelle: {ex.Message}";
throw;
}
}
private async Task LoadAvailableDatabases()
{
try
{
if (currentDatabaseManager == null)
{
databaseErrorMessage = "Database manager non disponibile";
return;
}
isLoadingDatabases = true;
Logger.LogInformation("Caricando database disponibili");
// Usa il metodo corretto dell'interfaccia IDatabaseManager
var allDatabases = await currentDatabaseManager.GetAvailableDatabasesAsync();
Logger.LogInformation("Ottenuti {DatabaseCount} database dal server", allDatabases.Count);
// Filtra i database di sistema
availableDatabases = FilterSystemDatabases(allDatabases).ToList();
Logger.LogInformation("Trovati {TotalDatabases} database, filtrati a {FilteredDatabases} (esclusi quelli di sistema)",
allDatabases.Count, availableDatabases.Count);
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nel caricamento dei database disponibili");
databaseErrorMessage = $"Errore nel caricamento database: {ex.Message}";
throw;
}
finally
{
isLoadingDatabases = false;
}
}
private IEnumerable<string> FilterSystemDatabases(List<string> allDatabases)
{
// Trova la credenziale per determinare il tipo di database
var credential = databaseCredentials.FirstOrDefault(c => c.Name == selectedDatabaseCredential);
if (credential == null)
{
Logger.LogWarning("Credenziale non trovata per filtraggio database di sistema");
return allDatabases; // Restituisce tutti se non riesce a determinare il tipo
}
var databaseType = credential.DatabaseType;
// Filtri per SQL Server
if (databaseType == DatabaseType.SqlServer)
{
var sqlServerSystemDatabases = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"master", "tempdb", "model", "msdb", "Resource", "mssqlsystemresource",
"ReportServer", "ReportServerTempDB", "SSISDB", "distribution"
};
return allDatabases.Where(db => !sqlServerSystemDatabases.Contains(db));
}
// TODO: Implementare filtri per altri tipi di database
if (databaseType == DatabaseType.MySql)
{
Logger.LogInformation("Filtro database di sistema MySQL - DA IMPLEMENTARE");
return allDatabases; // Per ora restituisce tutti
}
if (databaseType == DatabaseType.PostgreSql)
{
Logger.LogInformation("Filtro database di sistema PostgreSQL - DA IMPLEMENTARE");
return allDatabases; // Per ora restituisce tutti
}
if (databaseType == DatabaseType.Oracle)
{
Logger.LogInformation("Filtro database di sistema Oracle - DA IMPLEMENTARE");
return allDatabases; // Per ora restituisce tutti
}
Logger.LogWarning("Tipo database non riconosciuto per filtraggio: {DatabaseType}", databaseType);
return allDatabases; // Restituisce tutti per tipi non riconosciuti
}
// Metodo per gestire la selezione di un database dal modale
private async Task ConnectToDatabaseWithSpecificDatabase(string databaseName)
{
try
{
if (currentDatabaseManager == null)
{
databaseErrorMessage = "Database manager non disponibile";
return;
}
Logger.LogInformation("Cambiando database a: {DatabaseName}", databaseName);
// Usa il metodo dell'interfaccia per cambiare database
await currentDatabaseManager.ChangeDatabaseAsync(databaseName);
Logger.LogInformation("Database cambiato con successo a: {DatabaseName}", databaseName);
// Carica le tabelle dal database selezionato
await LoadTablesFromConnectedDatabase();
isDatabaseConnected = true;
Logger.LogInformation("Connessione completata per database: {DatabaseName}", databaseName);
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nella connessione al database specifico: {DatabaseName}", databaseName);
databaseErrorMessage = $"Errore nella connessione al database {databaseName}: {ex.Message}";
throw;
}
}
}