[tracker/tracker-client-writeback] libtracker-client: Add writeback functions



commit b5c2ef2893b0bf6ca6e2931250f2c39ddf33c428
Author: Adrien Bustany <abustany gnome org>
Date:   Thu Mar 25 13:35:24 2010 -0300

    libtracker-client: Add writeback functions
    
    This commits adds two new functions tracker_resources_writeback_connect and
    tracker_resources_writeback_disconnect to connect (and disconnect) to the
    Writeback signal emitted by the store.
    The DBus Writeback signal is connected on demande whenver needed, and
    disconnected when not needed anymore to avoid unnecessary wakeups.

 src/libtracker-client/tracker-client.vapi |    6 ++
 src/libtracker-client/tracker.c           |  126 +++++++++++++++++++++++++++++
 src/libtracker-client/tracker.h           |   19 +++++
 3 files changed, 151 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-client/tracker-client.vapi b/src/libtracker-client/tracker-client.vapi
index 007e8fa..d72335c 100644
--- a/src/libtracker-client/tracker-client.vapi
+++ b/src/libtracker-client/tracker-client.vapi
@@ -56,6 +56,10 @@ namespace Tracker {
 		public GLib.PtrArray statistics_get () throws GLib.Error;
 		[CCode (cname = "tracker_statistics_get_async")]
 		public void statistics_get_async (Tracker.ReplyGPtrArray callback);
+		[CCode (cname = "tracker_resources_writeback_connect")]
+		public void writeback_connect (Tracker.WritebackCallback callback);
+		[CCode (cname = "tracker_resources_writeback_disconnect")]
+		public void writeback_disconnect ();
 	}
 	[Compact]
 	[CCode (free_function = "g_object_unref", cheader_filename = "libtracker-client/tracker-sparql-builder.h")]
@@ -108,6 +112,8 @@ namespace Tracker {
 	public delegate void ReplyGPtrArray (GLib.PtrArray result, GLib.Error error);
 	[CCode (cheader_filename = "libtracker-client/tracker-client.h", instance_pos = -2)]
 	public delegate void ReplyVoid (GLib.Error error);
+	[CCode (cheader_filename = "libtracker-client/tracker.h", instance_pos = -2)]
+	public delegate void WritebackCallback (GLib.HashTable resources);
 
 	[CCode (cheader_filename = "libtracker-client/tracker-client.h")]
 	public const string DBUS_INTERFACE_RESOURCES;
diff --git a/src/libtracker-client/tracker.c b/src/libtracker-client/tracker.c
index 9cfda61..340b50f 100644
--- a/src/libtracker-client/tracker.c
+++ b/src/libtracker-client/tracker.c
@@ -26,6 +26,8 @@
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib-bindings.h>
 
+#include <libtracker-common/tracker-dbus.h>
+
 #include "tracker.h"
 
 #include "tracker-resources-glue.h"
@@ -99,6 +101,8 @@ typedef struct {
 	gint timeout;
 	gboolean enable_warnings;
 
+	GList *writeback_callbacks;
+
 	gboolean is_constructed;
 } TrackerClientPrivate;
 
@@ -121,6 +125,12 @@ typedef struct {
 	guint id;
 } CallbackVoid;
 
+typedef struct {
+	guint id;
+	TrackerWritebackCallback func;
+	gpointer data;
+} WritebackCallback;
+
 #ifndef TRACKER_DISABLE_DEPRECATED
 
 /* Deprecated and only used for 0.6 API */
@@ -152,6 +162,7 @@ enum {
 };
 
 static guint pending_call_id = 0;
+static guint writeback_callback_id = 0;
 
 G_DEFINE_TYPE(TrackerClient, tracker_client, G_TYPE_OBJECT)
 
@@ -190,6 +201,28 @@ pending_call_new (TrackerClient  *client,
 }
 
 static void
+writeback_cb (DBusGProxy       *proxy,
+              const GHashTable *resources,
+              gpointer          user_data)
+{
+	TrackerClientPrivate *private;
+	WritebackCallback *cb;
+	GList *current_callback;
+
+	g_return_if_fail (resources != NULL);
+	g_return_if_fail (user_data != NULL);
+
+	private = user_data;
+
+	for (current_callback = private->writeback_callbacks;
+	     current_callback;
+	     current_callback = g_list_next (current_callback)) {
+		cb = current_callback->data;
+		(*(TrackerWritebackCallback) cb->func) (resources, cb->data);
+	}
+}
+
+static void
 tracker_client_class_init (TrackerClientClass *klass)
 {
 	GObjectClass *object_class;
@@ -229,6 +262,7 @@ tracker_client_init (TrackerClient *client)
 	private->timeout = -1;
 	private->pending_calls = g_hash_table_new_full (NULL, NULL, NULL,
 	                                               (GDestroyNotify) pending_call_free);
+	private->writeback_callbacks = NULL;
 }
 
 static void
@@ -345,6 +379,11 @@ client_constructed (GObject *object)
 	dbus_g_proxy_set_default_timeout (private->proxy_resources, 
 	                                  private->timeout);
 
+	dbus_g_proxy_add_signal (private->proxy_resources,
+	                         "Writeback",
+	                         TRACKER_TYPE_STR_STRV_MAP,
+	                         G_TYPE_INVALID);
+
 	private->is_constructed = TRUE;
 }
 
