22#include <unordered_set>
25#include <boost/algorithm/string.hpp>
37 m_libTable( nullptr ),
50 const wxString& aLibraryPath,
53 std::vector<LIB_SYMBOL*> symbols;
57 aSymbolNameList.Add( symbol->GetName() );
62 const wxString& aLibraryPath,
65 wxCHECK_RET(
m_libTable,
"Database plugin missing library table handle!" );
72 bool powerSymbolsOnly = ( aProperties &&
78 std::vector<DATABASE_CONNECTION::ROW> results;
82 if( !
m_conn->GetLastError().empty() )
84 wxString msg = wxString::Format(
_(
"Error reading database table %s: %s" ),
94 if( !result.count( table.
key_col ) )
97 std::string prefix = table.
name.empty() ?
"" : fmt::format(
"{}/", table.
name );
98 wxString
name( fmt::format(
"{}{}", prefix,
99 std::any_cast<std::string>( result[table.
key_col] ) ) );
103 if( symbol && ( !powerSymbolsOnly || symbol->
IsPower() ) )
104 aSymbolList.emplace_back( symbol );
111 const wxString& aAliasName,
130 std::string tableName =
"";
131 std::string symbolName( aAliasName.ToUTF8() );
133 if( aAliasName.Contains(
'/' ) )
135 tableName = std::string( aAliasName.BeforeFirst(
'/' ).ToUTF8() );
136 symbolName = std::string( aAliasName.AfterFirst(
'/' ).ToUTF8() );
139 std::vector<const DATABASE_LIB_TABLE*> tablesToTry;
143 if( tableIter.
name == tableName )
144 tablesToTry.emplace_back( &tableIter );
147 if( tablesToTry.empty() )
149 wxLogTrace(
traceDatabase, wxT(
"LoadSymbol: table '%s' not found in config" ), tableName );
158 if(
m_conn->SelectOne( table->table, std::make_pair( table->key_col, symbolName ),
162 wxLogTrace(
traceDatabase, wxT(
"LoadSymbol: SelectOne (%s, %s) found in %s" ),
163 table->key_col, symbolName, table->table );
167 wxLogTrace(
traceDatabase, wxT(
"LoadSymbol: SelectOne (%s, %s) failed for table %s" ),
168 table->key_col, symbolName, table->table );
172 wxCHECK( foundTable,
nullptr );
184 std::set<wxString> tableNames;
188 if( tableNames.count( tableIter.
name ) )
191 aNames.emplace_back( tableIter.
name );
192 tableNames.insert( tableIter.
name );
206 std::back_inserter( aNames ) );
217 if( aErrorMsg && ( !
m_conn || !
m_conn->IsConnected() ) )
231 wxString msg = wxString::Format(
232 _(
"Could not load database library: settings file %s missing or invalid" ),
241 std::string
path( aSettingsPath.ToUTF8() );
254 wxASSERT_MSG( aSettingsPath ==
m_settings->GetFilename(),
255 "Path changed for database library without re-initializing plugin!" );
259 wxLogTrace(
traceDatabase, wxT(
"ensureSettings: no settings but no valid path!" ) );
266 wxCHECK_RET(
m_settings,
"Call ensureSettings before ensureConnection!" );
272 wxString msg = wxString::Format(
273 _(
"Could not load database library: could not connect to database %s (%s)" ),
283 wxCHECK_RET(
m_settings,
"Call ensureSettings before connect()!" );
290 if(
m_settings->m_Source.connection_string.empty() )
299 std::string cs =
m_settings->m_Source.connection_string;
300 std::string basePath( wxFileName(
m_settings->GetFilename() ).GetPath().ToUTF8() );
304 boost::replace_all( cs,
"${CWD}", basePath );
306 m_conn = std::make_unique<DATABASE_CONNECTION>( cs,
m_settings->m_Source.timeout );
309 if( !
m_conn->IsConnected() )
318 std::set<std::string> columns;
320 columns.insert( tableIter.
key_col );
332 columns.insert( field.
column );
334 m_conn->CacheTableInfo( tableIter.
table, columns );
346 bool val = std::any_cast<bool>( aVal );
349 catch(
const std::bad_any_cast& )
355 int val = std::any_cast<int>( aVal );
356 return static_cast<bool>( val );
358 catch(
const std::bad_any_cast& )
364 wxString strval( std::any_cast<std::string>( aVal ).c_str(), wxConvUTF8 );
366 if( strval.IsEmpty() )
371 for(
const auto& trueVal : { wxS(
"true" ), wxS(
"yes" ), wxS(
"y" ), wxS(
"1" ) } )
373 if( strval.Matches( trueVal ) )
377 for(
const auto& falseVal : { wxS(
"false" ), wxS(
"no" ), wxS(
"n" ), wxS(
"0" ) } )
379 if( strval.Matches( falseVal ) )
383 catch(
const std::bad_any_cast& )
402 std::string symbolIdStr = std::any_cast<std::string>( aRow.at( aTable.
symbols_col ) );
404 symbolId.
Parse( std::any_cast<std::string>( aRow.at( aTable.
symbols_col ) ) );
411 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: found original symbol '%s'" ),
418 wxLogTrace(
traceDatabase, wxT(
"loadSymboFromRow: source symbol id '%s' is invalid, "
419 "will create empty symbol" ), symbolIdStr );
423 wxLogTrace(
traceDatabase, wxT(
"loadSymboFromRow: source symbol '%s' not found, "
424 "will create empty symbol" ), symbolIdStr );
436 symbol->
SetName( aSymbolName );
443 std::string footprints = std::any_cast<std::string>( aRow.at( aTable.
footprints_col ) );
445 wxString footprintsStr = wxString( footprints.c_str(), wxConvUTF8 );
446 wxArrayString footprintsList;
447 wxStringTokenizer tokenizer( footprintsStr,
';' );
449 while( tokenizer.HasMoreTokens() )
450 footprintsList.Add( tokenizer.GetNextToken() );
452 if( footprintsList.size() > 0 )
459 wxLogTrace(
traceDatabase, wxT(
"loadSymboFromRow: footprint field %s not found." ),
473 wxString value( std::any_cast<std::string>( aRow.at( aTable.
properties.
keywords ) ).c_str(),
484 wxArrayString filters;
485 filters.push_back( value );
500 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: exclude_from_sim value for %s "
501 "could not be cast to a boolean" ), aSymbolName );
516 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: exclude_from_board value for %s "
517 "could not be cast to a boolean" ), aSymbolName );
532 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: exclude_from_bom value for %s "
533 "could not be cast to a boolean" ), aSymbolName );
537 std::vector<LIB_FIELD*> fields;
540 std::unordered_map<wxString, LIB_FIELD*> fieldsMap;
543 fieldsMap[field->GetName()] = field;
547 if( !aRow.count( mapping.
column ) )
549 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: field %s not found in result" ),
558 strValue = std::any_cast<std::string>( aRow.at( mapping.
column ) );
560 catch( std::bad_any_cast& e )
564 wxString value(
strValue.c_str(), wxConvUTF8 );
566 if( mapping.
name == wxT(
"Value" ) )
578 else if( mapping.
name == wxT(
"Datasheet" ) )
598 if( fieldsMap.count( mapping.
name ) )
600 field = fieldsMap[mapping.
name];
607 fieldsMap[mapping.
name] = field;
std::map< std::string, std::any > ROW
virtual void SetVisible(bool aVisible)
virtual void SetText(const wxString &aText)
Field object used in symbol libraries.
void SetAutoAdded(bool aAutoAdded)
void SetName(const wxString &aName)
Set a user definable field name to aName.
void SetNameShown(bool aShown=true)
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
bool IsValid() const
Check if this LID_ID is valid.
void SetSubLibraryName(const UTF8 &aName)
Define a library symbol object.
void SetSourceLibId(const LIB_ID &aLibId)
int GetNextAvailableFieldId() const
virtual LIB_SYMBOL * Duplicate() const
Create a copy of a LIB_SYMBOL and assigns unique KIIDs to the copy and its children.
LIB_FIELD & GetFootprintField()
Return reference to the footprint field.
void SetDescription(const wxString &aDescription)
Gets the Description field text value */.
void SetKeyWords(const wxString &aKeyWords)
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
LIB_FIELD & GetValueField()
Return reference to the value field.
void SetFPFilters(const wxArrayString &aFilters)
void AddField(LIB_FIELD *aField)
Add a field.
LIB_FIELD & GetDatasheetField()
Return reference to the datasheet field.
virtual void SetName(const wxString &aName)
void SetExcludedFromSim(bool aExcludeFromSim)
Set or clear the exclude from simulation flag.
void GetAvailableSymbolFields(std::vector< wxString > &aNames) override
Retrieves a list of (custom) field names that are present on symbols in this library.
static std::optional< bool > boolFromAny(const std::any &aVal)
std::unique_ptr< DATABASE_CONNECTION > m_conn
Generally will be null if no valid connection is established.
void GetSubLibraryNames(std::vector< wxString > &aNames) override
Retrieves a list of sub-libraries in this library.
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
void ensureSettings(const wxString &aSettingsPath)
bool TestConnection(wxString *aErrorMsg=nullptr)
std::set< wxString > m_defaultShownFields
std::set< wxString > m_customFields
LIB_SYMBOL * loadSymbolFromRow(const wxString &aSymbolName, const DATABASE_LIB_TABLE &aTable, const DATABASE_CONNECTION::ROW &aRow)
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const STRING_UTF8_MAP *aProperties=nullptr) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
void GetDefaultSymbolFields(std::vector< wxString > &aNames) override
Retrieves a list of (custom) field names that should be shown by default for this library in the symb...
virtual ~SCH_DATABASE_PLUGIN()
std::unique_ptr< DATABASE_LIB_SETTINGS > m_settings
SYMBOL_LIB_TABLE * m_libTable
A name/value tuple with unique names and optional values.
static const char * PropPowerSymsOnly
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
const char *const traceDatabase
#define THROW_IO_ERROR(msg)
static std::string strValue(double aValue)
bool visible_in_chooser
Whether the column is shown by default in the chooser.
std::string column
Database column name.
std::string name
KiCad field name.
bool inherit_properties
Whether or not to inherit properties from symbol field.
bool visible_on_add
Whether to show the field when placing the symbol.
bool show_name
Whether or not to show the field name as well as its value.
A database library table will be mapped to a sub-library provided by the database library entry in th...
std::string key_col
Unique key column name (will form part of the LIB_ID)
std::string name
KiCad library nickname (will form part of the LIB_ID)
std::string symbols_col
Column name containing KiCad symbol refs.
std::string footprints_col
Column name containing KiCad footprint refs.
std::vector< DATABASE_FIELD_MAPPING > fields
std::string table
Database table to pull content from.
MAPPABLE_SYMBOL_PROPERTIES properties
std::string footprint_filters
std::string exclude_from_sim
std::string exclude_from_board
std::string exclude_from_bom