Be more flexible about extracting booleans from database

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14376


(cherry picked from commit dd8b52af93)
This commit is contained in:
Jon Evans 2023-03-22 21:24:24 -04:00
parent 5dc683c968
commit 2ada171806
2 changed files with 83 additions and 6 deletions

View File

@ -292,6 +292,55 @@ void SCH_DATABASE_PLUGIN::ensureConnection()
} }
std::optional<bool> SCH_DATABASE_PLUGIN::boolFromAny( const std::any& aVal )
{
try
{
bool val = std::any_cast<bool>( aVal );
return val;
}
catch( const std::bad_any_cast& )
{
}
try
{
int val = std::any_cast<int>( aVal );
return static_cast<bool>( val );
}
catch( const std::bad_any_cast& )
{
}
try
{
wxString strval( std::any_cast<std::string>( aVal ).c_str(), wxConvUTF8 );
if( strval.IsEmpty() )
return std::nullopt;
strval.MakeLower();
for( const wxString& trueVal : { wxS( "true" ), wxS( "yes" ), wxS( "y" ), wxS( "1" ) } )
{
if( strval.Matches( trueVal ) )
return true;
}
for( const wxString& falseVal : { wxS( "false" ), wxS( "no" ), wxS( "n" ), wxS( "0" ) } )
{
if( strval.Matches( falseVal ) )
return false;
}
}
catch( const std::bad_any_cast& )
{
}
return std::nullopt;
}
LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName, LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
const DATABASE_LIB_TABLE& aTable, const DATABASE_LIB_TABLE& aTable,
const DATABASE_CONNECTION::ROW& aRow ) const DATABASE_CONNECTION::ROW& aRow )
@ -300,12 +349,15 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
if( aRow.count( aTable.symbols_col ) ) if( aRow.count( aTable.symbols_col ) )
{ {
LIB_SYMBOL* originalSymbol = nullptr;
// TODO: Support multiple options for symbol // TODO: Support multiple options for symbol
std::string symbolIdStr = std::any_cast<std::string>( aRow.at( aTable.symbols_col ) ); std::string symbolIdStr = std::any_cast<std::string>( aRow.at( aTable.symbols_col ) );
LIB_ID symbolId; LIB_ID symbolId;
symbolId.Parse( std::any_cast<std::string>( aRow.at( aTable.symbols_col ) ) ); symbolId.Parse( std::any_cast<std::string>( aRow.at( aTable.symbols_col ) ) );
LIB_SYMBOL* originalSymbol = m_libTable->LoadSymbol( symbolId ); if( symbolId.IsValid() )
originalSymbol = m_libTable->LoadSymbol( symbolId );
if( originalSymbol ) if( originalSymbol )
{ {
@ -314,6 +366,11 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
symbol = originalSymbol->Duplicate(); symbol = originalSymbol->Duplicate();
symbol->SetSourceLibId( symbolId ); symbol->SetSourceLibId( symbolId );
} }
else if( !symbolId.IsValid() )
{
wxLogTrace( traceDatabase, wxT( "loadSymboFromRow: source symbol id '%s' is invalid, "
"will create empty symbol" ), symbolIdStr );
}
else else
{ {
wxLogTrace( traceDatabase, wxT( "loadSymboFromRow: source symbol '%s' not found, " wxLogTrace( traceDatabase, wxT( "loadSymboFromRow: source symbol '%s' not found, "
@ -376,15 +433,33 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
if( !aTable.properties.exclude_from_board.empty() if( !aTable.properties.exclude_from_board.empty()
&& aRow.count( aTable.properties.exclude_from_board ) ) && aRow.count( aTable.properties.exclude_from_board ) )
{ {
bool exclude = std::any_cast<bool>( aRow.at( aTable.properties.exclude_from_board ) ); std::optional<bool> val = boolFromAny( aRow.at( aTable.properties.exclude_from_board ) );
symbol->SetIncludeOnBoard( !exclude );
if( val )
{
symbol->SetIncludeOnBoard( !( *val ) );
}
else
{
wxLogTrace( traceDatabase, wxT( "loadSymbolFromRow: exclude_from_board value for %s "
"could not be cast to a boolean" ), aSymbolName );
}
} }
if( !aTable.properties.exclude_from_bom.empty() if( !aTable.properties.exclude_from_bom.empty()
&& aRow.count( aTable.properties.exclude_from_bom ) ) && aRow.count( aTable.properties.exclude_from_bom ) )
{ {
bool exclude = std::any_cast<bool>( aRow.at( aTable.properties.exclude_from_bom ) ); std::optional<bool> val = boolFromAny( aRow.at( aTable.properties.exclude_from_bom ) );
symbol->SetIncludeInBom( !exclude );
if( val )
{
symbol->SetIncludeInBom( !( *val ) );
}
else
{
wxLogTrace( traceDatabase, wxT( "loadSymbolFromRow: exclude_from_bom value for %s "
"could not be cast to a boolean" ), aSymbolName );
}
} }
std::vector<LIB_FIELD*> fields; std::vector<LIB_FIELD*> fields;
@ -399,7 +474,7 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
{ {
if( !aRow.count( mapping.column ) ) if( !aRow.count( mapping.column ) )
{ {
wxLogTrace( traceDatabase, wxT( "loadSymboFromRow: field %s not found in result" ), wxLogTrace( traceDatabase, wxT( "loadSymbolFromRow: field %s not found in result" ),
mapping.column ); mapping.column );
continue; continue;
} }

View File

@ -103,6 +103,8 @@ private:
const DATABASE_LIB_TABLE& aTable, const DATABASE_LIB_TABLE& aTable,
const DATABASE_CONNECTION::ROW& aRow ); const DATABASE_CONNECTION::ROW& aRow );
static std::optional<bool> boolFromAny( const std::any& aVal );
SYMBOL_LIB_TABLE* m_libTable; SYMBOL_LIB_TABLE* m_libTable;
std::unique_ptr<DATABASE_LIB_SETTINGS> m_settings; std::unique_ptr<DATABASE_LIB_SETTINGS> m_settings;