HTTP library reload cache, if the cache is empty, when picking a part

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17569
This commit is contained in:
Rosy 2024-04-25 00:42:13 +00:00 committed by Seth Hillbrand
parent 058b337b00
commit 0984af1676
2 changed files with 69 additions and 62 deletions

View File

@ -29,8 +29,7 @@
#include "sch_io_http_lib.h"
SCH_IO_HTTP_LIB::SCH_IO_HTTP_LIB() : SCH_IO( wxS( "HTTP library" ) ),
m_libTable( nullptr )
SCH_IO_HTTP_LIB::SCH_IO_HTTP_LIB() : SCH_IO( wxS( "HTTP library" ) ), m_libTable( nullptr )
{
}
@ -56,11 +55,11 @@ void SCH_IO_HTTP_LIB::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties )
{
wxCHECK_RET( m_libTable, _("httplib plugin missing library table handle!") );
wxCHECK_RET( m_libTable, _( "httplib plugin missing library table handle!" ) );
ensureSettings( aLibraryPath );
ensureConnection();
if( !m_conn)
if( !m_conn )
{
THROW_IO_ERROR( m_lastError );
return;
@ -70,13 +69,11 @@ void SCH_IO_HTTP_LIB::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
( aProperties
&& aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() );
for(const HTTP_LIB_CATEGORY& category : m_conn->getCategories() )
for( const HTTP_LIB_CATEGORY& category : m_conn->getCategories() )
{
bool refresh_cache = true;
std::vector<HTTP_LIB_PART> found_parts;
// Check if there is already a part in our cache, if not fetch it
// Check if there is already a part in our cache, if not fetch it
if( m_cachedCategories.find( category.id ) != m_cachedCategories.end() )
{
// check if it's outdated, if so re-fetch
@ -89,26 +86,7 @@ void SCH_IO_HTTP_LIB::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
if( refresh_cache )
{
if( !m_conn->SelectAll( category, found_parts ) )
{
if( !m_conn->GetLastError().empty() )
{
wxString msg =
wxString::Format( _( "Error retriving data from HTTP library %s: %s" ),
category.name, m_conn->GetLastError() );
THROW_IO_ERROR( msg );
}
continue;
}
// remove cached parts
m_cachedCategories[category.id].cachedParts.clear();
// Copy newly cached data across
m_cachedCategories[category.id].cachedParts = found_parts;
m_cachedCategories[category.id].lastCached = std::time( nullptr );
syncCache( category );
}
for( const HTTP_LIB_PART& part : m_cachedCategories[category.id].cachedParts )
@ -119,14 +97,12 @@ void SCH_IO_HTTP_LIB::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
if( symbol && ( !powerSymbolsOnly || symbol->IsPower() ) )
aSymbolList.emplace_back( symbol );
}
}
}
LIB_SYMBOL* SCH_IO_HTTP_LIB::LoadSymbol( const wxString& aLibraryPath,
const wxString& aAliasName,
LIB_SYMBOL* SCH_IO_HTTP_LIB::LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const STRING_UTF8_MAP* aProperties )
{
wxCHECK( m_libTable, nullptr );
@ -145,13 +121,17 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::LoadSymbol( const wxString& aLibraryPath,
std::vector<HTTP_LIB_CATEGORY> categories = m_conn->getCategories();
std::tuple relations = m_conn->getCachedParts()[partName];
if( m_conn->getCachedParts().empty() )
{
syncCache();
}
std::tuple relations = m_conn->getCachedParts()[partName];
std::string associatedCatID = std::get<1>( relations );
// get the matching category
for( const HTTP_LIB_CATEGORY& categoryIter : categories )
{
std::string associatedCatID = std::get<1>( relations );
if( categoryIter.id == associatedCatID )
{
foundCategory = &categoryIter;
@ -197,26 +177,26 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::LoadSymbol( const wxString& aLibraryPath,
void SCH_IO_HTTP_LIB::GetSubLibraryNames( std::vector<wxString>& aNames )
{
ensureSettings( wxEmptyString );
ensureSettings( wxEmptyString );
aNames.clear();
aNames.clear();
std::set<wxString> categoryNames;
std::set<wxString> categoryNames;
for( const HTTP_LIB_CATEGORY& categoryIter : m_conn->getCategories() )
{
for( const HTTP_LIB_CATEGORY& categoryIter : m_conn->getCategories() )
{
if( categoryNames.count( categoryIter.name ) )
continue;
aNames.emplace_back( categoryIter.name );
categoryNames.insert( categoryIter.name );
}
}
}
void SCH_IO_HTTP_LIB::GetAvailableSymbolFields( std::vector<wxString>& aNames )
{
// TODO: Implement this sometime; This is currently broken...
// TODO: Implement this sometime; This is currently broken...
std::copy( m_customFields.begin(), m_customFields.end(), std::back_inserter( aNames ) );
}
@ -230,13 +210,12 @@ void SCH_IO_HTTP_LIB::GetDefaultSymbolFields( std::vector<wxString>& aNames )
void SCH_IO_HTTP_LIB::ensureSettings( const wxString& aSettingsPath )
{
auto tryLoad = [&]()
{
if( !m_settings->LoadFromFile() )
{
wxString msg = wxString::Format( _( "HTTP library settings file %s missing or invalid" ),
aSettingsPath );
wxString msg = wxString::Format(
_( "HTTP library settings file %s missing or invalid" ), aSettingsPath );
THROW_IO_ERROR( msg );
}
@ -252,11 +231,10 @@ void SCH_IO_HTTP_LIB::ensureSettings( const wxString& aSettingsPath )
if( m_settings->getSupportedAPIVersion() != m_settings->m_Source.api_version )
{
wxString msg = wxString::Format(
_( "HTTP library settings file %s uses API version %s, but KiCad requires version %s" ),
aSettingsPath,
m_settings->m_Source.api_version,
m_settings->getSupportedAPIVersion() );
wxString msg = wxString::Format( _( "HTTP library settings file %s uses API version "
"%s, but KiCad requires version %s" ),
aSettingsPath, m_settings->m_Source.api_version,
m_settings->getSupportedAPIVersion() );
THROW_IO_ERROR( msg );
}
@ -264,8 +242,7 @@ void SCH_IO_HTTP_LIB::ensureSettings( const wxString& aSettingsPath )
if( m_settings->m_Source.root_url.empty() )
{
wxString msg = wxString::Format(
_( "HTTP library settings file %s is missing the root URL!" ),
aSettingsPath );
_( "HTTP library settings file %s is missing the root URL!" ), aSettingsPath );
THROW_IO_ERROR( msg );
}
@ -290,7 +267,6 @@ void SCH_IO_HTTP_LIB::ensureSettings( const wxString& aSettingsPath )
// Append api version to root URL
m_settings->m_Source.root_url += m_settings->m_Source.api_version + "/";
};
if( !m_settings && !aSettingsPath.IsEmpty() )
@ -322,9 +298,8 @@ void SCH_IO_HTTP_LIB::ensureConnection()
if( !m_conn || !m_conn->IsValidEndpoint() )
{
wxString msg = wxString::Format(
_( "Could not connect to %s. Errors: %s" ),
m_settings->m_Source.root_url, m_lastError );
wxString msg = wxString::Format( _( "Could not connect to %s. Errors: %s" ),
m_settings->m_Source.root_url, m_lastError );
THROW_IO_ERROR( msg );
}
@ -351,6 +326,38 @@ void SCH_IO_HTTP_LIB::connect()
}
}
void SCH_IO_HTTP_LIB::syncCache()
{
for( const HTTP_LIB_CATEGORY& category : m_conn->getCategories() )
{
syncCache( category );
}
}
void SCH_IO_HTTP_LIB::syncCache( const HTTP_LIB_CATEGORY& category )
{
std::vector<HTTP_LIB_PART> found_parts;
if( !m_conn->SelectAll( category, found_parts ) )
{
if( !m_conn->GetLastError().empty() )
{
wxString msg = wxString::Format( _( "Error retriving data from HTTP library %s: %s" ),
category.name, m_conn->GetLastError() );
THROW_IO_ERROR( msg );
}
return;
}
// remove cached parts
m_cachedCategories[category.id].cachedParts.clear();
// Copy newly cached data across
m_cachedCategories[category.id].cachedParts = found_parts;
m_cachedCategories[category.id].lastCached = std::time( nullptr );
}
LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbolName,
const HTTP_LIB_CATEGORY& aCategory,
@ -483,7 +490,6 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbo
m_customFields.insert( fieldName );
}
}
}

View File

@ -78,20 +78,22 @@ public:
const wxString& GetError() const override { return m_lastError; }
private:
void ensureSettings( const wxString& aSettingsPath );
void ensureConnection();
void connect();
LIB_SYMBOL* loadSymbolFromPart( const wxString& aSymbolName,
const HTTP_LIB_CATEGORY& aCategory,
void syncCache();
void syncCache( const HTTP_LIB_CATEGORY& category );
LIB_SYMBOL* loadSymbolFromPart( const wxString& aSymbolName, const HTTP_LIB_CATEGORY& aCategory,
const HTTP_LIB_PART& aPart );
SYMBOL_LIB_TABLE* m_libTable;
/// Generally will be null if no valid connection is established
/// Generally will be null if no valid connection is established
std::unique_ptr<HTTP_LIB_CONNECTION> m_conn;
std::unique_ptr<HTTP_LIB_SETTINGS> m_settings;
@ -110,9 +112,8 @@ private:
wxString datasheet_field = "datasheet";
wxString reference_field = "reference";
// category.id category
// category.id category
std::map<std::string, HTTP_LIB_CATEGORY> m_cachedCategories;
};
#endif // SCH_IO_HTTP_LIB_H_