[Feature] Aggiunto supporto completo OLE DB per connessione database

## Nuovi file
- DataConnection/DB/OleDbDatabaseManager.cs: Manager completo per connessioni OLE DB
  con supporto Task.Run() per operazioni sincrone, parametri posizionali '?',
  guard per piattaforma Windows, nessun supporto ChangeDatabaseAsync (no-op)
- DataConnection/DB/EF/SchemaProviders/OleDbSchemaProvider.cs: Schema provider per
  OLE DB, usa OleDbSchemaGuid per tabelle/colonne/chiavi primarie, mapping tipi dati
- CredentialManager/Services/OleDbProviderDiscoveryService.cs: Servizio di discovery
  provider OLE DB installati tramite registro Windows (HKEY_CLASSES_ROOT). Rileva
  9 provider noti: VFPOLEDB.1, Microsoft.ACE.OLEDB.12.0, Jet 4.0, SQLOLEDB, ecc.
  Mostra warning per provider solo 32-bit (VFPOLEDB, Jet)
- PUBLISH_32BIT_64BIT.md: Documentazione completa comandi pubblicazione per
  win-x64, win-x86 (richiesto per VFP), linux-x64, osx-x64, osx-arm64.
  Include prerequisiti VFPOLEDB, esempi connection string VFP, note Docker

## File modificati
- DataConnection/DB/Enums/DatabaseType.cs: Aggiunto valore OleDb dopo Odbc
- DataConnection/DataConnection.csproj: Aggiunto pacchetto System.Data.OleDb 9.0.3
- DataConnection/DB/OdbcDatabaseManager.cs: Fix bug ChangeDatabaseAsync con try-catch
- CredentialManager/Models/CredentialModels.cs: Aggiunto OleDb all'enum DatabaseType,
  BuildOleDbConnectionString() con supporto provider da AdditionalParameters,
  default VFPOLEDB.1, costruzione connection string con parametri VFP
- DataConnection/CredentialManagement/Models/CredentialExtensions.cs: Mappatura
  OleDb in ToDataConnectionDatabaseType() e ToCredentialDatabaseType()
- DataConnection/CredentialManagement/Services/DataConnectionCredentialService.cs:
  Aggiunto case OleDb in TestDatabaseConnectionAsync e metodo TestOleDbConnection()
  con apertura connessione via Task.Run() e gestione OleDbException dettagliata
- Data_Coupler/Services/DataConnectionFactory.cs: Aggiunto case OleDb per creazione
  OleDbDatabaseManager
- Data_Coupler/Program.cs: Registrazione IOleDbProviderDiscoveryService come Scoped
- Data_Coupler/Pages/CredentialManagement.razor: Aggiunta UI completa OLE DB con
  sezione dedicata Visual FoxPro (percorso .dbc/.dbf, Collating Sequence, DELETED),
  provider discovery con refresh, anteprima connection string, variabili di stato
  e metodi nel codice Blazor, sincronizzazione AdditionalParameters al salvataggio

