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 ) );
224 if( aErrorMsg && ( !
m_conn || !
m_conn->IsConnected() ) )
238 wxString msg = wxString::Format(
239 _(
"Could not load database library: settings file %s missing or invalid" ),
248 std::string
path( aSettingsPath.ToUTF8() );
261 wxASSERT_MSG( aSettingsPath ==
m_settings->GetFilename(),
262 "Path changed for database library without re-initializing plugin!" );
266 wxLogTrace(
traceDatabase, wxT(
"ensureSettings: no settings but no valid path!" ) );
273 wxCHECK_RET(
m_settings,
"Call ensureSettings before ensureConnection!" );
279 wxString msg = wxString::Format(
280 _(
"Could not load database library: could not connect to database %s (%s)" ),
290 wxCHECK_RET(
m_settings,
"Call ensureSettings before connect()!" );
297 if(
m_settings->m_Source.connection_string.empty() )
306 std::string cs =
m_settings->m_Source.connection_string;
307 std::string basePath( wxFileName(
m_settings->GetFilename() ).GetPath().ToUTF8() );
311 boost::replace_all( cs,
"${CWD}", basePath );
313 m_conn = std::make_unique<DATABASE_CONNECTION>( cs,
m_settings->m_Source.timeout );
316 if( !
m_conn->IsConnected() )
332 bool val = std::any_cast<bool>( aVal );
335 catch(
const std::bad_any_cast& )
341 int val = std::any_cast<int>( aVal );
342 return static_cast<bool>( val );
344 catch(
const std::bad_any_cast& )
350 wxString strval( std::any_cast<std::string>( aVal ).c_str(), wxConvUTF8 );
352 if( strval.IsEmpty() )
357 for(
const auto& trueVal : { wxS(
"true" ), wxS(
"yes" ), wxS(
"y" ), wxS(
"1" ) } )
359 if( strval.Matches( trueVal ) )
363 for(
const auto& falseVal : { wxS(
"false" ), wxS(
"no" ), wxS(
"n" ), wxS(
"0" ) } )
365 if( strval.Matches( falseVal ) )
369 catch(
const std::bad_any_cast& )
388 std::string symbolIdStr = std::any_cast<std::string>( aRow.at( aTable.
symbols_col ) );
390 symbolId.
Parse( std::any_cast<std::string>( aRow.at( aTable.
symbols_col ) ) );
397 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: found original symbol '%s'" ),
404 wxLogTrace(
traceDatabase, wxT(
"loadSymboFromRow: source symbol id '%s' is invalid, "
405 "will create empty symbol" ), symbolIdStr );
409 wxLogTrace(
traceDatabase, wxT(
"loadSymboFromRow: source symbol '%s' not found, "
410 "will create empty symbol" ), symbolIdStr );
422 symbol->
SetName( aSymbolName );
430 std::string footprints = std::any_cast<std::string>( aRow.at( aTable.
footprints_col ) );
431 wxString footprint = wxString( footprints.c_str(), wxConvUTF8 ).BeforeFirst(
';' );
436 wxLogTrace(
traceDatabase, wxT(
"loadSymboFromRow: footprint field %s not found." ),
450 wxString value( std::any_cast<std::string>( aRow.at( aTable.
properties.
keywords ) ).c_str(),
461 wxArrayString filters;
462 filters.push_back( value );
477 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: exclude_from_board value for %s "
478 "could not be cast to a boolean" ), aSymbolName );
493 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: exclude_from_bom value for %s "
494 "could not be cast to a boolean" ), aSymbolName );
498 std::vector<LIB_FIELD*> fields;
501 std::unordered_map<wxString, LIB_FIELD*> fieldsMap;
504 fieldsMap[field->GetName()] = field;
508 if( !aRow.count( mapping.
column ) )
510 wxLogTrace(
traceDatabase, wxT(
"loadSymbolFromRow: field %s not found in result" ),
515 wxString value( std::any_cast<std::string>( aRow.at( mapping.
column ) ).c_str(),
518 if( mapping.
name == wxT(
"Value" ) )
530 else if( mapping.
name == wxT(
"Datasheet" ) )
550 if( fieldsMap.count( mapping.
name ) )
552 field = fieldsMap[mapping.
name];
559 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 SetIncludeOnBoard(bool aIncludeOnBoard)
Set or clear include in board netlist flag.
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)
void SetKeyWords(const wxString &aKeyWords)
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
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.
void SetIncludeInBom(bool aIncludeInBom)
Set or clear the include in schematic bill of materials flag.
virtual void SetName(const wxString &aName)
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)
bool CheckHeader(const wxString &aFileName) override
Return true if the first line in aFileName begins with the expected header.
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)
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_board
std::string exclude_from_bom