summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2013-01-11 13:25:12 -0500
committerRyan Lortie <desrt@desrt.ca>2013-01-11 13:25:12 -0500
commit80447f9ce0f61a4f150b0db99b7535ff5b033023 (patch)
tree9977c6dfa2f0960a26af90c9ae98916b57e489e6 /common
parent4536f4014b16e4e807c4857bb23f9f6662bad6bb (diff)
downloaddconf-80447f9ce0f61a4f150b0db99b7535ff5b033023.tar.gz
changeset: add a diff() operation on databases
Diffstat (limited to 'common')
-rw-r--r--common/dconf-changeset.c73
-rw-r--r--common/dconf-changeset.h3
2 files changed, 76 insertions, 0 deletions
diff --git a/common/dconf-changeset.c b/common/dconf-changeset.c
index 4c56b93..639ea89 100644
--- a/common/dconf-changeset.c
+++ b/common/dconf-changeset.c
@@ -697,3 +697,76 @@ dconf_changeset_change (DConfChangeset *changeset,
dconf_changeset_set (changeset, path, value);
}
}
+
+/**
+ * dconf_changeset_diff:
+ * @from: a database mode changeset
+ * @to: a database mode changeset
+ *
+ * Compares to database-mode changesets and produces a changeset that
+ * describes their differences.
+ *
+ * If there is no difference, %NULL is returned.
+ *
+ * Applying the returned changeset to @from using
+ * dconf_changeset_change() will result in the two changesets being
+ * equal.
+ *
+ * Returns: (transfer full): the changes, or %NULL
+ *
+ * Since: 0.16
+ */
+DConfChangeset *
+dconf_changeset_diff (DConfChangeset *from,
+ DConfChangeset *to)
+{
+ DConfChangeset *changeset = NULL;
+ GHashTableIter iter;
+ gpointer key, val;
+
+ g_return_val_if_fail (from->is_database, NULL);
+ g_return_val_if_fail (to->is_database, NULL);
+
+ /* We make no attempt to do dir resets, but we could...
+ *
+ * For now, we just reset each key individually.
+ *
+ * We create our list of changes in two steps:
+ *
+ * - iterate the 'to' changeset and note any keys that do not have
+ * the same value in the 'from' changeset
+ *
+ * - iterate the 'from' changeset and note any keys not present in
+ * the 'to' changeset, recording resets for them
+ *
+ * This will cover all changes.
+ *
+ * Note: because 'from' and 'to' are database changesets we don't have
+ * to worry about seeing NULL values or dirs.
+ */
+ g_hash_table_iter_init (&iter, to->table);
+ while (g_hash_table_iter_next (&iter, &key, &val))
+ {
+ GVariant *from_val = g_hash_table_lookup (from->table, key);
+
+ if (from_val == NULL || !g_variant_equal (val, from_val))
+ {
+ if (!changeset)
+ changeset = dconf_changeset_new ();
+
+ dconf_changeset_set (changeset, key, val);
+ }
+ }
+
+ g_hash_table_iter_init (&iter, from->table);
+ while (g_hash_table_iter_next (&iter, &key, &val))
+ if (!g_hash_table_lookup (to->table, key))
+ {
+ if (!changeset)
+ changeset = dconf_changeset_new ();
+
+ dconf_changeset_set (changeset, key, NULL);
+ }
+
+ return changeset;
+}
diff --git a/common/dconf-changeset.h b/common/dconf-changeset.h
index eb8dde1..7228105 100644
--- a/common/dconf-changeset.h
+++ b/common/dconf-changeset.h
@@ -67,4 +67,7 @@ DConfChangeset * dconf_changeset_deserialise (GVarian
void dconf_changeset_change (DConfChangeset *changeset,
DConfChangeset *changes);
+DConfChangeset * dconf_changeset_diff (DConfChangeset *from,
+ DConfChangeset *to);
+
#endif /* __dconf_changeset_h__ */