mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
GSettings - widen scope from 'migration' to 'transformation'
This commit mostly changes descriptions and variable names to use the more generic terms 'transformations' or 'conversions'. 'migration' is only one possible transform, future commits will add others. There are no functional changes in this commit other than a logic inversion in parse_one_release_node. It now checks for nodes named 'migrate' rather than for nodes not named 'migrate' (the code is adapted accordingly to match this logic change).
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
set(SCHEMADIR_BUILD ${DATADIR_BUILD}/glib-2.0/schemas)
|
||||
file(MAKE_DIRECTORY ${SCHEMADIR_BUILD})
|
||||
unset(gschema_depends CACHE)
|
||||
unset(gschema_migration_files CACHE)
|
||||
unset(gschema_preftrans_files CACHE)
|
||||
# The subdirectories
|
||||
add_subdirectory (gnome)
|
||||
add_subdirectory (gnome-utils)
|
||||
|
||||
@@ -22,20 +22,21 @@ set(gschema_SOURCES
|
||||
|
||||
add_gschema_targets("${gschema_SOURCES}")
|
||||
|
||||
set(local_migration_files ${gschema_migration_files})
|
||||
list(APPEND local_migration_files ${CMAKE_CURRENT_SOURCE_DIR}/migratable-prefs.xml)
|
||||
set(gschema_migration_files ${local_migration_files} CACHE INTERNAL "gschema migration files")
|
||||
set(local_preftrans_files ${gschema_preftrans_files})
|
||||
list(APPEND local_preftrans_files ${CMAKE_CURRENT_SOURCE_DIR}/pref_transformations.xml)
|
||||
set(gschema_preftrans_files ${local_preftrans_files} CACHE INTERNAL "files describing transformations for our gsettings based preferences")
|
||||
|
||||
# Provide gnucash runtime with a list of migratable preferences
|
||||
# Provide gnucash runtime with a list of potential transformations to user set preferences
|
||||
# following GSettings schema changes between gnucash releases
|
||||
add_custom_command(
|
||||
OUTPUT ${DATADIR_BUILD}/${PROJECT_NAME}/migratable-prefs.xml
|
||||
COMMAND cat ${gschema_migration_files} > ${DATADIR_BUILD}/${PROJECT_NAME}/migratable-prefs.xml
|
||||
DEPENDS ${gschema_migration_files}
|
||||
OUTPUT ${DATADIR_BUILD}/${PROJECT_NAME}/pref_transformations.xml
|
||||
COMMAND cat ${gschema_preftrans_files} > ${DATADIR_BUILD}/${PROJECT_NAME}/pref_transformations.xml
|
||||
DEPENDS ${gschema_preftrans_files}
|
||||
)
|
||||
|
||||
add_custom_target(migratable-prefs ALL DEPENDS ${DATADIR_BUILD}/${PROJECT_NAME}/migratable-prefs.xml)
|
||||
add_custom_target(pref_transformations ALL DEPENDS ${DATADIR_BUILD}/${PROJECT_NAME}/pref_transformations.xml)
|
||||
|
||||
install(FILES ${DATADIR_BUILD}/${PROJECT_NAME}/migratable-prefs.xml
|
||||
install(FILES ${DATADIR_BUILD}/${PROJECT_NAME}/pref_transformations.xml
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME})
|
||||
|
||||
# Handle gschemas.compiled
|
||||
@@ -65,7 +66,7 @@ if (COMPILE_GSCHEMAS)
|
||||
${GLIB_COMPILE_SCHEMAS} --strict \$ENV\{DESTDIR\}${CMAKE_INSTALL_FULL_DATADIR}/glib-2.0/schemas\")")
|
||||
endif()
|
||||
|
||||
set(gschemas_DIST_local migratable-prefs.xml)
|
||||
set(gschemas_DIST_local pref_transformations.xml)
|
||||
foreach(file ${gschema_SOURCES})
|
||||
list(APPEND gschemas_DIST_local ${file}.in)
|
||||
endforeach()
|
||||
|
||||
@@ -1,3 +1,48 @@
|
||||
<!-- GSettings preference transformation rules
|
||||
|
||||
This xml file describes rules to transform the user's GSettings based
|
||||
preferences following schema changes between GnuCash versions. These
|
||||
rules are evaluated and (optionally) executed at runtime in order to
|
||||
dynamically make changes to the user's preferences to adapt them to the
|
||||
current version of GnuCash.
|
||||
|
||||
An example of such a transformation is changing the name of a preference.
|
||||
While the user may have set a value for the old name, without any
|
||||
additional work the new name would only be set to the default. As a result
|
||||
the user would experience a reset of the preference.
|
||||
By adding a migration rule here, GnuCash will copy the value from the old
|
||||
name to the new name at startup and hence for the user the name change
|
||||
becomes transparent.
|
||||
|
||||
All rules are grouped within 'release' nodes. Such nodes describe the
|
||||
GnuCash version in which the related schema changes first happened.
|
||||
GnuCash will use this information to check at runtime whether the enclosed
|
||||
rules should still be executed.
|
||||
The format of a release node is as follows:
|
||||
|
||||
<release version="encoded_version">
|
||||
...
|
||||
</releaase>
|
||||
|
||||
encoded_version = gnucash_major * 1000 + gnucash_minor
|
||||
For example for gnucash 4.7 encoded_version becomes 4 * 1000 + 7 = 4007
|
||||
|
||||
Within a release node the following rules are currently supported:
|
||||
|
||||
<migrate old-path="org.gnucash.general"
|
||||
old-key="prefs-version"
|
||||
new-path="org.gnucash.GnuCash.general"
|
||||
new-key="prefs-version" />
|
||||
|
||||
This will migrate the preference at old-path:old-key to new-path:new-key.
|
||||
|
||||
|
||||
Note
|
||||
====
|
||||
Do not remove this file from the GnuCash sources even if there are
|
||||
currently no active rules. Instead keep this introductory comment in
|
||||
place and remove all other content.
|
||||
-->
|
||||
|
||||
<release version="4007">
|
||||
|
||||
@@ -4,13 +4,13 @@ if (WITH_AQBANKING)
|
||||
|
||||
add_gschema_targets("${aqb_GSCHEMA}")
|
||||
|
||||
set(local_migration_files ${gschema_migration_files})
|
||||
list(APPEND local_migration_files ${CMAKE_CURRENT_SOURCE_DIR}/migratable-prefs.xml)
|
||||
set(gschema_migration_files ${local_migration_files} CACHE INTERNAL "gschema migration files")
|
||||
set(local_preftrans_files ${gschema_preftrans_files})
|
||||
list(APPEND local_preftrans_files ${CMAKE_CURRENT_SOURCE_DIR}/pref_transformations.xml)
|
||||
set(gschema_preftrans_files ${local_preftrans_files} CACHE INTERNAL "files describing transformations for our gsettings based preferences")
|
||||
endif()
|
||||
|
||||
set_dist_list(aqbanking_gschema_DIST
|
||||
CMakeLists.txt
|
||||
migratable-prefs.xml
|
||||
pref_transformations.xml
|
||||
org.gnucash.GnuCash.dialogs.import.hbci.gschema.xml.in
|
||||
org.gnucash.GnuCash.dialogs.flicker.gschema.xml.in)
|
||||
|
||||
@@ -4,12 +4,12 @@ if (WITH_OFX)
|
||||
|
||||
add_gschema_targets("${ofx_GSCHEMA}")
|
||||
|
||||
set(local_migration_files ${gschema_migration_files})
|
||||
list(APPEND local_migration_files ${CMAKE_CURRENT_SOURCE_DIR}/migratable-prefs.xml)
|
||||
set(gschema_migration_files ${local_migration_files} CACHE INTERNAL "gschema migration files")
|
||||
set(local_preftrans_files ${gschema_preftrans_files})
|
||||
list(APPEND local_preftrans_files ${CMAKE_CURRENT_SOURCE_DIR}/pref_transformations.xml)
|
||||
set(gschema_preftrans_files ${local_preftrans_files} CACHE INTERNAL "files describing transformations for our gsettings based preferences")
|
||||
endif()
|
||||
|
||||
set_dist_list(ofx_gschema_DIST
|
||||
CMakeLists.txt
|
||||
migratable-prefs.xml
|
||||
pref_transformations.xml
|
||||
org.gnucash.GnuCash.dialogs.import.ofx.gschema.xml.in)
|
||||
|
||||
@@ -667,7 +667,7 @@ migrate_one_key (const std::string &oldpath, const std::string &oldkey,
|
||||
}
|
||||
|
||||
static void
|
||||
migrate_one_node (bpt::ptree &pt)
|
||||
parse_one_release_node (bpt::ptree &pt)
|
||||
{
|
||||
/* loop over top-level property tree */
|
||||
std::for_each (pt.begin(), pt.end(),
|
||||
@@ -675,53 +675,55 @@ migrate_one_node (bpt::ptree &pt)
|
||||
{
|
||||
if (node.first == "<xmlattr>")
|
||||
return;
|
||||
if (node.first != "migrate")
|
||||
if (node.first == "migrate")
|
||||
{
|
||||
DEBUG ("Skipping non-<migrate> node <%s>", node.first.c_str());
|
||||
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 (!oldpath || !oldkey || !newpath || !newkey)
|
||||
{
|
||||
DEBUG ("Skipping migration node - missing attribute (old-path, old-key, new-path or new-key)");
|
||||
return;
|
||||
}
|
||||
migrate_one_key (*oldpath, *oldkey, *newpath, *newkey);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG ("Skipping unknown node <%s>", node.first.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
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 (!oldpath || !oldkey || !newpath || !newkey)
|
||||
{
|
||||
DEBUG ("Skipping migration node - missing attribute (old-path, old-key, new-path or new-key)");
|
||||
return;
|
||||
}
|
||||
migrate_one_key (*oldpath, *oldkey, *newpath, *newkey);
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
migrate_settings (int old_maj_min)
|
||||
transform_settings (int old_maj_min)
|
||||
{
|
||||
bpt::ptree pt;
|
||||
|
||||
auto pkg_data_dir = gnc_path_get_pkgdatadir();
|
||||
auto migrate_file = std::string (pkg_data_dir) + "/migratable-prefs.xml";
|
||||
auto transform_file = std::string (pkg_data_dir) + "/pref_transformations.xml";
|
||||
g_free (pkg_data_dir);
|
||||
|
||||
std::ifstream migrate_stream {migrate_file};
|
||||
if (!migrate_stream.is_open())
|
||||
std::ifstream transform_stream {transform_file};
|
||||
if (!transform_stream.is_open())
|
||||
{
|
||||
PWARN("Failed to load settings migration file '%s'", migrate_file.c_str());
|
||||
PWARN("Failed to load preferences transformation file '%s'", transform_file.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
bpt::read_xml (migrate_stream, pt);
|
||||
bpt::read_xml (transform_stream, pt);
|
||||
}
|
||||
catch (bpt::xml_parser_error &e) {
|
||||
PWARN ("Failed to parse GnuCash settings migration file.\n");
|
||||
PWARN ("Failed to parse GnuCash preferences transformation file.\n");
|
||||
PWARN ("Error message:\n");
|
||||
PWARN ("%s\n", e.what());
|
||||
return;
|
||||
}
|
||||
catch (...) {
|
||||
PWARN ("Unknown error while parsing GnuCash settings migration file.\n");
|
||||
PWARN ("Unknown error while parsing GnuCash preferences transformation file.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -747,27 +749,36 @@ migrate_settings (int old_maj_min)
|
||||
}
|
||||
DEBUG ("Retrieved version value '%i'", *version);
|
||||
|
||||
migrate_one_node (node.second);
|
||||
parse_one_release_node (node.second);
|
||||
});
|
||||
}
|
||||
|
||||
void gnc_gsettings_version_upgrade (void)
|
||||
{
|
||||
/* Use versioning to ensure this routine will only sync once for each
|
||||
* superseded setting
|
||||
* At first run of GnuCash 4.7 or more recent *all* settings will be migrated
|
||||
* from prefix org.gnucash to org.gnucash.GnuCash, including our GNC_PREF_VERSION setting.
|
||||
* As the logic to determine whether or not to upgrade depends on it we have to do
|
||||
* some extra tests to figure when exactly to start doing migrations.
|
||||
* - if GNC_PREF_VERSION is not set under old nor new prefix, that means
|
||||
* gnucash has never run before on this system = no migration necessary
|
||||
* - if GNC_PREF_VERSION is set under old prefix, but not new prefix
|
||||
* => full migration from old to new prefix should still be run
|
||||
/* This routine will conditionally execute conversion rules from
|
||||
* prefs_transformations.xml to adapt the user's existing preferences to
|
||||
* the current preferences schema. The rules in this file are versioned and
|
||||
* only rules still relevant to the user's existing preferences and for
|
||||
* this version of GnuCash will be executed.
|
||||
*
|
||||
* Starting with GnuCash 4.7 the code expects all preferences to be stored
|
||||
* under prefix org.gnucash instead of org.gnucash.GnuCash, including our
|
||||
* GNC_PREF_VERSION setting.
|
||||
* As the logic to determine whether or not settings conversions are needed
|
||||
* depends on this preference, we have to test for its value in two
|
||||
* locations:
|
||||
* - if GNC_PREF_VERSION is not set under old nor new prefix
|
||||
* => GnuCash has never run before so no conversion run necessary
|
||||
* - if GNC_PREF_VERSION is set under old prefix and not new prefix
|
||||
* => user's preferences weren't moved yet from old to new prefix. Use old
|
||||
* prefix GNC_PREF_VERSION to determine which conversions may be needed
|
||||
* - if GNC_PREF_VERSION is set under both prefixes
|
||||
* => ignore old prefix and use new prefix result to determine which
|
||||
* migrations would still be needed.
|
||||
* => ignore old prefix and use new prefix GNC_PREF_VERSION to determine
|
||||
* which conversions may be needed.
|
||||
* Sometime in the future (GnuCash 6.0) the old prefix will be fully removed
|
||||
* and the test will be simplified to only check in the new prefix.
|
||||
*/
|
||||
ENTER("Start of settings migration routine.");
|
||||
ENTER("Start of settings transform routine.");
|
||||
|
||||
auto ogG_maj_min = gnc_gsettings_get_user_value (GNC_PREFS_GROUP_GENERAL, GNC_PREF_VERSION);
|
||||
auto og_maj_min = gnc_gsettings_get_user_value (GSET_SCHEMA_OLD_PREFIX "." GNC_PREFS_GROUP_GENERAL, GNC_PREF_VERSION);
|
||||
@@ -790,7 +801,7 @@ void gnc_gsettings_version_upgrade (void)
|
||||
|
||||
PINFO ("Previous setting compatibility level: %i", old_maj_min);
|
||||
|
||||
migrate_settings (old_maj_min);
|
||||
transform_settings (old_maj_min);
|
||||
|
||||
/* Only write current version if it's more recent than what was set */
|
||||
auto cur_maj_min = PROJECT_VERSION_MAJOR * 1000 + PROJECT_VERSION_MINOR;
|
||||
|
||||
Reference in New Issue
Block a user