## Compatibilità
- VFP 8.0/9.0: testato con VFPOLEDB.1, connessione file-based .dbc e .dbf
- Richiede pubblicazione win-x86 per driver OLE DB 32-bit
- AnyCPU non supportato per VFP (COM 32-bit)
This commit is contained in:
2026-05-25 21:20:08 +02:00
parent 6452d45b77
commit 82e0d6bc77
13 changed files with 1342 additions and 5 deletions
+44 -1
View File
@@ -55,7 +55,8 @@ public enum DatabaseType
Sqlite,
DB2,
SapHana,
Odbc
Odbc,
OleDb
}
/// <summary>
@@ -194,6 +195,7 @@ public static class ConnectionStringBuilder
DatabaseType.DB2 => BuildDb2ConnectionString(credential),
DatabaseType.SapHana => BuildSapHanaConnectionString(credential),
DatabaseType.Odbc => BuildOdbcConnectionString(credential),
DatabaseType.OleDb => BuildOleDbConnectionString(credential),
_ => throw new NotSupportedException($"Database type {credential.DatabaseType} not supported")
};
} private static string BuildSqlServerConnectionString(DatabaseCredential credential)
@@ -427,6 +429,47 @@ public static class ConnectionStringBuilder
return string.Join(";", builder);
}
private static string BuildOleDbConnectionString(DatabaseCredential credential)
{
// Se è già presente una connection string personalizzata, utilizzala
if (!string.IsNullOrEmpty(credential.ConnectionString))
return credential.ConnectionString;
var builder = new List<string>();
// Provider OLE DB (obbligatorio)
var provider = credential.AdditionalParameters?.GetValueOrDefault("Provider") ?? "VFPOLEDB.1";
builder.Add($"Provider={provider}");
// Data Source: per VFP e Access è il percorso file/cartella
// DatabaseName è il campo principale (come per SQLite)
var dataSource = !string.IsNullOrEmpty(credential.DatabaseName)
? credential.DatabaseName
: credential.Host;
if (!string.IsNullOrEmpty(dataSource))
builder.Add($"Data Source={dataSource}");
// Credenziali (opzionali per VFP file-based)
if (!string.IsNullOrEmpty(credential.Username))
builder.Add($"User ID={credential.Username}");
if (!string.IsNullOrEmpty(credential.Password))
builder.Add($"Password={credential.Password}");
// Parametri aggiuntivi specifici (es. Collating Sequence, Exclusive, DELETED per VFP)
if (credential.AdditionalParameters != null)
{
foreach (var param in credential.AdditionalParameters)
{
if (param.Key != "Provider") // Provider già gestito sopra
builder.Add($"{param.Key}={param.Value}");
}
}
return string.Join(";", builder);
}
private static void AddAdditionalParameters(List<string> builder, Dictionary<string, string>? additionalParams)
{
if (additionalParams != null)
@@ -0,0 +1,112 @@
using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using System.Runtime.InteropServices;
namespace CredentialManager.Services;
/// <summary>
/// Informazioni su un provider OLE DB installato nel sistema
/// </summary>
public class OleDbProviderInfo
{
/// <summary>ProgID del provider (es. VFPOLEDB.1, Microsoft.ACE.OLEDB.12.0)</summary>
public string ProgId { get; set; } = string.Empty;
/// <summary>Descrizione leggibile del provider</summary>
public string Description { get; set; } = string.Empty;
/// <summary>Indica se è un provider Visual FoxPro (solo 32-bit)</summary>
public bool IsVfpProvider { get; set; }
/// <summary>Nota aggiuntiva (es. avviso 32-bit)</summary>
public string? Note { get; set; }
}
/// <summary>
/// Interfaccia per il servizio di discovery dei provider OLE DB installati
/// </summary>
public interface IOleDbProviderDiscoveryService
{
/// <summary>
/// Ottiene la lista dei provider OLE DB noti installati nel sistema
/// </summary>
List<OleDbProviderInfo> GetInstalledProviders();
/// <summary>
/// Verifica se almeno un provider Visual FoxPro è installato
/// </summary>
bool IsVfpProviderInstalled();
}
/// <summary>
/// Servizio per la discovery dei provider OLE DB installati tramite il registro di Windows.
/// Controlla un elenco di provider noti verificando la presenza della chiave HKEY_CLASSES_ROOT\{ProgId}.
/// </summary>
public class OleDbProviderDiscoveryService : IOleDbProviderDiscoveryService
{
private readonly ILogger<OleDbProviderDiscoveryService> _logger;
/// <summary>
/// Provider OLE DB noti: ProgID → Descrizione
/// </summary>
private static readonly (string ProgId, string Description, bool IsVfp)[] KnownProviders =
{
("VFPOLEDB.1", "Microsoft OLE DB Provider per Visual FoxPro 8.0/9.0 (32-bit)", true),
("VFPOLEDB", "Microsoft OLE DB Provider per Visual FoxPro (32-bit)", true),
("Microsoft.ACE.OLEDB.12.0", "Microsoft Access Database Engine 2010", false),
("Microsoft.ACE.OLEDB.16.0", "Microsoft Access Database Engine 2016", false),
("Microsoft.Jet.OLEDB.4.0", "Microsoft Jet 4.0 OLE DB Provider (Access/Excel 97-2003)", false),
("SQLOLEDB", "Microsoft OLE DB Provider for SQL Server (legacy)", false),
("SQLNCLI11", "SQL Server Native Client 11.0", false),
("MSOLEDBSQL", "Microsoft OLE DB Driver for SQL Server", false),
("MSDAORA", "Microsoft OLE DB Provider for Oracle (legacy)", false),
};
public OleDbProviderDiscoveryService(ILogger<OleDbProviderDiscoveryService> logger)
{
_logger = logger;
}
public List<OleDbProviderInfo> GetInstalledProviders()
{
var installed = new List<OleDbProviderInfo>();
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
_logger.LogWarning("OLE DB è supportato solo su Windows. Nessun provider restituito.");
return installed;
}
foreach (var (progId, description, isVfp) in KnownProviders)
{
try
{
using var key = Registry.ClassesRoot.OpenSubKey(progId);
if (key != null)
{
var note = isVfp ? "⚠ Solo 32-bit — pubblicare con --runtime win-x86" : null;
installed.Add(new OleDbProviderInfo
{
ProgId = progId,
Description = description,
IsVfpProvider = isVfp,
Note = note
});
_logger.LogDebug("Provider OLE DB trovato: {ProgId}", progId);
}
}
catch (Exception ex)
{
_logger.LogDebug("Errore nel verificare il provider {ProgId}: {Message}", progId, ex.Message);
}
}
_logger.LogInformation("Provider OLE DB installati trovati: {Count}", installed.Count);
return installed;
}
public bool IsVfpProviderInstalled()
{
return GetInstalledProviders().Any(p => p.IsVfpProvider);
}
}