mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-20 11:48:30 -06:00
Add structure to map migrated preferences to old ones
This can be used to keep both in sync in the period between initial migration and eventual obsolence. Note only non-obsoleted, migrated preferences are tracked. We don't want to resync preferences that have been obsoleted (reset). That would nullify the whole idea of making them obsolete for future removal. This commit only adds the mapping, synching will follow in a future commit.
This commit is contained in:
parent
16184daf95
commit
c6103a5c17
@ -41,6 +41,7 @@ extern "C" {
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
namespace bpt = boost::property_tree;
|
||||
|
||||
@ -57,6 +58,10 @@ static GHashTable *registered_handlers_hash = NULL;
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = "gnc.app-utils.gsettings";
|
||||
|
||||
using pref_id = std::pair<std::string, std::string>;
|
||||
|
||||
static std::map<pref_id, pref_id> oldkeys_map;
|
||||
|
||||
/************************************************************/
|
||||
/* Internal helper functions */
|
||||
/************************************************************/
|
||||
@ -313,7 +318,9 @@ void gnc_gsettings_bind (const gchar *schema,
|
||||
g_return_if_fail (G_IS_SETTINGS (settings_ptr));
|
||||
|
||||
if (gnc_gsettings_is_valid_key (settings_ptr, key))
|
||||
{
|
||||
g_settings_bind (settings_ptr, key, object, property, G_SETTINGS_BIND_DEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
PERR ("Invalid key %s for schema %s", key, schema);
|
||||
@ -687,6 +694,10 @@ migrate_one_key (const opt_str_vec &oldpath, const opt_str_vec &oldkey,
|
||||
auto user_value = gnc_gsettings_get_user_value (oldpath->c_str(), oldkey->c_str());
|
||||
if (user_value)
|
||||
gnc_gsettings_set_value (newpath->c_str(), newkey->c_str(), user_value);
|
||||
|
||||
/* Add old preference to oldkeys_map so we can keep it in sync with its replacement */
|
||||
oldkeys_map.emplace (std::make_pair(*oldpath, *oldkey),
|
||||
std::make_pair(*newpath, *newkey));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -700,6 +711,9 @@ obsolete_one_key (const opt_str_vec &oldpath, const opt_str_vec &oldkey)
|
||||
|
||||
PINFO ("Resetting obsolete '%s:%s'", oldpath->c_str(), oldkey->c_str());
|
||||
gnc_gsettings_reset (oldpath->c_str(), oldkey->c_str());
|
||||
|
||||
/* Removve old preference to oldkeys_map. It's been reset we don't want to keep it in synch any more */
|
||||
oldkeys_map.erase (std::make_pair(*oldpath, *oldkey));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -723,10 +737,39 @@ parse_one_release_node (bpt::ptree &pt)
|
||||
obsolete_one_key (node.second.get_optional<std::string> ("<xmlattr>.old-path"),
|
||||
node.second.get_optional<std::string> ("<xmlattr>.old-key"));
|
||||
else
|
||||
{
|
||||
DEBUG ("Skipping unknown node <%s>", node.first.c_str());
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
update_oldkeys_only (bpt::ptree &pt)
|
||||
{
|
||||
/* handles oldkey tracking for release nodes that don't require full processing
|
||||
* any more (when the preference db compatibility level is higher than what's in
|
||||
* this release node)
|
||||
* But even for those nodes we need to extract old preference ids to potentially
|
||||
* keep them in sync with their replacements
|
||||
*/
|
||||
|
||||
std::for_each (pt.begin(), pt.end(),
|
||||
[] (std::pair<bpt::ptree::key_type, bpt::ptree> node)
|
||||
{
|
||||
auto oldpath = node.second.get_optional<std::string> ("<xmlattr>.old-path");
|
||||
auto oldkey = node.second.get_optional<std::string> ("<xmlattr>.old-key");
|
||||
auto newpath = node.second.get_optional<std::string> ("<xmlattr>.new-path");
|
||||
auto newkey = node.second.get_optional<std::string> ("<xmlattr>.new-key");
|
||||
|
||||
if ((node.first == "<xmlattr>") || (node.first == "deprecate"))
|
||||
return;
|
||||
}
|
||||
else if (node.first == "migrate")
|
||||
/* Add old preference to oldkeys_map so we can keep it in sync with its replacement */
|
||||
oldkeys_map.emplace (std::make_pair(*oldpath, *oldkey),
|
||||
std::make_pair(*newpath, *newkey));
|
||||
else if (node.first == "obsolete")
|
||||
/* Removve old preference to oldkeys_map. It's been reset we don't want to keep it in synch any more */
|
||||
oldkeys_map.erase (std::make_pair(*oldpath, *oldkey));
|
||||
else
|
||||
DEBUG ("Skipping unknown node <%s>", node.first.c_str());
|
||||
});
|
||||
}
|
||||
|
||||
@ -751,13 +794,13 @@ transform_settings (int old_maj_min)
|
||||
bpt::read_xml (transform_stream, pt);
|
||||
}
|
||||
catch (bpt::xml_parser_error &e) {
|
||||
PWARN ("Failed to parse GnuCash preferences transformation file.\n");
|
||||
PWARN ("Error message:\n");
|
||||
PWARN ("%s\n", e.what());
|
||||
PWARN ("Failed to parse GnuCash preferences transformation file.");
|
||||
PWARN ("Error message:");
|
||||
PWARN ("%s", e.what());
|
||||
return;
|
||||
}
|
||||
catch (...) {
|
||||
PWARN ("Unknown error while parsing GnuCash preferences transformation file.\n");
|
||||
PWARN ("Unknown error while parsing GnuCash preferences transformation file.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -776,15 +819,36 @@ transform_settings (int old_maj_min)
|
||||
DEBUG ("Skipping <release> node - no version attribute found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*version <= old_maj_min)
|
||||
{
|
||||
DEBUG ("Skipping <release> node - version %i is less than current compatibility level %i", *version, old_maj_min);
|
||||
return;
|
||||
DEBUG ("Already processed <release> node with version %i (current compatibility level %i). Extracting old preferences only.",
|
||||
*version, old_maj_min);
|
||||
update_oldkeys_only (node.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG ("Found <release> node with version %i (current compatibility level %i). Processing child nodes.",
|
||||
*version, old_maj_min);
|
||||
parse_one_release_node (node.second);
|
||||
}
|
||||
DEBUG ("Retrieved version value '%i'", *version);
|
||||
|
||||
parse_one_release_node (node.second);
|
||||
});
|
||||
|
||||
/* oldkeys_map is generated oldkey->newkey for efficiency reasons but for
|
||||
* subesquent use we need newkey->oldkey. So let's swap keys and values now. */
|
||||
std::map<pref_id, pref_id> tmp_map;
|
||||
std::for_each (oldkeys_map.begin(), oldkeys_map.end(),
|
||||
[&tmp_map] (auto map_it)
|
||||
{
|
||||
tmp_map.emplace (map_it.second, map_it.first);
|
||||
DEBUG ("Added new pref-> old_pref mapping for %s:%s -> %s:%s",
|
||||
map_it.second.first.c_str(),
|
||||
map_it.second.second.c_str(),
|
||||
map_it.first.first.c_str(),
|
||||
map_it.first.second.c_str());
|
||||
});
|
||||
oldkeys_map = tmp_map;
|
||||
|
||||
}
|
||||
|
||||
void gnc_gsettings_version_upgrade (void)
|
||||
|
Loading…
Reference in New Issue
Block a user