[tracker/direct-access: 37/122] libtracker-bus: Implemented D-Bus FD passing using TrackerSparqlCursor API
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/direct-access: 37/122] libtracker-bus: Implemented D-Bus FD passing using TrackerSparqlCursor API
- Date: Fri, 6 Aug 2010 10:17:12 +0000 (UTC)
commit 49312ea016254399c3cd9dc90b0820193f61e1a8
Author: Martyn Russell <martyn lanedo com>
Date: Wed Jul 14 17:42:34 2010 +0100
libtracker-bus: Implemented D-Bus FD passing using TrackerSparqlCursor API
src/libtracker-bus/Makefile.am | 6 +-
src/libtracker-bus/tracker-bus-cursor.c | 263 +++++++++++++++++++++++++++++++
src/libtracker-bus/tracker-bus.vala | 35 ++++-
tests/functional-tests/Makefile.am | 35 ++++-
tests/functional-tests/bus-test.vala | 41 +++++
tests/functional-tests/direct-test.vala | 38 +++--
6 files changed, 395 insertions(+), 23 deletions(-)
---
diff --git a/src/libtracker-bus/Makefile.am b/src/libtracker-bus/Makefile.am
index e9c2f4e..1d95674 100644
--- a/src/libtracker-bus/Makefile.am
+++ b/src/libtracker-bus/Makefile.am
@@ -7,6 +7,7 @@ INCLUDES = \
-I$(top_srcdir)/src/libtracker-sparql \
-I$(top_builddir)/src \
$(WARN_CFLAGS) \
+ $(DBUS_CFLAGS) \
$(GLIB2_CFLAGS) \
$(GCOV_CFLAGS)
@@ -19,7 +20,8 @@ libtracker_bus_la_VALASOURCES = \
libtracker_bus_ TRACKER_API_VERSION@_la_SOURCES = \
libtracker-bus.vala.stamp \
- $(libtracker_bus_la_VALASOURCES:.vala=.c)
+ $(libtracker_bus_la_VALASOURCES:.vala=.c) \
+ tracker-bus-cursor.c
libtracker_bus_ TRACKER_API_VERSION@_la_LDFLAGS = \
-shared -fPIC -module -avoid-version
@@ -41,7 +43,7 @@ vapi_DATA = \
tracker-bus-$(TRACKER_API_VERSION).vapi
libtracker-bus.vala.stamp: $(libtracker_bus_la_VALASOURCES) $(vapi_sources)
- $(AM_V_GEN)$(VALAC) $(GCOV_VALAFLAGS) -C $(VALAFLAGS) --pkg gio-2.0 -H tracker-bus.h --vapi tracker-bus-$(TRACKER_API_VERSION).vapi $^
+ $(AM_V_GEN)$(VALAC) $(GCOV_VALAFLAGS) -C $(VALAFLAGS) --pkg gio-2.0 --pkg dbus-glib-1 -H tracker-bus.h --vapi tracker-bus-$(TRACKER_API_VERSION).vapi $^
$(AM_V_GEN)touch $@
libtracker_bus_ TRACKER_API_VERSION@_la_LIBADD = \
diff --git a/src/libtracker-bus/tracker-bus-cursor.c b/src/libtracker-bus/tracker-bus-cursor.c
new file mode 100644
index 0000000..b48c9cc
--- /dev/null
+++ b/src/libtracker-bus/tracker-bus-cursor.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2006, Jamie McCracken <jamiemcc gnome org>
+ * Copyright (C) 2008-2010, Nokia <ivan frade nokia com>
+ * Copyright (C) 2010, Codeminded BVBA <abustany gnome org>
+ *
+ * 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.1 of the License, 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <libtracker-common/tracker-common.h>
+
+#include <libtracker-sparql/tracker-sparql.h>
+
+#include "tracker-bus.h"
+
+#define TRACKER_TYPE_BUS_CURSOR (tracker_bus_cursor_get_type ())
+#define TRACKER_BUS_CURSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRACKER_TYPE_BUS_CURSOR, TrackerBusCursor))
+#define TRACKER_BUS_CURSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_BUS_CURSOR, TrackerBusCursorClass))
+#define TRACKER_IS_BUS_CURSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRACKER_TYPE_BUS_CURSOR))
+#define TRACKER_IS_BUS_CURSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((o), TRACKER_TYPE_BUS_CURSOR))
+#define TRACKER_BUS_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TRACKER_TYPE_BUS_CURSOR, TrackerBusCursorClass))
+
+typedef struct TrackerBusCursor TrackerBusCursor;
+typedef struct TrackerBusCursorClass TrackerBusCursorClass;
+
+struct TrackerBusCursor {
+ TrackerSparqlCursor parent_instance;
+
+ char *buffer;
+ int buffer_index;
+ long buffer_size;
+
+ guint n_columns;
+ int *offsets;
+ char *data;
+};
+
+struct TrackerBusCursorClass {
+ TrackerSparqlCursorClass parent_class;
+};
+
+GType tracker_bus_cursor_get_type (void);
+void tracker_bus_cursor_finalize (GObject *object);
+
+G_DEFINE_TYPE (TrackerBusCursor, tracker_bus_cursor, TRACKER_SPARQL_TYPE_CURSOR)
+
+static void
+tracker_bus_cursor_rewind (TrackerBusCursor *cursor)
+{
+ /* FIXME: Implement */
+}
+
+static inline int
+buffer_read_int (TrackerBusCursor *cursor)
+{
+ int v = *((int *)(cursor->buffer + cursor->buffer_index));
+
+ cursor->buffer_index += 4;
+
+ return v;
+}
+
+static gboolean
+tracker_bus_cursor_iter_next (TrackerBusCursor *cursor,
+ GCancellable *cancellable,
+ GError **error)
+{
+ int last_offset;
+
+ if (cursor->buffer_index >= cursor->buffer_size) {
+ return FALSE;
+ }
+
+ /* So, the make up on each cursor segment is:
+ *
+ * iteration = [4 bytes for number of columns,
+ * 4 bytes for last offset]
+ */
+ cursor->n_columns = buffer_read_int (cursor);
+ cursor->offsets = (int *)(cursor->buffer + cursor->buffer_index);
+ cursor->buffer_index += sizeof (int) * (cursor->n_columns - 1);
+
+ last_offset = buffer_read_int (cursor);
+ cursor->data = cursor->buffer + cursor->buffer_index;
+ cursor->buffer_index += last_offset + 1;
+
+ return TRUE;
+}
+
+static void
+tracker_bus_cursor_iter_next_thread (GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ /* This is stolen from the direct access work,
+ * do we REALLY need to do this in the next thread?
+ */
+
+ GError *error = NULL;
+ gboolean result;
+
+ result = tracker_bus_cursor_iter_next (TRACKER_BUS_CURSOR (object), cancellable, &error);
+ if (error) {
+ g_simple_async_result_set_from_error (res, error);
+ } else {
+ g_simple_async_result_set_op_res_gboolean (res, result);
+ }
+}
+
+static void
+tracker_bus_cursor_iter_next_async (TrackerBusCursor *cursor,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ res = g_simple_async_result_new (G_OBJECT (cursor), callback, user_data, tracker_bus_cursor_iter_next_async);
+ g_simple_async_result_run_in_thread (res, tracker_bus_cursor_iter_next_thread, 0, cancellable);
+}
+
+static gboolean
+tracker_bus_cursor_iter_next_finish (TrackerBusCursor *cursor,
+ GAsyncResult *res,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) {
+ return FALSE;
+ }
+ return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res));
+}
+
+static guint
+tracker_bus_cursor_get_n_columns (TrackerBusCursor *cursor)
+{
+ return cursor->n_columns;
+}
+
+static const gchar *
+tracker_bus_cursor_get_string (TrackerBusCursor *cursor,
+ guint column,
+ gint *length)
+{
+ g_return_val_if_fail (column < tracker_bus_cursor_get_n_columns (cursor), NULL);
+
+ if (column == 0) {
+ return cursor->data;
+ } else {
+ return cursor->data + cursor->offsets[column - 1] + 1;
+ }
+}
+
+static void
+tracker_bus_cursor_class_init (TrackerBusCursorClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ TrackerSparqlCursorClass *sparql_cursor_class = TRACKER_SPARQL_CURSOR_CLASS (class);
+
+ object_class->finalize = tracker_bus_cursor_finalize;
+
+ sparql_cursor_class->get_n_columns = (gint (*) (TrackerSparqlCursor *)) tracker_bus_cursor_get_n_columns;
+ sparql_cursor_class->get_string = (const gchar * (*) (TrackerSparqlCursor *, gint, gint*)) tracker_bus_cursor_get_string;
+ sparql_cursor_class->next = (gboolean (*) (TrackerSparqlCursor *, GCancellable *, GError **)) tracker_bus_cursor_iter_next;
+ sparql_cursor_class->next_async = (void (*) (TrackerSparqlCursor *, GCancellable *, GAsyncReadyCallback, gpointer)) tracker_bus_cursor_iter_next_async;
+ sparql_cursor_class->next_finish = (gboolean (*) (TrackerSparqlCursor *, GAsyncResult *, GError **)) tracker_bus_cursor_iter_next_finish;
+ sparql_cursor_class->rewind = (void (*) (TrackerSparqlCursor *)) tracker_bus_cursor_rewind;
+}
+
+void
+tracker_bus_cursor_init (TrackerBusCursor *cursor)
+{
+}
+
+void
+tracker_bus_cursor_finalize (GObject *object)
+{
+ TrackerBusCursor *cursor;
+
+ cursor = TRACKER_BUS_CURSOR (object);
+
+ g_free (cursor->buffer);
+
+ G_OBJECT_CLASS (tracker_bus_cursor_parent_class)->finalize (object);
+}
+
+
+// Public API
+
+TrackerSparqlCursor *
+tracker_bus_query (DBusGConnection *gconnection,
+ const gchar *query,
+ GError **error)
+{
+#ifdef HAVE_DBUS_FD_PASSING
+ TrackerBusCursor *cursor;
+ DBusConnection *connection;
+ DBusMessage *message;
+ DBusMessageIter iter;
+ int pipefd[2];
+ GError *inner_error = NULL;
+
+ g_return_val_if_fail (query, NULL);
+
+ if (pipe (pipefd) < 0) {
+ /* FIXME: Use proper error domain/code */
+ g_set_error (error, 0, 0, "Cannot open pipe");
+ return NULL;
+ }
+
+ connection = dbus_g_connection_get_connection (gconnection);
+
+ message = dbus_message_new_method_call (TRACKER_DBUS_SERVICE,
+ TRACKER_DBUS_OBJECT_STEROIDS,
+ TRACKER_DBUS_INTERFACE_STEROIDS,
+ "Query");
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &query);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &pipefd[1]);
+ close (pipefd[1]);
+
+ cursor = g_object_new (TRACKER_TYPE_BUS_CURSOR, NULL);
+
+ tracker_dbus_send_and_splice (connection,
+ message,
+ pipefd[0],
+ NULL,
+ (void **) &cursor->buffer,
+ &cursor->buffer_size,
+ &inner_error);
+ /* message is destroyed by tracker_dbus_send_and_splice */
+
+ if (G_UNLIKELY (inner_error)) {
+ g_propagate_error (error, inner_error);
+ g_object_unref (cursor);
+ cursor = NULL;
+ }
+
+ return TRACKER_SPARQL_CURSOR (cursor);
+#else /* HAVE_DBUS_FD_PASSING */
+ return NULL;
+#endif /* HAVE_DBUS_FD_PASSING */
+}
+
diff --git a/src/libtracker-bus/tracker-bus.vala b/src/libtracker-bus/tracker-bus.vala
index 91c60f2..bc4a11b 100644
--- a/src/libtracker-bus/tracker-bus.vala
+++ b/src/libtracker-bus/tracker-bus.vala
@@ -17,26 +17,55 @@
* Boston, MA 02110-1301, USA.
*/
+public const string TRACKER_DBUS_SERVICE = "org.freedesktop.Tracker1";
+public const string TRACKER_DBUS_INTERFACE_RESOURCES = TRACKER_DBUS_SERVICE + ".Resources";
+public const string TRACKER_DBUS_OBJECT_RESOURCES = "/org/freedesktop/Tracker1/Resources";
+public const string TRACKER_DBUS_INTERFACE_STEROIDS = TRACKER_DBUS_SERVICE + ".Steroids";
+public const string TRACKER_DBUS_OBJECT_STEROIDS = "/org/freedesktop/Tracker1/Steroids";
+
+[DBus (name = TRACKER_SERVICE_RESOURCES)]
+private interface Tracker.Bus.Resources : GLib.Object {
+ public abstract string[,] SparqlQuery (string query) throws DBus.Error;
+}
+
+// Imported DBus FD API until we have support with Vala
+public extern Tracker.Sparql.Cursor tracker_bus_query (DBus.Connection connection, string query) throws GLib.Error;
+
+// Actual class definition
public class Tracker.Bus.Connection : Tracker.Sparql.Connection {
+ static DBus.Connection connection;
static bool initialized;
public Connection ()
requires (!initialized) {
initialized = true;
+
+ try {
+ connection = DBus.Bus.get (DBus.BusType.SESSION);
- // FIXME: Implement DBus stuff
+ // FIXME: Test for steroids and resources interfaces?
+// resources = (Resources) c.get_object (TRACKER_DBUS_SERVICE,
+// TRACKER_DBUS_OBJECT_RESOURCES,
+// TRACKER_DBUS_INTERFACE_RESOURCES);
+ } catch (DBus.Error e) {
+ warning ("Could not connect to D-Bus service:'%s': %s", TRACKER_DBUS_INTERFACE_RESOURCES, e.message);
+ initialized = false;
+ return;
+ }
+
+ initialized = true;
}
~Connection () {
- // Clean up connection
initialized = false;
}
public override Sparql.Cursor? query (string sparql, Cancellable? cancellable) throws GLib.Error {
- return null;
+ return tracker_bus_query (connection, sparql);
}
public async override Sparql.Cursor? query_async (string sparql, Cancellable? cancellable = null) throws GLib.Error {
+ // FIXME: Implement
return null;
}
}
diff --git a/tests/functional-tests/Makefile.am b/tests/functional-tests/Makefile.am
index 37b4754..ca76516 100644
--- a/tests/functional-tests/Makefile.am
+++ b/tests/functional-tests/Makefile.am
@@ -5,6 +5,7 @@ SUBDIRS = data
INCLUDES = \
-I$(top_builddir)/src/libtracker-sparql \
-I$(top_builddir)/src/libtracker-direct \
+ -I$(top_builddir)/src/libtracker-bus \
$(WARN_CFLAGS) \
$(DBUS_CFLAGS) \
$(GLIB2_CFLAGS) \
@@ -49,7 +50,7 @@ bashscripts_SCRIPTS = \
@sed -e "s|@topsrcdir[ ]|${top_srcdir}|" \
-e "s|@libexecdir[ ]|${libexecdir}|" $< > $@
-noinst_PROGRAMS = busy-handling-test direct-test
+noinst_PROGRAMS = busy-handling-test direct-test bus-test
busy_handling_test_VALASOURCES = busy-handling-test.vala
@@ -72,22 +73,46 @@ direct_test_SOURCES = \
direct_test.vala.stamp \
$(direct_test_VALASOURCES:.vala=.c)
-vapi_sources = \
- $(top_srcdir)/src/libtracker-sparql/tracker-sparql-$(TRACKER_API_VERSION).vapi \
+bus_test_VALASOURCES = bus-test.vala
+
+bus_test_SOURCES = \
+ bus_test.vala.stamp \
+ $(bus_test_VALASOURCES:.vala=.c)
+
+direct_vapi_sources = \
+ $(top_srcdir)/src/libtracker-sparql/tracker-sparql-$(TRACKER_API_VERSION).vapi \
$(top_srcdir)/src/libtracker-direct/tracker-direct-$(TRACKER_API_VERSION).vapi
-direct-test.vala.stamp: $(direct_test_VALASOURCES) $(vapi_sources)
+direct-test.vala.stamp: $(direct_test_VALASOURCES) $(direct_vapi_sources)
$(AM_V_GEN)$(VALAC) $(GCOV_VALAFLAGS) -C $(VALAFLAGS) --pkg gio-2.0 $^
$(AM_V_GEN)touch $@
direct_test_LDADD = \
$(top_builddir)/src/libtracker-direct/libtracker-direct-$(TRACKER_API_VERSION).la \
$(top_builddir)/src/libtracker-sparql/libtracker-sparql-$(TRACKER_API_VERSION).la \
+ $(GIO_LIBS) \
$(GLIB2_LIBS)
+bus_vapi_sources = \
+ $(top_srcdir)/src/libtracker-sparql/tracker-sparql-$(TRACKER_API_VERSION).vapi \
+ $(top_srcdir)/src/libtracker-bus/tracker-bus-$(TRACKER_API_VERSION).vapi
+
+bus-test.vala.stamp: $(bus_test_VALASOURCES) $(bus_vapi_sources)
+ $(AM_V_GEN)$(VALAC) $(GCOV_VALAFLAGS) -C $(VALAFLAGS) --pkg gio-2.0 --pkg dbus-glib-1 $^
+ $(AM_V_GEN)touch $@
+
+bus_test_LDADD = \
+ $(top_builddir)/src/libtracker-bus/libtracker-bus-$(TRACKER_API_VERSION).la \
+ $(top_builddir)/src/libtracker-sparql/libtracker-sparql-$(TRACKER_API_VERSION).la \
+ $(top_builddir)/src/libtracker-common/libtracker-common.la \
+ $(GIO_LIBS) \
+ $(GLIB2_LIBS) \
+ $(DBUS_LIBS)
+
BUILT_SOURCES = \
busy-handling-test.vala.stamp \
- direct-test.vala.stamp
+ direct-test.vala.stamp \
+ bus-test.vala.stamp
EXTRA_DIST = \
$(config_SCRIPTS) \
diff --git a/tests/functional-tests/bus-test.vala b/tests/functional-tests/bus-test.vala
new file mode 100644
index 0000000..68ad63a
--- /dev/null
+++ b/tests/functional-tests/bus-test.vala
@@ -0,0 +1,41 @@
+using Tracker;
+using Tracker.Sparql;
+
+int
+main( string[] args )
+{
+ Sparql.Connection con = new Tracker.Bus.Connection ();
+ Cursor cursor;
+
+ try {
+ cursor = con.query ("SELECT ?u WHERE { ?u a rdfs:Class }");
+ } catch (GLib.Error e) {
+ warning ("Couldn't perform query: %s", e.message);
+ return -1;
+ }
+
+ try {
+ while (cursor.next()) {
+ int i;
+
+ for (i = 0; i < cursor.n_columns; i++) {
+ print ("%s%s", i != 0 ? ",":"", cursor.get_string (i));
+ }
+
+ print ("\n");
+ }
+ } catch (GLib.Error e) {
+ warning ("Couldn't iterate query results: %s", e.message);
+ return -1;
+ }
+
+ // Testing new API with GModule
+
+// print ("\n\n");
+
+// Lookup foo = new Lookup ();
+
+
+ return( 0 );
+}
+
diff --git a/tests/functional-tests/direct-test.vala b/tests/functional-tests/direct-test.vala
index f00d8ce..b73581a 100644
--- a/tests/functional-tests/direct-test.vala
+++ b/tests/functional-tests/direct-test.vala
@@ -1,28 +1,40 @@
using Tracker;
using Tracker.Sparql;
-using Tracker.Direct;
int
main( string[] args )
{
-// Sparql.Connection con = new Direct.Connection ();
-// Cursor cursor = con.query ("SELECT ?u WHERE { ?u a rdfs:Class }");
+ Sparql.Connection con = new Tracker.Direct.Connection ();
+ Cursor cursor;
+
+ try {
+ cursor = con.query ("SELECT ?u WHERE { ?u a rdfs:Class }");
+ } catch (GLib.Error e) {
+ warning ("Couldn't perform query: %s", e.message);
+ return -1;
+ }
-// while (cursor.next()) {
-// int i;
+ try {
+ while (cursor.next()) {
+ int i;
-// for (i = 0; i < cursor.n_columns; i++) {
-// print ("%s%s", i != 0 ? ",":"", cursor.get_string (i));
-// }
+ for (i = 0; i < cursor.n_columns; i++) {
+ print ("%s%s", i != 0 ? ",":"", cursor.get_string (i));
+ }
-// print ("\n");
-// }
-
+ print ("\n");
+ }
+ } catch (GLib.Error e) {
+ warning ("Couldn't iterate query results: %s", e.message);
+ return -1;
+ }
+
// Testing new API with GModule
- print ("\n\n");
+// print ("\n\n");
+
+// Lookup foo = new Lookup ();
- Lookup foo = new Lookup ();
return( 0 );
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]