[tracker/dbus-fd-experiment: 7/7] libtracker-client: Add SparqlUpdate for steroids



commit 04941f03855d4dea1ab5de77edbdcbba8ab2cfc1
Author: Adrien Bustany <abustany gnome org>
Date:   Tue Jun 1 11:35:02 2010 -0400

    libtracker-client: Add SparqlUpdate for steroids

 src/libtracker-client/tracker.c |  146 +++++++++++++++++++++++++++++++++++++++
 src/libtracker-client/tracker.h |    3 +
 2 files changed, 149 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-client/tracker.c b/src/libtracker-client/tracker.c
index 784c3d9..43f5623 100644
--- a/src/libtracker-client/tracker.c
+++ b/src/libtracker-client/tracker.c
@@ -725,6 +725,15 @@ buffer_read_int (char *buf)
 	return result;
 }
 
+static void
+buffer_write_int (char *buf, int value)
+{
+	memset (buf++, (value      ) & 0xff, sizeof (char));
+	memset (buf++, (value >>  8) & 0xff, sizeof (char));
+	memset (buf++, (value >> 16) & 0xff, sizeof (char));
+	memset (buf++, (value >> 24) & 0xff, sizeof (char));
+}
+
 static int
 iterator_buffer_read_int (TrackerResultIterator *iterator)
 {
@@ -766,6 +775,35 @@ pipe_read (int fd, char *dst, int size)
 	return TRUE;
 }
 
+static gboolean
+pipe_write (int fd, const char *src, int size)
+{
+	ssize_t sent = 0;
+	ssize_t ret;
+
+	while (sent < size) {
+		ret = write (fd,
+		             src + sent,
+		             size - sent);
+		if (ret < 0) {
+			switch (errno) {
+			case EAGAIN:
+				break;
+			case EPIPE:
+				g_critical ("SIGPIPE in pipe_write");
+				return FALSE;
+			default:
+				g_critical ("write returned %d in pipe_write", errno);
+				return FALSE;
+			}
+		} else {
+			sent += ret;
+		}
+	}
+
+	return TRUE;
+}
+
 static int
 iterator_buffer_fill (TrackerResultIterator *iterator)
 {
@@ -1613,6 +1651,114 @@ tracker_resources_sparql_update (TrackerClient  *client,
 	                                                  error);
 }
 
+void
+tracker_resources_sparql_update_fast (TrackerClient  *client,
+                                      const gchar    *query,
+                                      GError        **error)
+{
+	TrackerClientPrivate *private;
+	DBusConnection *connection;
+	DBusMessage *message;
+	DBusMessage *reply;
+	DBusPendingCall *call;
+	guint query_id;
+	DBusError dbus_error;
+	int fd;
+	char *query_size_buffer;
+	int query_len;
+	int query_index;
+
+	g_return_if_fail (TRACKER_IS_CLIENT (client));
+	g_return_if_fail (query != NULL);
+
+	private = TRACKER_CLIENT_GET_PRIVATE (client);
+
+	connection = dbus_g_connection_get_connection (private->connection);
+
+	dbus_error_init (&dbus_error);
+
+	message = dbus_message_new_method_call (TRACKER_STEROIDS_SERVICE,
+	                                        TRACKER_STEROIDS_PATH,
+	                                        TRACKER_STEROIDS_INTERFACE,
+	                                        "PrepareUpdate");
+	reply = dbus_connection_send_with_reply_and_block (connection,
+	                                                   message,
+	                                                   -1,
+	                                                   &dbus_error);
+	dbus_message_unref (message);
+
+	if (!reply) {
+		dbus_set_g_error (error, &dbus_error);
+		return;
+	}
+
+	dbus_message_get_args (reply,
+	                       &dbus_error,
+	                       DBUS_TYPE_UNIX_FD, &fd,
+	                       DBUS_TYPE_UINT32,  &query_id,
+	                       DBUS_TYPE_INVALID);
+	dbus_message_unref (reply);
+
+	message = dbus_message_new_method_call (TRACKER_STEROIDS_SERVICE,
+	                                        TRACKER_STEROIDS_PATH,
+	                                        TRACKER_STEROIDS_INTERFACE,
+	                                        "Update");
+	dbus_message_append_args (message,
+	                          DBUS_TYPE_UINT32, &query_id,
+	                          DBUS_TYPE_INVALID);
+	dbus_connection_send_with_reply (connection,
+	                                 message,
+	                                 &call,
+	                                 -1);
+
+	if (!call) {
+		g_set_error (error,
+		             TRACKER_CLIENT_ERROR,
+		             TRACKER_CLIENT_ERROR_UNSUPPORTED,
+		             "FD passing unsupported or connection disconnected");
+		return;
+	}
+
+	query_size_buffer = g_malloc (sizeof (int));
+
+	/* We don't need to null terminate, the store will do it for us */
+	query_len = strlen (query);
+	query_index = 0;
+	buffer_write_int (query_size_buffer, query_len);
+
+	pipe_write (fd, query_size_buffer, sizeof (int));
+
+	if ((sizeof (int) + query_len) > TRACKER_STEROIDS_BUFFER_SIZE) {
+		pipe_write (fd, query, TRACKER_STEROIDS_BUFFER_SIZE - sizeof (int));
+		query_index += TRACKER_STEROIDS_BUFFER_SIZE - sizeof (int);
+	}
+
+	while (query_index < query_len) {
+		int to_send = MIN(TRACKER_STEROIDS_BUFFER_SIZE, query_len - query_index);
+		pipe_write (fd, query + query_index, to_send);
+		query_index += to_send;
+	}
+
+	g_free (query_size_buffer);
+
+	dbus_pending_call_block (call);
+
+	reply = dbus_pending_call_steal_reply (call);
+
+	g_assert (reply);
+
+	if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
+		dbus_set_error_from_message (&dbus_error, reply);
+		dbus_set_g_error (error, &dbus_error);
+		dbus_pending_call_unref (call);
+		return;
+	}
+
+	dbus_message_unref (reply);
+
+	dbus_pending_call_unref (call);
+}
+
 GPtrArray *
 tracker_resources_sparql_update_blank (TrackerClient  *client,
                                        const gchar    *query,
diff --git a/src/libtracker-client/tracker.h b/src/libtracker-client/tracker.h
index f6fd5f0..7b4ec65 100644
--- a/src/libtracker-client/tracker.h
+++ b/src/libtracker-client/tracker.h
@@ -146,6 +146,9 @@ const gchar *  tracker_result_iterator_value               (TrackerResultIterato
 void           tracker_resources_sparql_update             (TrackerClient          *client,
                                                             const gchar            *query,
                                                             GError                **error);
+void           tracker_resources_sparql_update_fast        (TrackerClient          *client,
+                                                            const gchar            *query,
+                                                            GError                **error);
 GPtrArray *    tracker_resources_sparql_update_blank       (TrackerClient          *client,
                                                             const gchar            *query,
                                                             GError                **error);



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