[tracker/dbus-fd-experiment: 6/13] Steroids: Add SparqlUpdate



commit 4e93b404a5332caaf82f4231f8878ceab89972f3
Author: Adrien Bustany <abustany gnome org>
Date:   Tue Jun 1 10:41:33 2010 -0400

    Steroids: Add SparqlUpdate
    
    This commit adds two new methods to handle Sparql Update. Those methods
    are exported on the Steroids object /org/freedesktop/Tracker1/Steroids.
    PrepareUpdate -> File descriptor where to write the query
                  -> Identifier for the query
    The PrepareUpdate calls opens and returns a FD where to write the update
    query. It also returns a query identifier, to use with the Update
    method.
    Update <- Identifier for the query
    The Update calls reads the query from the FD and runs it.

 data/dbus/tracker-steroids.xml       |    9 ++
 src/tracker-store/tracker-steroids.c |  174 +++++++++++++++++++++++++++++++---
 src/tracker-store/tracker-steroids.h |    7 ++
 3 files changed, 175 insertions(+), 15 deletions(-)
---
diff --git a/data/dbus/tracker-steroids.xml b/data/dbus/tracker-steroids.xml
index e7af30b..b626242 100644
--- a/data/dbus/tracker-steroids.xml
+++ b/data/dbus/tracker-steroids.xml
@@ -13,5 +13,14 @@
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <arg type="u" name="query_id" direction="in" />
     </method>
+    <method name="PrepareUpdate">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="h" name="pipe" direction="out" />
+      <arg type="u" name="query_id" direction="out" />
+    </method>
+    <method name="Update">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="u" name="query_id" direction="in" />
+    </method>
   </interface>
 </node>
diff --git a/src/tracker-store/tracker-steroids.c b/src/tracker-store/tracker-steroids.c
index 8e9c322..1ff83e8 100644
--- a/src/tracker-store/tracker-steroids.c
+++ b/src/tracker-store/tracker-steroids.c
@@ -110,6 +110,19 @@ buffer_write_int (char *dst, int value)
 	memset (dst++, (value >> 24) & 0xff, sizeof (char));
 }
 
+static int
+buffer_read_int (char *src)
+{
+	int result = 0;
+
+	result += (((unsigned char)*(src++)));
+	result += (((unsigned char)*(src++)) <<  8);
+	result += (((unsigned char)*(src++)) << 16);
+	result += (((unsigned char)*(src++)) << 24);
+
+	return result;
+}
+
 static void
 client_write_int (ClientInfo *info, int value)
 {
@@ -137,6 +150,24 @@ buffer_send (int fd, char *buf, int size)
 }
 
 static void
