diff --git a/eeschema/sch_io/database/sch_io_database.cpp b/eeschema/sch_io/database/sch_io_database.cpp index 1646fbcf68..ff02badc2f 100644 --- a/eeschema/sch_io/database/sch_io_database.cpp +++ b/eeschema/sch_io/database/sch_io_database.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -38,6 +39,8 @@ SCH_IO_DATABASE::SCH_IO_DATABASE() : SCH_IO( wxS( "Database library" ) ), m_settings(), m_conn() { + m_cacheTimestamp = 0; + m_cacheModifyHash = 0; } @@ -65,6 +68,7 @@ void SCH_IO_DATABASE::EnumerateSymbolLib( std::vector& aSymbolList, wxCHECK_RET( m_libTable, "Database plugin missing library table handle!" ); ensureSettings( aLibraryPath ); ensureConnection(); + cacheLib(); if( !m_conn ) THROW_IO_ERROR( m_lastError ); @@ -73,36 +77,12 @@ void SCH_IO_DATABASE::EnumerateSymbolLib( std::vector& aSymbolList, aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() ); - for( const DATABASE_LIB_TABLE& table : m_settings->m_Tables ) + for( auto const& pair : m_nameToSymbolcache ) { - std::vector results; + LIB_SYMBOL* symbol = pair.second; - if( !m_conn->SelectAll( table.table, table.key_col, results ) ) - { - if( !m_conn->GetLastError().empty() ) - { - wxString msg = wxString::Format( _( "Error reading database table %s: %s" ), - table.table, m_conn->GetLastError() ); - THROW_IO_ERROR( msg ); - } - - continue; - } - - for( DATABASE_CONNECTION::ROW& result : results ) - { - if( !result.count( table.key_col ) ) - continue; - - std::string prefix = table.name.empty() ? "" : fmt::format( "{}/", table.name ); - wxString name( fmt::format( "{}{}", prefix, - std::any_cast( result[table.key_col] ) ) ); - - LIB_SYMBOL* symbol = loadSymbolFromRow( name, table, result ); - - if( symbol && ( !powerSymbolsOnly || symbol->IsPower() ) ) - aSymbolList.emplace_back( symbol ); - } + if( !powerSymbolsOnly || symbol->IsPower() ) + aSymbolList.emplace_back( symbol ); } } @@ -221,6 +201,52 @@ bool SCH_IO_DATABASE::TestConnection( wxString* aErrorMsg ) } +void SCH_IO_DATABASE::cacheLib() +{ + long long currentTimestampSeconds = wxDateTime::Now().GetValue().GetValue() / 1000; + + if( m_libTable->GetModifyHash() == m_cacheModifyHash + && ( currentTimestampSeconds - m_cacheTimestamp ) < m_settings->m_Cache.max_age ) + { + return; + } + + for( const DATABASE_LIB_TABLE& table : m_settings->m_Tables ) + { + std::vector results; + + if( !m_conn->SelectAll( table.table, table.key_col, results ) ) + { + if( !m_conn->GetLastError().empty() ) + { + wxString msg = wxString::Format( _( "Error reading database table %s: %s" ), + table.table, m_conn->GetLastError() ); + THROW_IO_ERROR( msg ); + } + + continue; + } + + for( DATABASE_CONNECTION::ROW& result : results ) + { + if( !result.count( table.key_col ) ) + continue; + + std::string prefix = table.name.empty() ? "" : fmt::format( "{}/", table.name ); + wxString name( fmt::format( "{}{}", prefix, + std::any_cast( result[table.key_col] ) ) ); + + LIB_SYMBOL* symbol = loadSymbolFromRow( name, table, result ); + + if( symbol ) + m_nameToSymbolcache.insert( { symbol->GetName(), symbol } ); + } + } + + m_cacheTimestamp = currentTimestampSeconds; + m_cacheModifyHash = m_libTable->GetModifyHash(); +} + void SCH_IO_DATABASE::ensureSettings( const wxString& aSettingsPath ) { auto tryLoad = diff --git a/eeschema/sch_io/database/sch_io_database.h b/eeschema/sch_io/database/sch_io_database.h index 3748efa937..a3e16983e6 100644 --- a/eeschema/sch_io/database/sch_io_database.h +++ b/eeschema/sch_io/database/sch_io_database.h @@ -85,6 +85,8 @@ public: bool TestConnection( wxString* aErrorMsg = nullptr ); private: + void cacheLib(); + void ensureSettings( const wxString& aSettingsPath ); void ensureConnection(); @@ -108,6 +110,14 @@ private: std::set m_defaultShownFields; + std::map m_nameToSymbolcache; + + long long m_cacheTimestamp; + + int m_cacheModifyHash; + + + wxString m_lastError; };