11 KiB
Implementazione ODBC Query Custom Only
📋 Panoramica
Data la natura generica dei driver ODBC e le limitazioni del discovery automatico delle tabelle, è stato implementato un comportamento speciale per le connessioni ODBC nel DataCoupler: le connessioni ODBC utilizzano esclusivamente query SQL custom, bypassando completamente il sistema di discovery delle tabelle.
🎯 Motivazione
I driver ODBC sono estremamente eterogenei e spesso:
- Non supportano query standard di discovery delle tabelle
- Hanno sintassi SQL non standardizzate
- Richiedono permessi specifici per accedere ai metadati del database
- Possono avere limitazioni sulla lettura dello schema
Per questi motivi, è più sicuro e affidabile richiedere all'utente di specificare direttamente la query SQL da eseguire.
🔧 Modifiche Implementate
1. DatabaseMethod.cs
Nuovo Metodo Helper: IsOdbcConnection()
/// <summary>
/// Verifica se la credenziale database selezionata è di tipo ODBC
/// </summary>
/// <returns>True se la credenziale è ODBC, altrimenti False</returns>
protected bool IsOdbcConnection()
{
if (string.IsNullOrEmpty(selectedDatabaseCredential))
return false;
var credential = databaseCredentials.FirstOrDefault(c => c.Name == selectedDatabaseCredential);
return credential?.DatabaseType == DatabaseType.Odbc;
}
Funzionalità:
- Verifica rapidamente se la credenziale corrente è ODBC
- Utilizzato in tutta l'UI per condizionare la visualizzazione degli elementi
Modificato: OnDatabaseCredentialChanged()
protected void OnDatabaseCredentialChanged(ChangeEventArgs e)
{
selectedDatabaseCredential = e.Value?.ToString() ?? "";
ResetDatabaseState();
// Se è una connessione ODBC, forza l'uso di query custom
if (IsOdbcConnection())
{
useCustomQuery = true;
}
}
Comportamento:
- Quando l'utente seleziona una credenziale ODBC,
useCustomQueryviene automaticamente impostato atrue - Questo forza l'applicazione a mostrare solo la sezione query custom
Modificato: ValidateCustomQuery()
Problema originale: Il metodo richiedeva currentDatabaseManager già creato, ma per ODBC non si fa connessione preliminare.
Soluzione implementata:
protected async Task ValidateCustomQuery()
{
// ...
IDatabaseManager? tempManager = null;
try
{
// Per ODBC, crea un database manager temporaneo se non esiste
var managerToUse = currentDatabaseManager;
if (managerToUse == null && IsOdbcConnection())
{
Logger.LogInformation("Creando database manager temporaneo per validazione query ODBC");
tempManager = await ConnectionFactory.CreateDatabaseManagerAsync(selectedDatabaseCredential);
managerToUse = tempManager;
}
// Valida la query con il manager
var testResults = await managerToUse.ExecuteRawQueryAsync(testQuery);
// Se validazione OK, salva il manager per ODBC
if (IsOdbcConnection() && currentDatabaseManager == null && tempManager != null)
{
currentDatabaseManager = tempManager;
tempManager = null; // Non distruggerlo nel finally
}
}
finally
{
// Pulisci il manager temporaneo se non è stato salvato
if (tempManager != null)
{
try { tempManager.Dispose(); } catch { /* Ignora errori di dispose */ }
}
}
}
Funzionalità:
- Crea temporaneamente un
OdbcDatabaseManagerse non esiste - Usa questo manager per testare la query
- Se la validazione ha successo, salva il manager in
currentDatabaseManagerper riutilizzarlo - Gestisce correttamente il dispose del manager temporaneo in caso di errore
2. DataCoupler.razor
Modificata: Sezione Pulsante Connessione
Prima:
@if (!string.IsNullOrEmpty(selectedDatabaseCredential))
{
<div class="mb-3">
<button class="btn btn-success btn-sm" @onclick="ConnectToDatabase">
<i class="fas fa-plug"></i> Connetti e Scopri Schema
</button>
</div>
}
Dopo:
@if (!string.IsNullOrEmpty(selectedDatabaseCredential))
{
<!-- Per ODBC: mostra messaggio esplicativo, niente discovery -->
@if (IsOdbcConnection())
{
<div class="alert alert-info" role="alert">
<i class="oi oi-info"></i> <strong>Connessione ODBC rilevata</strong><br>
Per le connessioni ODBC, il discovery automatico delle tabelle non è disponibile.<br>
Procedi direttamente con l'inserimento di una <strong>query SQL custom</strong> nella sezione sottostante.
</div>
}
else
{
<!-- Per database standard: mostra pulsante di connessione -->
<div class="mb-3">
<button class="btn btn-success btn-sm" @onclick="ConnectToDatabase">
<i class="fas fa-plug"></i> Connetti e Scopri Schema
</button>
</div>
}
}
Funzionalità:
- Per ODBC: mostra un messaggio informativo che spiega la situazione
- Per altri database: mostra il pulsante di connessione standard
- L'utente comprende immediatamente che deve usare query custom
Aggiunta: Sezione Query Custom per ODBC (sempre visibile)
<!-- Per ODBC: mostra direttamente la sezione Query Custom -->
@if (IsOdbcConnection())
{
<!-- Sezione Query Custom per ODBC -->
<div class="mb-3">
<h6>Query SQL Custom:</h6>
<div class="mb-2">
<label class="form-label">Scrivi la tua query SELECT:</label>
<textarea class="form-control" rows="6"
placeholder="SELECT * FROM your_table WHERE condition..."
@bind="customQuery" @bind:event="oninput"></textarea>
<!-- Alert sicurezza -->
</div>
<div class="mb-2">
<button class="btn btn-primary btn-sm me-2" @onclick="ValidateCustomQuery">
<i class="fas fa-check-circle"></i> Valida Query
</button>
<!-- Altri pulsanti preview, ecc. -->
</div>
</div>
}
Funzionalità:
- Sezione query custom sempre visibile quando si seleziona ODBC
- Non richiede connessione preliminare
- Include tutti i controlli per validazione, preview, ecc.
Modificata: Condizione Lista Tabelle
Prima:
@if (isDatabaseConnected)
{
<!-- Lista tabelle e query custom switch -->
}
Dopo:
<!-- Lista Tabelle (solo per database NON ODBC) -->
@if (isDatabaseConnected && !IsOdbcConnection())
{
<!-- Selezione modalità: Tabelle o Query Custom -->
<!-- Lista tabelle -->
}
Funzionalità:
- La sezione lista tabelle non viene mai mostrata per ODBC
- Anche se
isDatabaseConnectedètrue(non dovrebbe mai succedere per ODBC), la sezione resta nascosta
🔄 Flusso Utente ODBC
Prima dell'implementazione:
- Seleziona credenziale ODBC
- Clicca "Connetti e Scopri Schema"
- Errore: discovery tabelle fallisce
- User frustrato, deve capire come fare
Dopo l'implementazione:
- ✅ Seleziona credenziale ODBC
- ✅ Vede immediatamente messaggio informativo
- ✅ Vede la sezione query custom già pronta
- ✅ Scrive la query SQL
- ✅ Clicca "Valida Query" (crea automaticamente
OdbcDatabaseManager) - ✅ Vede preview dei dati
- ✅ Procede con il mapping
Nessun pulsante di connessione, nessun discovery, solo query diretta.
🎨 Esperienza Utente
Per Database Standard (SQL Server, MySQL, ecc.)
- Mostra: Pulsante "Connetti e Scopri Schema"
- Discovery: Automatico con lista tabelle
- Query Custom: Opzionale, via switch
Per Database ODBC
- Mostra: Messaggio informativo + textarea query
- Discovery: Disabilitato completamente
- Query Custom: Obbligatoria, sempre visibile
📊 Vantaggi dell'Implementazione
1. Affidabilità
- Nessun rischio di errori nel discovery delle tabelle ODBC
- L'utente ha il controllo completo della query SQL
2. Semplicità
- Flusso chiaro: seleziona ODBC → scrivi query → valida → preview
- Nessun passo intermedio confusionario
3. Performance
- Nessun tentativo di discovery che può essere lento o fallire
- Connessione ODBC creata solo quando serve (alla validazione)
4. Flessibilità
- L'utente può scrivere qualsiasi query SELECT
- Supporta JOIN, WHERE, GROUP BY, ecc.
- Nessuna limitazione del discovery automatico
🔒 Sicurezza
Tutti i controlli di sicurezza esistenti restano attivi:
- ✅ Solo query
SELECTpermesse - ✅ Query multiple (separate da
;) bloccate - ✅ Operazioni
INSERT,UPDATE,DELETE,DROPbloccate - ✅ Query pulita da caratteri pericolosi
🧪 Test Manuali Suggeriti
Test 1: Selezione Credenziale ODBC
- Vai a DataCoupler
- Seleziona sorgente Database
- Seleziona una credenziale ODBC
- Verifica:
- ✅ Nessun pulsante "Connetti e Scopri Schema"
- ✅ Messaggio informativo visibile
- ✅ Sezione query custom visibile
- ✅ Textarea query pronta per input
Test 2: Validazione Query ODBC
- Seleziona credenziale ODBC
- Scrivi query:
SELECT * FROM MyTable - Clicca "Valida Query"
- Verifica:
- ✅ Creazione automatica
OdbcDatabaseManager - ✅ Query eseguita con successo
- ✅ Colonne rilevate mostrate
- ✅ Messaggio "Query valida - N colonne rilevate"
- ✅ Creazione automatica
Test 3: Preview Dati ODBC
- Dopo validazione query (Test 2)
- Clicca "Anteprima Risultati"
- Verifica:
- ✅ Preview tabella con 10 righe
- ✅ Colonne corrette
- ✅ Dati visualizzati correttamente
Test 4: Mapping e Trasferimento ODBC
- Dopo validazione e preview (Test 2-3)
- Procedi con configurazione destinazione
- Crea mapping campi
- Esegui trasferimento
- Verifica:
- ✅ Trasferimento dati completato
- ✅ Record copiati correttamente
Test 5: Confronto con Database Standard
- Seleziona credenziale SQL Server
- Verifica:
- ✅ Pulsante "Connetti e Scopri Schema" visibile
- ✅ Discovery tabelle funziona
- ✅ Switch query custom disponibile
- ✅ Nessun messaggio ODBC
📝 Note Tecniche
Manager ODBC Temporaneo
- Creato on-demand durante la validazione query
- Salvato in
currentDatabaseManagerse validazione OK - Riutilizzato per preview e trasferimento dati
- Disposto correttamente in caso di errore
Compatibilità con Profili Esistenti
- Profili ODBC con query custom salvate continuano a funzionare
- Al caricamento profilo, se ODBC + query custom → valida automaticamente
- Nessuna breaking change per profili esistenti
Dipendenze
OdbcDatabaseManager(già implementato)DataConnectionFactorycon supporto ODBC (già implementato)DatabaseType.Odbcenum (già implementato)
🚀 Future Improvements
Possibili miglioramenti futuri (non implementati ora):
- Syntax Highlighting per query SQL nella textarea
- Query Templates predefiniti per ODBC comuni (SAP HANA, DB2, ecc.)
- Salvataggio Query Recenti per riutilizzo rapido
- Auto-complete Tabelle (se driver ODBC lo supporta)
- Explain Plan per query complesse
Versione: 2.2.0
Data Implementazione: 2 Febbraio 2026
Commit: 8a8ccec
Branch: development
Sviluppatore: Alessio Dalsanto