33#include <wx/filename.h>
50 bool aVisibleOnAdd,
bool aVisibleInChooser,
51 bool aShowName,
bool aInheritProperties ) :
54 name_wx( aName.c_str(), wxConvUTF8 ),
67 name_wx = wxString( aName.c_str(), wxConvUTF8 );
76static void patchKey( nlohmann::json& aObj,
const std::string& aKey,
const T& aValue,
const T& aParsed,
79 if( aValue == aParsed && ( aObj.contains( aKey ) || !aRequired ) )
82 if constexpr( std::is_same_v<T, std::string> )
84 if( aValue.empty() && !aRequired )
111 nlohmann::json out = aField.
source.is_object() ? aField.
source : nlohmann::json::object();
129 table.source = aEntry;
139 std::erase(
table.name,
'/' );
141 if( aEntry.contains(
"properties" ) && aEntry[
"properties"].is_object() )
143 const nlohmann::json& propJson = aEntry[
"properties"];
153 if( aEntry.contains(
"fields" ) && aEntry[
"fields"].is_array() )
155 for(
const nlohmann::json& fieldJson : aEntry[
"fields"] )
157 if( fieldJson.empty() || !fieldJson.is_object() )
170 nlohmann::json out = aTable.
source.is_object() ? aTable.
source : nlohmann::json::object();
182 bool hadProps = out.contains(
"properties" );
183 nlohmann::json propJson = hadProps ? out[
"properties"] : nlohmann::json::object();
186 if( props != oldProps && !propJson.is_object() )
187 propJson = nlohmann::json::object();
189 if( propJson.is_object() )
198 if( hadProps || !propJson.empty() )
199 out[
"properties"] = propJson;
202 if( !aTable.
fields.empty() || out.contains(
"fields" ) )
204 nlohmann::json fieldsJson = nlohmann::json::array();
210 bool fieldsEdited = aTable.
fields.size() != parsed.
fields.size();
212 for(
size_t i = 0; !fieldsEdited && i < aTable.
fields.size(); ++i )
215 if( fieldsEdited || !out.contains(
"fields" ) )
216 out[
"fields"] = fieldsJson;
237 &
m_Source.connection_string,
"" ) );
243 [&]() -> nlohmann::json
245 nlohmann::json libraries = nlohmann::json::array();
247 for( const DATABASE_LIB_TABLE& table : m_Tables )
248 libraries.push_back( tableToJson( table ) );
252 [&](
const nlohmann::json& aObj )
256 if( !aObj.is_array() )
259 for( const nlohmann::json& entry : aObj )
261 if( entry.empty() || !entry.is_object() )
264 m_Tables.emplace_back( tableFromJson( entry ) );
269 m_params.emplace_back(
new PARAM<int>(
"cache.max_size", &m_Cache.max_size, 256 ) );
271 m_params.emplace_back(
new PARAM<int>(
"cache.max_age", &m_Cache.max_age, 60 ) );
273 m_params.emplace_back(
new PARAM<bool>(
"globally_unique_keys", &m_GloballyUniqueKeys,
false ) );
275 registerMigration( 0, 1,
283 if( !Contains(
"libraries" ) || !At(
"libraries" ).is_array() )
286 for( nlohmann::json&
library : At(
"libraries" ) )
288 if( !
library.contains(
"fields" ) )
291 for(
const nlohmann::json& field :
library[
"fields"] )
293 if( !field.contains(
"name" ) || !field.contains(
"column" ) )
296 std::string
name = field[
"name"].get<std::string>();
297 std::string col = field[
"column"].get<std::string>();
299 if(
name ==
"ki_description" )
300 library[
"properties"][
"description"] = col;
301 else if(
name ==
"ki_fp_filters" )
302 library[
"properties"][
"footprint_filters"] = col;
320 nlohmann::json::json_pointer ptr( parent );
322 if( aInternals.contains( ptr ) && !aInternals[ptr].is_object() )
323 aInternals[ptr] = nlohmann::json::object();
346 if( !original.is_object() || original.empty() )
349 const std::vector<std::pair<std::string, bool>> unchanged = {
355 {
"source.connection_string",
m_Source.connection_string ==
m_loaded.source.connection_string },
362 std::set<std::string> editedParents;
364 for(
const auto& [
path, isUnchanged] : unchanged )
370 editedParents.insert( ptr.parent_pointer().to_string() );
374 if( original.contains( ptr ) )
376 else if(
Internals()->contains( ptr.parent_pointer() ) )
377 ( *
Internals() )[ptr.parent_pointer()].erase( ptr.back() );
383 nlohmann::json::json_pointer ptr( parent );
385 if( editedParents.contains( parent ) )
388 if( original.contains( ptr ) )
413 auto settings = std::make_unique<DATABASE_LIB_SETTINGS>( std::string( aPath.ToUTF8() ) );
416 settings->SetReadOnly(
true );
417 bool loaded = settings->LoadFromFile();
421 wxFileName
path( aPath );
425 *aLoaded = !
path.FileExists() || ( loaded &&
path.IsFileReadable() );
433 wxString
name = aLibName;
434 name.Trim(
true ).Trim(
false );
438 if(
name.IsEmpty() ||
name.find_first_not_of( wxS(
"._" ) ) == wxString::npos )
439 return wxS(
"database_library" );
447 return wxS(
"KiCad ODBC:" ) + wxString::FromUTF8( aSource.
dsn );
459 using NO_PROMPT_FN = bool ( * )(
const wxString&,
const wxString&, wxString& );
461 const NO_PROMPT_FN* target = aLookup.target<NO_PROMPT_FN>();
486 aPassword = secret.utf8_string();
504 wxString user = wxString::FromUTF8( aSource.
username );
506 if( aPassword.empty() )
bool m_GloballyUniqueKeys
static DATABASE_LIB_TABLE tableFromJson(const nlohmann::json &aEntry)
Missing or mistyped keys load as defaults so one incomplete entry cannot stop the others.
void ResolvePassword(const DATABASE_SECRET_LOOKUP &aLookup=nullptr)
Fills in the source password from the keyring when the file has none.
DATABASE_LIB_SETTINGS(const std::string &aFilename)
wxString getFileExt() const override
static DATABASE_FIELD_MAPPING fieldFromJson(const nlohmann::json &aEntry)
struct DATABASE_LIB_SETTINGS::LOADED_SCALARS m_loaded
bool Store() override
Stores parameters, then restores the raw file value of every scalar the caller left unchanged so that...
void Load() override
Records the scalars as loaded; runs before a schema migration writes the file back.
std::string m_Description
static nlohmann::json tableToJson(const DATABASE_LIB_TABLE &aTable)
DATABASE_CACHE_SETTINGS m_Cache
static nlohmann::json fieldToJson(const DATABASE_FIELD_MAPPING &aField)
static nlohmann::json::json_pointer PointerFromString(std::string aPath)
Builds a JSON pointer based on a given string.
const nlohmann::json & originalJson() const
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
JSON_SETTINGS_INTERNALS * Internals()
static ResultType fetchOrDefault(const nlohmann::json &aJson, const std::string &aKey, ResultType aDefault=ResultType())
Helper to retrieve a value from a JSON object (dictionary) as a certain result type.
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
virtual bool Store()
Stores the current parameters into the JSON document represented by this object Note: this doesn't do...
Like a normal param, but with custom getter and setter functions.
wxString DefaultDatabaseLibFileName(const wxString &aLibName)
const int dblibSchemaVersion
bool IsNoPromptSecretLookup(const DATABASE_SECRET_LOOKUP &aLookup)
static constexpr const char * c_scalarParents[]
Objects that hold scalar settings rather than library tables.
static void normalizeScalarParents(JSON_SETTINGS_INTERNALS &aInternals)
Nested params cannot store into a non-object parent, so replace a malformed one before storing.
static void patchKey(nlohmann::json &aObj, const std::string &aKey, const T &aValue, const T &aParsed, bool aRequired)
Writes aValue to aObj[aKey] only if it differs from aParsed, the value the raw key was read as.
std::unique_ptr< DATABASE_LIB_SETTINGS > LoadDatabaseLibSettingsReadOnly(const wxString &aPath, bool *aLoaded)
Loads a database library settings file without allowing the load itself (e.g.
static wxString passwordService(const DATABASE_SOURCE &aSource)
void ResolveDatabasePassword(DATABASE_SOURCE &aSource, const DATABASE_SECRET_LOOKUP &aLookup)
Fills in the source password from the keyring, but only when the library file did not supply one.
static bool hasKeyringLogin(const DATABASE_SOURCE &aSource)
bool StoreDatabasePassword(const DATABASE_SOURCE &aSource, const std::string &aPassword)
Stores the password for the source's DSN login in the system keyring, or removes the entry when the p...
DATABASE_SECRET_LOOKUP DefaultDatabaseSecretLookup()
The lookup used when none is injected, which must never prompt to unlock the keyring.
bool GetDatabasePassword(const DATABASE_SOURCE &aSource, std::string &aPassword, const DATABASE_SECRET_LOOKUP &aLookup)
DSN passwords that are not saved in the (often shared) library file live in the system keyring,...
KICOMMON_API void ResolveDatabasePassword(DATABASE_SOURCE &aSource, const DATABASE_SECRET_LOOKUP &aLookup=nullptr)
Fills in the source password from the keyring, but only when the library file did not supply one.
std::function< bool(const wxString &aService, const wxString &aKey, wxString &aSecret)> DATABASE_SECRET_LOOKUP
Keyring lookup signature, matching KIPLATFORM::SECRETS::GetSecretNoPrompt.
static const std::string DatabaseLibraryFileExtension
bool ReplaceIllegalFileNameChars(std::string &aName, int aReplaceChar)
Checks aName for illegal file name characters.
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.
void SetName(const std::string &aName)
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.
nlohmann::json source
Raw JSON as loaded; untouched keys are written back verbatim.
wxString name_wx
KiCad field name (converted)
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)
nlohmann::json source
Raw JSON as loaded; untouched keys are written back verbatim.
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 pins_col
Column name containing JSON pin assignments (optional)
std::string connection_string
std::string footprint_filters
std::string exclude_from_sim
std::string exclude_from_board
std::string exclude_from_bom
Definition of file extensions used in Kicad.