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:
Geert Janssens
2021-09-30 18:26:01 +02:00
parent 71722c46ad
commit 64576f7d27
8 changed files with 113 additions and 56 deletions

View File

@@ -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)

View File

@@ -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()

View File

@@ -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">

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;