Performance optimizations for database libraries.
This commit is contained in:
parent
3e26e7b646
commit
e68df8e1d1
|
@ -448,7 +448,7 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||||
{
|
{
|
||||||
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
|
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
|
||||||
}
|
}
|
||||||
catch( nanodbc::null_access_error& e )
|
catch( nanodbc::null_access_error& )
|
||||||
{
|
{
|
||||||
// Column was empty (null)
|
// Column was empty (null)
|
||||||
aResult[column] = std::string();
|
aResult[column] = std::string();
|
||||||
|
@ -498,6 +498,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||||
{
|
{
|
||||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
|
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
|
||||||
|
|
||||||
|
aResults.reserve( cacheEntry.size() );
|
||||||
|
|
||||||
for( auto &[ key, row ] : cacheEntry )
|
for( auto &[ key, row ] : cacheEntry )
|
||||||
aResults.emplace_back( row );
|
aResults.emplace_back( row );
|
||||||
|
|
||||||
|
@ -605,7 +607,7 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||||
{
|
{
|
||||||
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
|
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
|
||||||
}
|
}
|
||||||
catch( nanodbc::null_access_error& e )
|
catch( nanodbc::null_access_error& )
|
||||||
{
|
{
|
||||||
// Column was empty (null)
|
// Column was empty (null)
|
||||||
result[column] = std::string();
|
result[column] = std::string();
|
||||||
|
|
|
@ -32,6 +32,17 @@
|
||||||
const int dblibSchemaVersion = 1;
|
const int dblibSchemaVersion = 1;
|
||||||
|
|
||||||
|
|
||||||
|
DATABASE_FIELD_MAPPING::DATABASE_FIELD_MAPPING( std::string aColumn, std::string aName,
|
||||||
|
bool aVisibleOnAdd, bool aVisibleInChooser,
|
||||||
|
bool aShowName, bool aInheritProperties ) :
|
||||||
|
column( aColumn ),
|
||||||
|
name( aName ), name_wx( aName.c_str(), wxConvUTF8 ), visible_on_add( aVisibleOnAdd ),
|
||||||
|
visible_in_chooser( aVisibleInChooser ), show_name( aShowName ),
|
||||||
|
inherit_properties( aInheritProperties )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||||
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, dblibSchemaVersion )
|
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, dblibSchemaVersion )
|
||||||
{
|
{
|
||||||
|
@ -113,11 +124,8 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||||
bool inherit = fetchOrDefault<bool>( fieldJson, "inherit_properties" );
|
bool inherit = fetchOrDefault<bool>( fieldJson, "inherit_properties" );
|
||||||
|
|
||||||
table.fields.emplace_back(
|
table.fields.emplace_back(
|
||||||
DATABASE_FIELD_MAPPING(
|
DATABASE_FIELD_MAPPING( column, name, visible_on_add,
|
||||||
{
|
visible_in_chooser, show_name, inherit ) );
|
||||||
column, name, visible_on_add, visible_in_chooser, show_name,
|
|
||||||
inherit
|
|
||||||
} ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -313,40 +313,40 @@ wxString UnescapeString( const wxString& aSource )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
token.append( ch );
|
token << ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !terminated )
|
if( !terminated )
|
||||||
{
|
{
|
||||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) );
|
newbuf << wxT( "{" ) << UnescapeString( token );
|
||||||
}
|
}
|
||||||
else if( prev == '$' || prev == '~' || prev == '^' || prev == '_' )
|
else if( prev == '$' || prev == '~' || prev == '^' || prev == '_' )
|
||||||
{
|
{
|
||||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
newbuf << wxT( "{" ) << UnescapeString( token ) << wxT( "}" );
|
||||||
}
|
}
|
||||||
else if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
|
else if( token == wxT( "dblquote" ) ) newbuf << wxT( "\"" );
|
||||||
else if( token == wxT( "quote" ) ) newbuf.append( wxT( "'" ) );
|
else if( token == wxT( "quote" ) ) newbuf << wxT( "'" );
|
||||||
else if( token == wxT( "lt" ) ) newbuf.append( wxT( "<" ) );
|
else if( token == wxT( "lt" ) ) newbuf << wxT( "<" );
|
||||||
else if( token == wxT( "gt" ) ) newbuf.append( wxT( ">" ) );
|
else if( token == wxT( "gt" ) ) newbuf << wxT( ">" );
|
||||||
else if( token == wxT( "backslash" ) ) newbuf.append( wxT( "\\" ) );
|
else if( token == wxT( "backslash" ) ) newbuf << wxT( "\\" );
|
||||||
else if( token == wxT( "slash" ) ) newbuf.append( wxT( "/" ) );
|
else if( token == wxT( "slash" ) ) newbuf << wxT( "/" );
|
||||||
else if( token == wxT( "bar" ) ) newbuf.append( wxT( "|" ) );
|
else if( token == wxT( "bar" ) ) newbuf << wxT( "|" );
|
||||||
else if( token == wxT( "comma" ) ) newbuf.append( wxT( "," ) );
|
else if( token == wxT( "comma" ) ) newbuf << wxT( "," );
|
||||||
else if( token == wxT( "colon" ) ) newbuf.append( wxT( ":" ) );
|
else if( token == wxT( "colon" ) ) newbuf << wxT( ":" );
|
||||||
else if( token == wxT( "space" ) ) newbuf.append( wxT( " " ) );
|
else if( token == wxT( "space" ) ) newbuf << wxT( " " );
|
||||||
else if( token == wxT( "dollar" ) ) newbuf.append( wxT( "$" ) );
|
else if( token == wxT( "dollar" ) ) newbuf << wxT( "$" );
|
||||||
else if( token == wxT( "tab" ) ) newbuf.append( wxT( "\t" ) );
|
else if( token == wxT( "tab" ) ) newbuf << wxT( "\t" );
|
||||||
else if( token == wxT( "return" ) ) newbuf.append( wxT( "\n" ) );
|
else if( token == wxT( "return" ) ) newbuf << wxT( "\n" );
|
||||||
else if( token == wxT( "brace" ) ) newbuf.append( wxT( "{" ) );
|
else if( token == wxT( "brace" ) ) newbuf << wxT( "{" );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
newbuf << wxT( "{" ) << UnescapeString( token ) << wxT( "}" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newbuf.append( ch );
|
newbuf << ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,11 +785,14 @@ int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreC
|
||||||
// Any numerical comparisons to here are identical.
|
// Any numerical comparisons to here are identical.
|
||||||
if( aIgnoreCase )
|
if( aIgnoreCase )
|
||||||
{
|
{
|
||||||
if( wxToupper( c1 ) < wxToupper( c2 ) )
|
if( c1 != c2 )
|
||||||
return -1;
|
{
|
||||||
|
wxUniChar uc1 = wxToupper( c1 );
|
||||||
|
wxUniChar uc2 = wxToupper( c2 );
|
||||||
|
|
||||||
if( wxToupper( c1 ) > wxToupper( c2 ) )
|
if( uc1 != uc2 )
|
||||||
return 1;
|
return uc1 < uc2 ? -1 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,8 +54,16 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTra
|
||||||
case FOOTPRINT_FIELD: return s_CanonicalFootprint; // The footprint for use with Pcbnew
|
case FOOTPRINT_FIELD: return s_CanonicalFootprint; // The footprint for use with Pcbnew
|
||||||
case DATASHEET_FIELD: return s_CanonicalDatasheet; // Link to a datasheet for symbol
|
case DATASHEET_FIELD: return s_CanonicalDatasheet; // Link to a datasheet for symbol
|
||||||
case DESCRIPTION_FIELD: return s_CanonicalDescription; // The symbol description
|
case DESCRIPTION_FIELD: return s_CanonicalDescription; // The symbol description
|
||||||
default: return wxString::Format( wxT( "Field%d" ), aFieldNdx );
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString str( wxS( "Field" ) );
|
||||||
|
#if wxUSE_UNICODE_WCHAR
|
||||||
|
str << std::to_wstring( aFieldNdx );
|
||||||
|
#else
|
||||||
|
str << std::to_string( aFieldNdx );
|
||||||
|
#endif
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( aFieldNdx )
|
switch( aFieldNdx )
|
||||||
|
|
|
@ -568,6 +568,9 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
for( LIB_FIELD* field : fields )
|
for( LIB_FIELD* field : fields )
|
||||||
fieldsMap[field->GetName()] = field;
|
fieldsMap[field->GetName()] = field;
|
||||||
|
|
||||||
|
static const wxString c_valueFieldName( wxS( "Value" ) );
|
||||||
|
static const wxString c_datasheetFieldName( wxS( "Datasheet" ) );
|
||||||
|
|
||||||
for( const DATABASE_FIELD_MAPPING& mapping : aTable.fields )
|
for( const DATABASE_FIELD_MAPPING& mapping : aTable.fields )
|
||||||
{
|
{
|
||||||
if( !aRow.count( mapping.column ) )
|
if( !aRow.count( mapping.column ) )
|
||||||
|
@ -577,7 +580,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std:: string strValue;
|
std::string strValue;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -589,7 +592,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
|
|
||||||
wxString value( strValue.c_str(), wxConvUTF8 );
|
wxString value( strValue.c_str(), wxConvUTF8 );
|
||||||
|
|
||||||
if( mapping.name == wxT( "Value" ) )
|
if( mapping.name_wx == c_valueFieldName )
|
||||||
{
|
{
|
||||||
LIB_FIELD& field = symbol->GetValueField();
|
LIB_FIELD& field = symbol->GetValueField();
|
||||||
field.SetText( value );
|
field.SetText( value );
|
||||||
|
@ -601,7 +604,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if( mapping.name == wxT( "Datasheet" ) )
|
else if( mapping.name_wx == c_datasheetFieldName )
|
||||||
{
|
{
|
||||||
LIB_FIELD& field = symbol->GetDatasheetField();
|
LIB_FIELD& field = symbol->GetDatasheetField();
|
||||||
field.SetText( value );
|
field.SetText( value );
|
||||||
|
@ -621,16 +624,16 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
LIB_FIELD* field;
|
LIB_FIELD* field;
|
||||||
bool isNew = false;
|
bool isNew = false;
|
||||||
|
|
||||||
if( fieldsMap.count( mapping.name ) )
|
if( fieldsMap.count( mapping.name_wx ) )
|
||||||
{
|
{
|
||||||
field = fieldsMap[mapping.name];
|
field = fieldsMap[mapping.name_wx];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
field = new LIB_FIELD( symbol->GetNextAvailableFieldId() );
|
field = new LIB_FIELD( symbol->GetNextAvailableFieldId() );
|
||||||
field->SetName( mapping.name );
|
field->SetName( mapping.name_wx );
|
||||||
isNew = true;
|
isNew = true;
|
||||||
fieldsMap[mapping.name] = field;
|
fieldsMap[mapping.name_wx] = field;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !mapping.inherit_properties || isNew )
|
if( !mapping.inherit_properties || isNew )
|
||||||
|
@ -643,13 +646,15 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
field->SetText( value );
|
field->SetText( value );
|
||||||
|
|
||||||
if( isNew )
|
if( isNew )
|
||||||
symbol->AddField( field );
|
symbol->AddDrawItem( field, false );
|
||||||
|
|
||||||
m_customFields.insert( mapping.name );
|
m_customFields.insert( mapping.name_wx );
|
||||||
|
|
||||||
if( mapping.visible_in_chooser )
|
if( mapping.visible_in_chooser )
|
||||||
m_defaultShownFields.insert( mapping.name );
|
m_defaultShownFields.insert( mapping.name_wx );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symbol->GetDrawItems().sort();
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1644,12 +1644,21 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
wxString prefix = aSymbol.GetPrefix();
|
wxString prefix = aSymbol.GetPrefix();
|
||||||
T_field* valueField = aSymbol.FindField( wxT( "Value" ) );
|
T_field* valueField = aSymbol.FindField( wxT( "Value" ) );
|
||||||
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
||||||
|
bool sourcePinsSorted = false;
|
||||||
|
|
||||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
auto lazySortSourcePins = [&sourcePins, &sourcePinsSorted]()
|
||||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
{
|
||||||
{
|
if( !sourcePinsSorted )
|
||||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
{
|
||||||
} );
|
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||||
|
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||||
|
{
|
||||||
|
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
sourcePinsSorted = true;
|
||||||
|
};
|
||||||
|
|
||||||
FIELD_INFO deviceInfo;
|
FIELD_INFO deviceInfo;
|
||||||
FIELD_INFO modelInfo;
|
FIELD_INFO modelInfo;
|
||||||
|
@ -1740,6 +1749,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
|
|
||||||
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
|
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
|
||||||
|
|
||||||
|
lazySortSourcePins();
|
||||||
|
|
||||||
if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
|
if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
|
||||||
{
|
{
|
||||||
if( pinIndexes[0] == wxT( "2" ) )
|
if( pinIndexes[0] == wxT( "2" ) )
|
||||||
|
@ -1800,6 +1811,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
model = model.BeforeFirst( ' ', &modelLineParams );
|
model = model.BeforeFirst( ' ', &modelLineParams );
|
||||||
modelInfo.m_Text = model;
|
modelInfo.m_Text = model;
|
||||||
|
|
||||||
|
lazySortSourcePins();
|
||||||
|
|
||||||
SIM_LIBRARY::MODEL simModel = libMgr.CreateModel( lib, model.ToStdString(),
|
SIM_LIBRARY::MODEL simModel = libMgr.CreateModel( lib, model.ToStdString(),
|
||||||
emptyFields, sourcePins, reporter );
|
emptyFields, sourcePins, reporter );
|
||||||
|
|
||||||
|
@ -1873,6 +1886,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
|
|
||||||
if( pinMapInfo.IsEmpty() )
|
if( pinMapInfo.IsEmpty() )
|
||||||
{
|
{
|
||||||
|
lazySortSourcePins();
|
||||||
|
|
||||||
// Generate a default pin map from the SIM_MODEL's pins
|
// Generate a default pin map from the SIM_MODEL's pins
|
||||||
simModel->createPins( sourcePins );
|
simModel->createPins( sourcePins );
|
||||||
pinMapInfo.m_Text = wxString( simModel->Serializer().GeneratePins() );
|
pinMapInfo.m_Text = wxString( simModel->Serializer().GeneratePins() );
|
||||||
|
@ -1979,7 +1994,10 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
// the default pin map from the symbol's pins.
|
// the default pin map from the symbol's pins.
|
||||||
|
|
||||||
if( pinMapInfo.IsEmpty() )
|
if( pinMapInfo.IsEmpty() )
|
||||||
|
{
|
||||||
|
lazySortSourcePins();
|
||||||
pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
|
pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !pinMapInfo.IsEmpty() )
|
if( !pinMapInfo.IsEmpty() )
|
||||||
|
|
|
@ -163,13 +163,15 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
|
||||||
if( !parentDesc.IsEmpty() )
|
if( !parentDesc.IsEmpty() )
|
||||||
desc = wxString::Format( wxT( "%s (%s)" ), parentDesc, lib );
|
desc = wxString::Format( wxT( "%s (%s)" ), parentDesc, lib );
|
||||||
|
|
||||||
|
UTF8 utf8Lib( lib );
|
||||||
|
|
||||||
std::vector<LIB_SYMBOL*> symbols;
|
std::vector<LIB_SYMBOL*> symbols;
|
||||||
|
|
||||||
std::copy_if( libSymbols.begin(), libSymbols.end(),
|
std::copy_if( libSymbols.begin(), libSymbols.end(),
|
||||||
std::back_inserter( symbols ),
|
std::back_inserter( symbols ),
|
||||||
[&lib]( LIB_SYMBOL* aSym )
|
[&utf8Lib]( LIB_SYMBOL* aSym )
|
||||||
{
|
{
|
||||||
return lib.IsSameAs( aSym->GetLibId().GetSubLibraryName() );
|
return utf8Lib == aSym->GetLibId().GetSubLibraryName();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
addFunc( name, symbols, desc );
|
addFunc( name, symbols, desc );
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define KICAD_DATABASE_LIB_SETTINGS_H
|
#define KICAD_DATABASE_LIB_SETTINGS_H
|
||||||
|
|
||||||
#include <settings/json_settings.h>
|
#include <settings/json_settings.h>
|
||||||
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
|
||||||
enum class DATABASE_SOURCE_TYPE
|
enum class DATABASE_SOURCE_TYPE
|
||||||
|
@ -44,12 +45,17 @@ struct DATABASE_SOURCE
|
||||||
|
|
||||||
struct DATABASE_FIELD_MAPPING
|
struct DATABASE_FIELD_MAPPING
|
||||||
{
|
{
|
||||||
std::string column; ///< Database column name
|
const std::string column; ///< Database column name
|
||||||
std::string name; ///< KiCad field name
|
const std::string name; ///< KiCad field name
|
||||||
bool visible_on_add; ///< Whether to show the field when placing the symbol
|
const wxString name_wx; ///< KiCad field name (converted)
|
||||||
bool visible_in_chooser; ///< Whether the column is shown by default in the chooser
|
const 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
|
const bool visible_in_chooser; ///< Whether the column is shown by default in the chooser
|
||||||
bool inherit_properties; ///< Whether or not to inherit properties from symbol field
|
const bool show_name; ///< Whether or not to show the field name as well as its value
|
||||||
|
const bool inherit_properties; ///< Whether or not to inherit properties from symbol field
|
||||||
|
|
||||||
|
explicit DATABASE_FIELD_MAPPING( std::string aColumn, std::string aName, bool aVisibleOnAdd,
|
||||||
|
bool aVisibleInChooser, bool aShowName,
|
||||||
|
bool aInheritProperties );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue