[gnome-latex] latexila -> gnome-latex migration: copy DhDconfMigration utility



commit 28b3d9d00e4a22b1f993b7dc63e8261d01c89bb3
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Mar 25 11:24:08 2018 +0200

    latexila -> gnome-latex migration: copy DhDconfMigration utility
    
    Copied from Devhelp.

 configure.ac                         |   1 +
 docs/reference/Makefile.am           |   1 +
 po/POTFILES.in                       |   1 +
 src/liblatexila/Makefile.am          |   2 +
 src/liblatexila/dh-dconf-migration.c | 140 +++++++++++++++++++++++++++++++++++
 src/liblatexila/dh-dconf-migration.h |  42 +++++++++++
 6 files changed, 187 insertions(+)
---
diff --git a/configure.ac b/configure.ac
index d293937..666593d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -109,6 +109,7 @@ PKG_CHECK_MODULES([DEP], [
        tepl-4 >= ${TEPL_REQUIRED_VERSION}
        gspell-1 >= ${GSPELL_REQUIRED_VERSION}
        gee-0.8 >= ${GEE_REQUIRED_VERSION}
+       dconf
        gsettings-desktop-schemas
 ])
 
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 5e92ab8..38ea2a2 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -53,6 +53,7 @@ EXTRA_HFILES =
 # Header files or dirs to ignore when scanning. Use base file/dir names
 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
 IGNORE_HFILES =                                        \
+       dh-dconf-migration.h                    \
        latexila-enum-types.h                   \
        latexila-templates-common.h
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 14cce60..b1b308e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -25,6 +25,7 @@ src/file_browser.vala
 src/finance.vala
 src/latexila_app.vala
 src/latex_menu.vala
+src/liblatexila/dh-dconf-migration.c
 src/liblatexila/latexila-build-job.c
 src/liblatexila/latexila-build-tool.c
 src/liblatexila/latexila-build-tools.c
diff --git a/src/liblatexila/Makefile.am b/src/liblatexila/Makefile.am
index 42f0ebe..26daadb 100644
--- a/src/liblatexila/Makefile.am
+++ b/src/liblatexila/Makefile.am
@@ -20,6 +20,7 @@ liblatexila_la_LIBADD =               \
        ../evince/libevince.la
 
 liblatexila_headers =                          \
+       dh-dconf-migration.h                    \
        latexila.h                              \
        latexila-build-job.h                    \
        latexila-build-tool.h                   \
@@ -43,6 +44,7 @@ liblatexila_headers =                         \
        latexila-view.h
 
 liblatexila_sources =                          \
+       dh-dconf-migration.c                    \
        latexila-build-job.c                    \
        latexila-build-tool.c                   \
        latexila-build-tools.c                  \
