summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2012-11-09 12:53:58 -0500
committerRyan Lortie <desrt@desrt.ca>2012-11-09 12:53:58 -0500
commit12395df3d35426e05231e8401bd03fdded6cb7ab (patch)
treed5f87a8223ee66fa8f8eb04beaad768d7b69f567
parentd03ca16343ca6b2c0475c77eed8f7a25dda41df6 (diff)
downloaddconf-12395df3d35426e05231e8401bd03fdded6cb7ab.tar.gz
service: factor out gvdb read/write code
Factor the code for reading and writing DConfChangeset databases to the gvdb file format out from dconf-writer.c. This will allow those functions to be used by other backend implementations that want to store things in gvdb format (like on NFS).
-rw-r--r--service/Makefile.am2
-rw-r--r--service/dconf-gvdb-utils.c157
-rw-r--r--service/dconf-gvdb-utils.h34
-rw-r--r--service/dconf-writer.c152
4 files changed, 204 insertions, 141 deletions
diff --git a/service/Makefile.am b/service/Makefile.am
index 3f70ff2..5801b3f 100644
--- a/service/Makefile.am
+++ b/service/Makefile.am
@@ -15,6 +15,8 @@ dconf_service_SOURCES = \
$(BUILT_SOURCES) \
dconf-blame.c \
dconf-blame.h \
+ dconf-gvdb-utils.c \
+ dconf-gvdb-utils.h \
dconf-service.c \
dconf-service.h \
dconf-writer.h \
diff --git a/service/dconf-gvdb-utils.c b/service/dconf-gvdb-utils.c
new file mode 100644
index 0000000..4e93cc8
--- /dev/null
+++ b/service/dconf-gvdb-utils.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2012 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "dconf-gvdb-utils.h"
+
+#include "../gvdb/gvdb-builder.h"
+#include "../gvdb/gvdb-reader.h"
+
+#include <string.h>
+
+DConfChangeset *
+dconf_gvdb_utils_read_file (const gchar *filename,
+ GError **error)
+{
+ DConfChangeset *database;
+ GError *my_error = NULL;
+ GvdbTable *table;
+
+ table = gvdb_table_new (filename, FALSE, &my_error);
+
+ /* It is perfectly fine if the file does not exist -- then it's
+ * just empty.
+ */
+ if (g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+ g_clear_error (&my_error);
+
+ /* Otherwise, we should report errors to prevent ourselves from
+ * overwriting the database in other situations...
+ */
+ if (my_error)
+ {
+ g_propagate_prefixed_error (error, my_error, "Cannot open dconf database: ");
+ return NULL;
+ }
+
+ /* Only allocate once we know we are in a non-error situation */
+ database = dconf_changeset_new_database (NULL);
+
+ /* Fill the table up with the initial state */
+ if (table != NULL)
+ {
+ gchar **names;
+ gint n_names;
+ gint i;
+
+ names = gvdb_table_get_names (table, &n_names);
+ for (i = 0; i < n_names; i++)
+ {
+ if (dconf_is_key (names[i], NULL))
+ {
+ GVariant *value;
+
+ value = gvdb_table_get_value (table, names[i]);
+
+ if (value != NULL)
+ {
+ dconf_changeset_set (database, names[i], value);
+ g_variant_unref (value);
+ }
+ }
+
+ g_free (names[i]);
+ }
+
+ gvdb_table_unref (table);
+ g_free (names);
+ }
+
+ return database;
+}
+
+static GvdbItem *
+dconf_gvdb_utils_get_parent (GHashTable *table,
+ const gchar *key)
+{
+ GvdbItem *grandparent, *parent;
+ gchar *parent_name;
+ gint len;
+
+ if (g_str_equal (key, "/"))
+ return NULL;
+
+ len = strlen (key);
+ if (key[len - 1] == '/')
+ len--;
+
+ while (key[len - 1] != '/')
+ len--;
+
+ parent_name = g_strndup (key, len);
+ parent = g_hash_table_lookup (table, parent_name);
+
+ if (parent == NULL)
+ {
+ parent = gvdb_hash_table_insert (table, parent_name);
+
+ grandparent = dconf_gvdb_utils_get_parent (table, parent_name);
+
+ if (grandparent != NULL)
+ gvdb_item_set_parent (parent, grandparent);
+ }
+
+ g_free (parent_name);
+
+ return parent;
+}
+
+static gboolean
+dconf_gvdb_utils_add_key (const gchar *path,
+ GVariant *value,
+ gpointer user_data)
+{
+ GHashTable *gvdb = user_data;
+ GvdbItem *item;
+
+ g_assert (g_hash_table_lookup (gvdb, path) == NULL);
+ item = gvdb_hash_table_insert (gvdb, path);
+ gvdb_item_set_parent (item, dconf_gvdb_utils_get_parent (gvdb, path));
+ gvdb_item_set_value (item, value);
+
+ return TRUE;
+}
+
+gboolean
+dconf_gvdb_utils_write_file (const gchar *filename,
+ DConfChangeset *database,
+ GError **error)
+{
+ GHashTable *gvdb;
+ gboolean success;
+
+ gvdb = gvdb_hash_table_new (NULL, NULL);
+ dconf_changeset_all (database, dconf_gvdb_utils_add_key, gvdb);
+ success = gvdb_table_write_contents (gvdb, filename, FALSE, error);
+ g_hash_table_unref (gvdb);
+
+ return success;
+}
diff --git a/service/dconf-gvdb-utils.h b/service/dconf-gvdb-utils.h
new file mode 100644
index 0000000..ff5d9fe
--- /dev/null
+++ b/service/dconf-gvdb-utils.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2012 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __dconf_gvdb_utils_h__
+#define __dconf_gvdb_utils_h__
+
+#include "../common/dconf-changeset.h"
+
+DConfChangeset * dconf_gvdb_utils_read_file (const gchar *filename,
+ GError **error);
+gboolean dconf_gvdb_utils_write_file (const gchar *filename,
+ DConfChangeset *database,
+ GError **error);
+
+#endif /* __dconf_gvdb_utils_h__ */
diff --git a/service/dconf-writer.c b/service/dconf-writer.c
index 7e9a539..b0b1015 100644
--- a/service/dconf-writer.c
+++ b/service/dconf-writer.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2010 Codethink Limited
+ * Copyright © 2012 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,8 @@
#include "dconf-writer.h"
#include "../shm/dconf-shm.h"
+#include "dconf-gvdb-utils.h"
+#include "dconf-generated.h"
#include <stdlib.h>
#include <unistd.h>
@@ -30,11 +33,6 @@
#include <errno.h>
#include <stdio.h>
-#include "dconf-generated.h"
-#include "../common/dconf-changeset.h"
-#include "../gvdb/gvdb-builder.h"
-#include "../gvdb/gvdb-reader.h"
-
typedef struct
{
DConfDBusWriterSkeleton parent_instance;
@@ -76,62 +74,6 @@ static void dconf_writer_iface_init (DConfDBusWriterIface *iface);
G_DEFINE_TYPE_WITH_CODE (DConfWriter, dconf_writer, DCONF_DBUS_TYPE_WRITER_SKELETON,
G_IMPLEMENT_INTERFACE (DCONF_DBUS_TYPE_WRITER, dconf_writer_iface_init))
-static GvdbItem *
-dconf_writer_get_parent (GHashTable *table,
- const gchar *key)
-{
- GvdbItem *grandparent, *parent;
- gchar *parent_name;
- gint len;
-
- if (g_str_equal (key, "/"))
- return NULL;
-
- len = strlen (key);
- if (key[len - 1] == '/')
- len--;
-
- while (key[len - 1] != '/')
- len--;
-
- parent_name = g_strndup (key, len);
- parent = g_hash_table_lookup (table, parent_name);
-
- if (parent == NULL)
- {
- parent = gvdb_hash_table_insert (table, parent_name);
-
- grandparent = dconf_writer_get_parent (table, parent_name);
-
- if (grandparent != NULL)
- gvdb_item_set_parent (parent, grandparent);
- }
-
- g_free (parent_name);
-
- return parent;
-}
-
-static GHashTable *
-dconf_writer_new_value_table (GHashTable *copy_from)
-{
- GHashTable *table;
-
- table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
-
- if (copy_from)
- {
- GHashTableIter iter;
- gpointer key, value;
-
- g_hash_table_iter_init (&iter, copy_from);
- while (g_hash_table_iter_next (&iter, &key, &value))
- g_hash_table_insert (table, g_strdup (key), g_variant_ref (value));
- }
-
- return table;
-}
-
static gchar *
dconf_writer_get_tag (DConfWriter *writer)
{
@@ -153,58 +95,10 @@ dconf_writer_real_begin (DConfWriter *writer,
*/
if (writer->commited_values == NULL)
{
- GError *my_error = NULL;
- GvdbTable *table;
-
- table = gvdb_table_new (writer->filename, FALSE, &my_error);
-
- /* It is perfectly fine if the file does not exist -- then it's
- * just empty.
- */
- if (g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
- g_clear_error (&my_error);
-
- /* Otherwise, we should report errors to prevent ourselves from
- * overwriting the database in other situations...
- */
- if (my_error)
- {
- g_propagate_prefixed_error (error, my_error, "Cannot open dconf database: ");
- return FALSE;
- }
-
- /* Only initialise once we know we are in a non-error situation */
- writer->commited_values = dconf_changeset_new_database (NULL);
-
- /* Fill the table up with the initial state */
- if (table != NULL)
- {
- gchar **names;
- gint n_names;
- gint i;
-
- names = gvdb_table_get_names (table, &n_names);
- for (i = 0; i < n_names; i++)
- {
- if (dconf_is_key (names[i], NULL))
- {
- GVariant *value;
-
- value = gvdb_table_get_value (table, names[i]);
-
- if (value != NULL)
- {
- dconf_changeset_set (writer->commited_values, names[i], value);
- g_variant_unref (value);
- }
- }
-
- g_free (names[i]);
- }
-
- gvdb_table_unref (table);
- g_free (names);
- }
+ writer->commited_values = dconf_gvdb_utils_read_file (writer->filename, error);
+
+ if (!writer->commited_values)
+ return FALSE;
}
writer->uncommited_values = dconf_changeset_new_database (writer->commited_values);
@@ -234,37 +128,13 @@ dconf_writer_real_change (DConfWriter *writer,
}
static gboolean
-dconf_writer_add_to_gvdb (const gchar *path,
- GVariant *value,
- gpointer user_data)
-{
- GHashTable *gvdb = user_data;
- GvdbItem *item;
-
- g_assert (g_hash_table_lookup (gvdb, path) == NULL);
- item = gvdb_hash_table_insert (gvdb, path);
- gvdb_item_set_parent (item, dconf_writer_get_parent (gvdb, path));
- gvdb_item_set_value (item, value);
-
- return TRUE;
-}
-
-static gboolean
dconf_writer_real_commit (DConfWriter *writer,
GError **error)
{
- gboolean success;
-
- {
- GHashTable *gvdb;
-
- gvdb = gvdb_hash_table_new (NULL, NULL);
- dconf_changeset_all (writer->uncommited_values, dconf_writer_add_to_gvdb, gvdb);
- success = gvdb_table_write_contents (gvdb, writer->filename, FALSE, error);
- g_hash_table_unref (gvdb);
- }
+ if (!dconf_gvdb_utils_write_file (writer->filename, writer->uncommited_values, error))
+ return FALSE;
- if (success && writer->native)
+ if (writer->native)
dconf_shm_flag (writer->name);
if (writer->commited_values)
@@ -280,7 +150,7 @@ dconf_writer_real_commit (DConfWriter *writer,
writer->uncommited_changes = empty_queue;
}
- return success;
+ return TRUE;
}
static void