@@ -1396,6 +1435,93 @@ tracker_resources_batch_commit_async (TrackerClient    *client,
 	return cb->id;
 }
 
+/**
+ * tracker_resources_writeback_connect:
+ * @callback: a #TrackerWritebackCallback to call when the writeback signal is
+ *            emitted
+ *
+ * Registers a callback to be called when the writeback signal is emitted by
+ * the store.
+ *
+ * The writeback signal is emitted by the store everytime a property annotated
+ * with tracker:writeback is changed. This annotation means that whenever
+ * possible the changes in the RDF store should be reflected in the metadata of
+ * the original file.
+ *
+ * Returns a handle that can be used to disconnect the signal later using
+ * tracker_resources_writeback_disconnect. The handle will always be greater
+ * than 0 on success.
+ */
+guint
+tracker_resources_writeback_connect (TrackerClient            *client,
+                                     TrackerWritebackCallback  callback,
+                                     gpointer                  user_data)
+{
+	TrackerClientPrivate *private;
+	WritebackCallback *cb;
+
+	g_return_val_if_fail (TRACKER_IS_CLIENT (client), 0);
+	g_return_val_if_fail (callback != NULL, 0);
+
+	private = TRACKER_CLIENT_GET_PRIVATE (client);
+
+	/* Connect the DBus signal if needed */
+	if (g_list_length (private->writeback_callbacks) == 0) {
+		dbus_g_proxy_connect_signal (private->proxy_resources,
+		                             "Writeback",
+		                             G_CALLBACK (writeback_cb),
+		                             private,
+		                             NULL);
+	}
+
+	cb = g_slice_new0 (WritebackCallback);
+	cb->id = ++writeback_callback_id;
+	cb->func = callback;
+	cb->data = user_data;
+
+	private->writeback_callbacks = g_list_prepend (private->writeback_callbacks,
+	                                               cb);
+
+	return cb->id;
+}
+
+/**
+ * tracker_resources_writeback_disconnect:
+ * @callback: the #TrackerWritebackCallback to disconnect
+ *
+ * Removes @callback from the writeback callbacks
+ */
+void
+tracker_resources_writeback_disconnect (TrackerClient            *client,
+                                        guint                     handle)
+{
+	TrackerClientPrivate *private;
+	GList *current_callback;
+
+	g_return_if_fail (TRACKER_IS_CLIENT (client));
+
+	private = TRACKER_CLIENT_GET_PRIVATE (client);
+
+	for (current_callback = private->writeback_callbacks;
+	     current_callback;
+	     current_callback = g_list_next (current_callback)) {
+		if (((WritebackCallback*) current_callback->data)->id == handle) {
+			g_slice_free (WritebackCallback, current_callback->data);
+			private->writeback_callbacks = g_list_remove (private->writeback_callbacks,
+			                                              current_callback);
+			break;
+		}
+	}
+
+	/* Disconnect the DBus signal if not needed anymore */
+	if (g_list_length (private->writeback_callbacks) == 0) {
+		dbus_g_proxy_disconnect_signal (private->proxy_resources,
+		                                "Writeback",
+		                                G_CALLBACK (writeback_cb),
+		                                private);
+	}
+}
+
 /* tracker_search_metadata_by_text_async is used by GTK+ */
 
 static void
diff --git a/src/libtracker-client/tracker.h b/src/libtracker-client/tracker.h
index ccbf82c..0069907 100644
--- a/src/libtracker-client/tracker.h
+++ b/src/libtracker-client/tracker.h
@@ -85,6 +85,18 @@ typedef void (*TrackerReplyGPtrArray) (GPtrArray *result,
 typedef void (*TrackerReplyVoid)      (GError    *error,
                                        gpointer   user_data);
 
+/**
+ * TrackerWritebackCallback:
+ * @resources: a hash table where each key is the uri of a resources which
+ *             was modified. To each key is associated an array of strings,
+ *             which are the various RDF classes the uri belongs to.
+ *
+ * The callback is called everytime a property annotated with tracker:writeback
+ * is modified in the store.
+ */
+typedef void (*TrackerWritebackCallback) (const GHashTable *resources,
+                                          gpointer          user_data);
+
 GType          tracker_client_get_type                     (void) G_GNUC_CONST;
 TrackerClient *tracker_client_new                          (TrackerClientFlags      flags,
                                                             gint                    timeout);
@@ -149,6 +161,13 @@ guint          tracker_resources_batch_commit_async        (TrackerClient
                                                             TrackerReplyVoid        callback,
                                                             gpointer                user_data);
 
+/* Store signals */
+guint          tracker_resources_writeback_connect         (TrackerClient            *client,
+                                                            TrackerWritebackCallback  callback,
+                                                            gpointer                  user_data);
+void           tracker_resources_writeback_disconnect      (TrackerClient            *client,
+                                                            guint handle);
+
 #ifndef TRACKER_DISABLE_DEPRECATED
 
 /* Deprecated APIs */



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