diff --git a/src/liblatexila/dh-dconf-migration.c b/src/liblatexila/dh-dconf-migration.c
new file mode 100644
index 0000000..fae9bfa
--- /dev/null
+++ b/src/liblatexila/dh-dconf-migration.c
@@ -0,0 +1,140 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2018 Sébastien Wilmet <swilmet gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dh-dconf-migration.h"
+#include <dconf.h>
+
+/* #DhDconfMigration is a utility class to copy the value of dconf keys from old
+ * paths to new paths.
+ *
+ * You'll probably need to add a "migration-done" #GSettings key to know if the
+ * migration has already been done or not (either with a boolean, or an integer
+ * if you plan to have other migrations in the future).
+ *
+ * Use-case examples:
+ * - When a project is renamed. The old #GSettings schema may no longer be
+ *   installed, so it is not possible to use the #GSettings API to retrieve the
+ *   values at the old locations. But the values are still stored in the dconf
+ *   database.
+ * - Be able to do refactorings in the #GSettings schema without users losing
+ *   their settings when *upgrading* to a new version (doesn't work when
+ *   downgrading).
+ * - When a library uses #GSettings, with parallel-installability for different
+ *   major versions, each major version provides a different #GSettings schema,
+ *   but when upgrading to a new major version we don't want all the users to
+ *   lose their settings. An alternative is for the library to install only
+ *   relocatable schemas, relocated to an old common path (if all the keys of
+ *   that schema are still compatible). When a schema (or sub-schema) becomes
+ *   incompatible, the compatible keys can be migrated individually with
+ *   #DhDconfMigration.
+ */
+
+/* Tested inside a Flatpak sandbox, works fine. */
+
+struct _DhDconfMigration {
+        DConfClient *client;
+};
+
+DhDconfMigration *
+_dh_dconf_migration_new (void)
+{
+        DhDconfMigration *migration;
+
+        migration = g_new0 (DhDconfMigration, 1);
+        migration->client = dconf_client_new ();
+
+        return migration;
+}
+
+void
+_dh_dconf_migration_free (DhDconfMigration *migration)
+{
+        if (migration == NULL)
+                return;
+
+        dconf_client_sync (migration->client);
+
+        g_object_unref (migration->client);
+        g_free (migration);
+}
+
+/*
+ * _dh_dconf_migration_migrate_key:
+ * @migration: a #DhDconfMigration.
+ * @new_key_path: the dconf path to the new key.
+ * @first_old_key_path: the dconf path to the first old key.
+ * @...: %NULL-terminated list of strings containing the dconf paths to the old
+ *   keys (usually from most recent to the oldest).
+ *
+ * Copies a value from an old path to a new path. The values on the old paths
+ * are not reset, it is just a copy.
+ *
+ * The function loops on the old key paths, in the same order as provided; as
+ * soon as an old key contains a value, that value is copied to @new_key_path
+ * and the function returns. Which means that, usually, all the keys must be
+ * provided in reverse chronological order.
+ */
+void
+_dh_dconf_migration_migrate_key (DhDconfMigration *migration,
+                                 const gchar      *new_key_path,
+                                 const gchar      *first_old_key_path,
+                                 ...)
+{
+        va_list old_key_paths;
+        GVariant *value;
+
+        g_return_if_fail (migration != NULL);
+        g_return_if_fail (new_key_path != NULL);
+        g_return_if_fail (first_old_key_path != NULL);
+
+        va_start (old_key_paths, first_old_key_path);
+
+        value = dconf_client_read (migration->client, first_old_key_path);
+
+        while (value == NULL) {
+                const gchar *next_old_key_path;
+
+                next_old_key_path = va_arg (old_key_paths, const gchar *);
+                if (next_old_key_path == NULL)
+                        break;
+
+                value = dconf_client_read (migration->client, next_old_key_path);
+        }
+
+        if (value != NULL) {
+                GError *error = NULL;
+
+                /* The GVariant type is not checked against the new GSettings
+                 * schema. If we write a value with an incompatible type by
+                 * mistake, no problem, GSettings will take the default value
+                 * from the schema (without printing a warning).
+                 */
+                dconf_client_write_fast (migration->client, new_key_path, value, &error);
+
+                if (error != NULL) {
+                        g_warning ("Error when migrating dconf key %s: %s",
+                                   new_key_path,
+                                   error->message);
+                        g_clear_error (&error);
+                }
+
+                g_variant_unref (value);
+        }
+
+        va_end (old_key_paths);
+}
diff --git a/src/liblatexila/dh-dconf-migration.h b/src/liblatexila/dh-dconf-migration.h
new file mode 100644
index 0000000..4bcfdcd
--- /dev/null
+++ b/src/liblatexila/dh-dconf-migration.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2018 Sébastien Wilmet <swilmet gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DH_DCONF_MIGRATION_H
+#define DH_DCONF_MIGRATION_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _DhDconfMigration DhDconfMigration;
+
+G_GNUC_INTERNAL
+DhDconfMigration *      _dh_dconf_migration_new         (void);
+
+G_GNUC_INTERNAL
+void                    _dh_dconf_migration_free        (DhDconfMigration *migration);
+
+G_GNUC_INTERNAL
+void                    _dh_dconf_migration_migrate_key (DhDconfMigration *migration,
+                                                         const gchar      *new_key_path,
+                                                         const gchar      *first_old_key_path,
+                                                         ...);
+
+G_END_DECLS
+
+#endif /* DH_DCONF_MIGRATION_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]