feat: Implementa gestione intelligente della chiave sorgente con rilevamento PK
- Aggiunge rilevamento automatico Primary Key per connessioni database - Rimuove completamente il fallback automatico per lato sorgente - Implementa selezione manuale obbligatoria per file e sorgenti non-DB - Migliora UI con suggerimenti intelligenti e feedback visivo - Aggiunge validazione multi-livello (UI, pre-transfer, runtime) - Introduce metodo GetPrimaryKeyFieldAsync in IDatabaseManager - Modifica GenerateSourceKey per richiedere sempre campo specifico - Implementa controllo IsTransferButtonEnabled per validazione form Breaking changes: - La generazione automatica delle chiavi sorgente è stata rimossa - Il campo chiave sorgente è ora obbligatorio quando si usa il sistema associazioni Fixes: Risolve problema di discovery schema vuoto con selezione database
This commit is contained in:
@@ -64,15 +64,27 @@ public class DatabaseInitializer : IDatabaseInitializer
|
||||
{
|
||||
try
|
||||
{
|
||||
// Prova a fare una query semplice per verificare che la tabella esista
|
||||
// Verifica che la tabella principale Credentials esista
|
||||
await _context.Credentials.CountAsync();
|
||||
_logger.LogInformation("Verifica tabelle completata con successo");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning("Tabelle mancanti, ricreazione database...");
|
||||
_logger.LogInformation("Tabella Credentials verificata con successo");
|
||||
|
||||
// Se le tabelle non esistono, le ricreiamo
|
||||
// Verifica se la tabella RecordAssociations esiste, se non esiste la crea senza ricreare tutto il database
|
||||
try
|
||||
{
|
||||
await _context.RecordAssociations.CountAsync();
|
||||
_logger.LogInformation("Tabella RecordAssociations verificata con successo");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.LogInformation("Tabella RecordAssociations non trovata, creazione tramite migrazione...");
|
||||
await CreateRecordAssociationsTableAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.LogWarning("Tabella Credentials mancante, ricreazione database...");
|
||||
|
||||
// Solo se la tabella principale non esiste, ricreiamo tutto
|
||||
await _context.Database.EnsureDeletedAsync();
|
||||
await _context.Database.EnsureCreatedAsync();
|
||||
await SeedInitialDataAsync();
|
||||
@@ -142,7 +154,7 @@ public class DatabaseInitializer : IDatabaseInitializer
|
||||
{
|
||||
_logger.LogInformation("Verifica e applicazione migrazioni...");
|
||||
|
||||
// Verifica se la colonna RestServiceType esiste usando una query diretta
|
||||
// Migrazione 1: Verifica se la colonna RestServiceType esiste
|
||||
try
|
||||
{
|
||||
await _context.Database.ExecuteSqlRawAsync(
|
||||
@@ -157,6 +169,62 @@ public class DatabaseInitializer : IDatabaseInitializer
|
||||
"ALTER TABLE Credentials ADD COLUMN RestServiceType TEXT");
|
||||
_logger.LogInformation("Colonna RestServiceType aggiunta con successo");
|
||||
}
|
||||
|
||||
// Migrazione 2: Verifica se la tabella RecordAssociations esiste
|
||||
try
|
||||
{
|
||||
await _context.Database.ExecuteSqlRawAsync(
|
||||
"SELECT COUNT(*) FROM RecordAssociations LIMIT 1");
|
||||
_logger.LogInformation("Tabella RecordAssociations già presente");
|
||||
}
|
||||
catch (Microsoft.Data.Sqlite.SqliteException)
|
||||
{
|
||||
// La tabella non esiste, la creiamo
|
||||
_logger.LogInformation("Creazione tabella RecordAssociations...");
|
||||
|
||||
// Crea la tabella
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE TABLE RecordAssociations (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
SourceName TEXT NOT NULL,
|
||||
SourceType TEXT NOT NULL,
|
||||
SourceKey TEXT NOT NULL,
|
||||
DestinationEntity TEXT NOT NULL,
|
||||
DestinationId TEXT NOT NULL,
|
||||
RestCredentialName TEXT NOT NULL,
|
||||
CreatedAt TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UpdatedAt TEXT,
|
||||
IsActive INTEGER NOT NULL DEFAULT 1,
|
||||
AdditionalInfo TEXT
|
||||
)");
|
||||
|
||||
// Crea gli indici
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE UNIQUE INDEX IX_RecordAssociations_Unique
|
||||
ON RecordAssociations (SourceName, SourceKey, DestinationEntity)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_SourceType
|
||||
ON RecordAssociations (SourceType)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_DestinationEntity
|
||||
ON RecordAssociations (DestinationEntity)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_RestCredentialName
|
||||
ON RecordAssociations (RestCredentialName)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_IsActive
|
||||
ON RecordAssociations (IsActive)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_CreatedAt
|
||||
ON RecordAssociations (CreatedAt)");
|
||||
|
||||
_logger.LogInformation("Tabella RecordAssociations creata con successo");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -164,4 +232,60 @@ public class DatabaseInitializer : IDatabaseInitializer
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateRecordAssociationsTableAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Creazione tabella RecordAssociations...");
|
||||
|
||||
// Crea la tabella
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE TABLE RecordAssociations (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
SourceName TEXT NOT NULL,
|
||||
SourceType TEXT NOT NULL,
|
||||
SourceKey TEXT NOT NULL,
|
||||
DestinationEntity TEXT NOT NULL,
|
||||
DestinationId TEXT NOT NULL,
|
||||
RestCredentialName TEXT NOT NULL,
|
||||
CreatedAt TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UpdatedAt TEXT,
|
||||
IsActive INTEGER NOT NULL DEFAULT 1,
|
||||
AdditionalInfo TEXT
|
||||
)");
|
||||
|
||||
// Crea gli indici
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE UNIQUE INDEX IX_RecordAssociations_Unique
|
||||
ON RecordAssociations (SourceName, SourceKey, DestinationEntity)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_SourceType
|
||||
ON RecordAssociations (SourceType)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_DestinationEntity
|
||||
ON RecordAssociations (DestinationEntity)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_RestCredentialName
|
||||
ON RecordAssociations (RestCredentialName)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_IsActive
|
||||
ON RecordAssociations (IsActive)");
|
||||
|
||||
await _context.Database.ExecuteSqlRawAsync(@"
|
||||
CREATE INDEX IX_RecordAssociations_CreatedAt
|
||||
ON RecordAssociations (CreatedAt)");
|
||||
|
||||
_logger.LogInformation("Tabella RecordAssociations creata con successo");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Errore nella creazione della tabella RecordAssociations");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user