+buffer_read (int fd, char *buf, int size)
+{
+	ssize_t received = 0;
+
+	while (received != size) {
+		ssize_t ret = read (fd,
+		                    buf + received,
+		                    size - received);
+
+		if (ret == -1) {
+			g_critical ("Could not read buffer");
+		}
+
+		received += ret;
+	}
+}
+
+static void
 page_flush (ClientInfo *info)
 {
 	/* Put an "end of page" marker if there was still some space left
@@ -196,6 +227,29 @@ query_callback (gpointer  inthread_data,
 	g_hash_table_remove (priv->clients, info);
 }
 
+static void
+update_callback (GError *error, gpointer user_data)
+{
+	ClientInfo *info = user_data;
+
+	if (info->fd) {
+		close (info->fd);
+	}
+
+	if (error) {
+		tracker_dbus_request_failed (info->request_id,
+		                             info->context,
+		                             &error,
+		                             NULL);
+		dbus_g_method_return_error (info->context, error);
+		return;
+	}
+
+	tracker_dbus_request_success (info->request_id,
+	                              info->context);
+	dbus_g_method_return (info->context);
+}
+
 static gpointer
 query_inthread (TrackerDBCursor *cursor,
                 GError          *error,
@@ -325,11 +379,11 @@ query_inthread (TrackerDBCursor *cursor,
 	return ptr;
 }
 
-void
-tracker_steroids_prepare_query (TrackerSteroids        *steroids,
-                                const char             *query,
-                                DBusGMethodInvocation  *context,
-                                GError                **error)
+static ClientInfo*
+tracker_steroids_prepare (TrackerSteroids        *steroids,
+                          DBusGMethodInvocation  *context,
+                          gboolean                read,
+                          GError                **error)
 {
 	TrackerSteroidsPrivate *priv = TRACKER_STEROIDS_GET_PRIVATE (steroids);
 	guint                   request_id;
@@ -342,13 +396,10 @@ tracker_steroids_prepare_query (TrackerSteroids        *steroids,
 
 	request_id = tracker_dbus_get_next_request_id ();
 
-	tracker_dbus_async_return_if_fail (query != NULL, context);
-
 	tracker_dbus_request_new (request_id,
 	                          context,
-	                          "%s(): '%s'",
-	                          __FUNCTION__,
-	                          query);
+	                          "%s()",
+	                          __FUNCTION__);
 
 	if (pipe (pipefd) < 0) {
 		g_set_error (&inner_error, TRACKER_DBUS_ERROR, 0, "Cannot open pipe");
@@ -360,13 +411,12 @@ tracker_steroids_prepare_query (TrackerSteroids        *steroids,
 		dbus_g_method_return_error (context, inner_error);
 		g_propagate_error (error, inner_error);
 
-		return;
+		return NULL;
 	}
 
 	info = g_slice_new0 (ClientInfo);
 	info->parent = steroids;
-	info->fd = pipefd[1];
-	info->query = g_strdup (query);
+	info->fd = pipefd[1 - read];
 
 	sender = dbus_g_method_get_sender (context);
 
@@ -376,7 +426,7 @@ tracker_steroids_prepare_query (TrackerSteroids        *steroids,
 
 	if (!dbus_message_iter_append_basic (&iter,
 	                                     DBUS_TYPE_UNIX_FD,
-	                                     &pipefd[0])) {
+	                                     &pipefd[read])) {
 		g_critical ("FD passing not supported");
 
 		g_set_error (&inner_error, TRACKER_DBUS_ERROR, 0, "FD passing not supported");
@@ -390,7 +440,7 @@ tracker_steroids_prepare_query (TrackerSteroids        *steroids,
 
 		g_slice_free (ClientInfo, info);
 		g_free (sender);
-		return;
+		return NULL;
 	}
 
 	dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &request_id);
@@ -403,6 +453,28 @@ tracker_steroids_prepare_query (TrackerSteroids        *steroids,
 	dbus_g_method_send_reply (context, reply);
 
 	g_free (sender);
+
+	return info;
+}
+
+void
+tracker_steroids_prepare_query (TrackerSteroids        *steroids,
+                                const char             *query,
+                                DBusGMethodInvocation  *context,
+                                GError                **error)
+{
+	ClientInfo *info;
+	GError *inner_error = NULL;
+
+	tracker_dbus_async_return_if_fail (query != NULL, context);
+
+	info = tracker_steroids_prepare (steroids, context, FALSE, &inner_error);
+
+	if (!info) {
+		g_propagate_error (error, inner_error);
+	} else {
+		info->query = g_strdup (query);
+	}
 }
 
 void
@@ -452,6 +524,78 @@ tracker_steroids_fetch (TrackerSteroids        *steroids,
 	g_free (sender);
 }
 
+void
+tracker_steroids_prepare_update (TrackerSteroids        *steroids,
+                                 DBusGMethodInvocation  *context,
+                                 GError                **error)
+{
+	ClientInfo *info;
+	GError *inner_error = NULL;
+
+	info = tracker_steroids_prepare (steroids, context, TRUE, &inner_error);
+
+	if (!info) {
+		g_propagate_error (error, inner_error);
+	}
+}
+
+void
+tracker_steroids_update (TrackerSteroids        *steroids,
+                         guint                   query_id,
+                         DBusGMethodInvocation  *context,
+                         GError                **error)
+{
+	TrackerSteroidsPrivate *priv = TRACKER_STEROIDS_GET_PRIVATE (steroids);
+	ClientInfo             *info;
+	guint                   request_id;
+	gchar                  *sender;
+	static char             query_size_buffer[sizeof(int)];
+	int                     query_size;
+	GError                 *inner_error = NULL;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_request_new (request_id,
+	                          context,
+	                          "%s(): %u",
+	                          __FUNCTION__,
+	                          query_id);
+
+	info = g_hash_table_lookup (priv->clients,
+	                            GUINT_TO_POINTER (query_id));
+
+	if (!info) {
+		g_set_error (&inner_error, TRACKER_DBUS_ERROR, 0, "Wrong query id");
+		tracker_dbus_request_failed (request_id,
+		                             context,
+		                             &inner_error,
+		                             NULL);
+		dbus_g_method_return_error (info->context, inner_error);
+		g_propagate_error (error, inner_error);
+
+		return;
+	}
+
+	info->request_id = request_id;
+	info->context = context;
+
+	sender = dbus_g_method_get_sender (context);
+
+	buffer_read (info->fd, query_size_buffer, sizeof (int));
+	query_size = buffer_read_int (query_size_buffer);
+
+	/* We malloc one more char to ensure string is 0 terminated */
+	info->query = g_malloc0 ((1 + query_size) * sizeof (char));
+
+	buffer_read (info->fd, info->query, query_size);
+
+	tracker_store_sparql_update (info->query, TRACKER_STORE_PRIORITY_HIGH, FALSE,
+	                             update_callback, sender,
+	                             info, destroy_client_info);
+
+	g_free (sender);
+}
+
 static void
 tracker_steroids_finalize (GObject *object)
 {
diff --git a/src/tracker-store/tracker-steroids.h b/src/tracker-store/tracker-steroids.h
index 7a4e3ea..d941cb6 100644
--- a/src/tracker-store/tracker-steroids.h
+++ b/src/tracker-store/tracker-steroids.h
@@ -65,5 +65,12 @@ void             tracker_steroids_fetch         (TrackerSteroids        *steroid
                                                  guint                   query_id,
                                                  DBusGMethodInvocation  *context,
                                                  GError                **error);
+void             tracker_steroids_prepare_update (TrackerSteroids        *steroids,
+                                                  DBusGMethodInvocation  *context,
+                                                  GError                **error);
+void             tracker_steroids_update         (TrackerSteroids        *steroids,
+                                                  guint                   query_id,
+                                                  DBusGMethodInvocation  *context,
+                                                  GError                **error);
 
 #endif /* __TRACKER_STEROIDS_H__ */



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