[tracker/wip/carlosg/remote-conn-rewrite] libtracker-sparql: Rewrite TrackerRemoteConnection
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/remote-conn-rewrite] libtracker-sparql: Rewrite TrackerRemoteConnection
- Date: Mon, 9 May 2022 10:26:25 +0000 (UTC)
commit 30b661988fbdf0739e44cc8b880fe0985af961a6
Author: Carlos Garnacho <carlosg gnome org>
Date: Sat May 7 15:49:27 2022 +0200
libtracker-sparql: Rewrite TrackerRemoteConnection
This very cathartic change rewrites the remote TrackerSparqlConnection
implementation from Vala to C, besides the additional boilerplate code
is pretty much 1:1 otherwise.
Indirectly fixes build errors when using tracker as a submodule (like
in tracker-miners CI) on some semi-recent Vala versions (e.g. the one
in F34), seen as:
subprojects/tracker/src/libtracker-sparql/libtracker-sparql-private.a.p/remote/tracker-remote.c:58:8:
error: redefinition of 'struct _TrackerRemoteConnection'
58 | struct _TrackerRemoteConnection {
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from
subprojects/tracker/src/libtracker-sparql/libtracker-sparql-private.a.p/remote/tracker-remote.c:34:
subprojects/tracker/src/libtracker-sparql/tracker-sparql-private.h:88:8: note: originally defined here
88 | struct _TrackerRemoteConnection {
| ^~~~~~~~~~~~~~~~~~~~~~~~
Where both tracker-remote.c and tracker-sparql-private.h here are
files generated by Vala, and the latter should have no struct
definitions.
But this also reduces on symbols that Vala unintendedly makes
public behind our back (through VALA_EXTERN).
Closes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/220
src/libtracker-sparql/remote/meson.build | 3 +-
src/libtracker-sparql/remote/tracker-remote.c | 360 +++++++++++++++++++++++
src/libtracker-sparql/remote/tracker-remote.h | 38 +++
src/libtracker-sparql/remote/tracker-remote.vala | 80 -----
src/libtracker-sparql/remote/tracker-remote.vapi | 30 --
src/libtracker-sparql/tracker-backend.vala | 5 -
src/libtracker-sparql/tracker-connection.c | 33 ++-
7 files changed, 421 insertions(+), 128 deletions(-)
---
diff --git a/src/libtracker-sparql/remote/meson.build b/src/libtracker-sparql/remote/meson.build
index d41c96509..741a927e1 100644
--- a/src/libtracker-sparql/remote/meson.build
+++ b/src/libtracker-sparql/remote/meson.build
@@ -2,8 +2,7 @@ remote_files = files(
'tracker-http.c',
'tracker-remote-statement.c',
'tracker-remote-namespaces.c',
- 'tracker-remote.vapi',
- 'tracker-remote.vala',
+ 'tracker-remote.c',
)
module_sources = files('tracker-http-module.c')
diff --git a/src/libtracker-sparql/remote/tracker-remote.c b/src/libtracker-sparql/remote/tracker-remote.c
new file mode 100644
index 000000000..7349d3512
--- /dev/null
+++ b/src/libtracker-sparql/remote/tracker-remote.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2016 Carlos Garnacho <carlosg 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.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#include "config.h"
+
+#include "tracker-remote.h"
+
+#include "tracker-http.h"
+#include "tracker-remote-namespaces.h"
+#include "tracker-remote-statement.h"
+
+struct _TrackerRemoteConnection
+{
+ TrackerSparqlConnection parent_instance;
+};
+
+typedef struct _TrackerRemoteConnectionPrivate TrackerRemoteConnectionPrivate;
+
+struct _TrackerRemoteConnectionPrivate
+{
+ TrackerHttpClient *client;
+ TrackerNamespaceManager *namespaces;
+ gchar *base_uri;
+};
+
+enum {
+ PROP_0,
+ PROP_BASE_URI,
+ N_PROPS
+};
+
+static GParamSpec *props[N_PROPS];
+
+G_DEFINE_TYPE_WITH_PRIVATE (TrackerRemoteConnection, tracker_remote_connection,
+ TRACKER_TYPE_SPARQL_CONNECTION)
+
+static void
+tracker_remote_connection_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerRemoteConnection *remote =
+ TRACKER_REMOTE_CONNECTION (object);
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+
+ switch (prop_id) {
+ case PROP_BASE_URI:
+ priv->base_uri = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+tracker_remote_connection_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerRemoteConnection *remote =
+ TRACKER_REMOTE_CONNECTION (object);
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+
+ switch (prop_id) {
+ case PROP_BASE_URI:
+ g_value_set_string (value, priv->base_uri);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+tracker_remote_connection_finalize (GObject *object)
+{
+ TrackerRemoteConnection *remote =
+ TRACKER_REMOTE_CONNECTION (object);
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+
+ g_object_unref (priv->client);
+ g_free (priv->base_uri);
+
+ G_OBJECT_CLASS (tracker_remote_connection_parent_class)->finalize (object);
+}
+
+static TrackerSparqlCursor *
+tracker_remote_connection_query (TrackerSparqlConnection *connection,
+ const gchar *sparql,
+ GCancellable *cancellable,
+ GError **error)
+{
+ TrackerRemoteConnection *remote =
+ TRACKER_REMOTE_CONNECTION (connection);
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+ TrackerSerializerFormat format;
+ TrackerSparqlCursor *deserializer;
+ GInputStream *stream;
+ guint formats =
+ (1 << TRACKER_SERIALIZER_FORMAT_JSON) ||
+ (1 << TRACKER_SERIALIZER_FORMAT_XML);
+
+ stream = tracker_http_client_send_message (priv->client,
+ priv->base_uri,
+ sparql, formats,
+ cancellable,
+ &format,
+ error);
+ if (!stream)
+ return NULL;
+
+ deserializer = tracker_deserializer_new (stream, NULL, format);
+ g_object_unref (stream);
+
+ return deserializer;
+}
+
+static void
+query_message_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ TrackerSerializerFormat format;
+ TrackerSparqlCursor *deserializer;
+ GInputStream *stream;
+ GTask *task = user_data;
+ GError *error = NULL;
+
+ stream = tracker_http_client_send_message_finish (TRACKER_HTTP_CLIENT (source),
+ res,
+ &format,
+ &error);
+ if (stream) {
+ deserializer = tracker_deserializer_new (stream, NULL, format);
+ g_object_unref (stream);
+
+ g_task_return_pointer (task, deserializer, g_object_unref);
+ } else {
+ g_task_return_error (task, error);
+ }
+
+ g_object_unref (task);
+}
+
+static void
+tracker_remote_connection_query_async (TrackerSparqlConnection *connection,
+ const gchar *sparql,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TrackerRemoteConnection *remote =
+ TRACKER_REMOTE_CONNECTION (connection);
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+ GTask *task;
+ guint flags =
+ (1 << TRACKER_SERIALIZER_FORMAT_JSON) ||
+ (1 << TRACKER_SERIALIZER_FORMAT_XML);
+
+ task = g_task_new (connection, cancellable, callback, user_data);
+ tracker_http_client_send_message_async (priv->client,
+ priv->base_uri,
+ sparql, flags,
+ cancellable,
+ query_message_cb,
+ task);
+}
+
+static TrackerSparqlCursor *
+tracker_remote_connection_query_finish (TrackerSparqlConnection *connection,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static TrackerSparqlStatement *
+tracker_remote_connection_query_statement (TrackerSparqlConnection *connection,
+ const gchar *sparql,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return tracker_remote_statement_new (connection, sparql, error);
+}
+
+static void
+tracker_remote_connection_close (TrackerSparqlConnection *connection)
+{
+}
+
+static void
+tracker_remote_connection_close_async (TrackerSparqlConnection *connection,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ task = g_task_new (connection, cancellable, callback, user_data);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static gboolean
+tracker_remote_connection_close_finish (TrackerSparqlConnection *connection,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+serialize_message_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GInputStream *stream;
+ GTask *task = user_data;
+ GError *error = NULL;
+
+ stream = tracker_http_client_send_message_finish (TRACKER_HTTP_CLIENT (source),
+ res,
+ NULL,
+ &error);
+ if (stream)
+ g_task_return_pointer (task, stream, g_object_unref);
+ else
+ g_task_return_error (task, error);
+
+ g_object_unref (task);
+}
+
+static void
+tracker_remote_connection_serialize_async (TrackerSparqlConnection *connection,
+ TrackerSerializeFlags flags,
+ TrackerRdfFormat format,
+ const gchar *query,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TrackerRemoteConnection *remote =
+ TRACKER_REMOTE_CONNECTION (connection);
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+ GTask *task;
+ guint formats = 0;
+
+ if (format == TRACKER_RDF_FORMAT_TURTLE)
+ formats = 1 << TRACKER_SERIALIZER_FORMAT_TTL;
+ else if (format == TRACKER_RDF_FORMAT_TRIG)
+ formats = 1 << TRACKER_SERIALIZER_FORMAT_TRIG;
+
+ task = g_task_new (connection, cancellable, callback, user_data);
+ tracker_http_client_send_message_async (priv->client,
+ priv->base_uri,
+ query, formats,
+ cancellable,
+ serialize_message_cb,
+ task);
+}
+
+static GInputStream *
+tracker_remote_connection_serialize_finish (TrackerSparqlConnection *connection,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static TrackerNamespaceManager *
+tracker_remote_connection_get_namespace_manager (TrackerSparqlConnection *connection)
+{
+ TrackerRemoteConnection *remote =
+ TRACKER_REMOTE_CONNECTION (connection);
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+
+ if (!priv->namespaces) {
+ priv->namespaces =
+ tracker_remote_namespace_manager_new (connection);
+ }
+
+ return priv->namespaces;
+}
+
+static void
+tracker_remote_connection_class_init (TrackerRemoteConnectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TrackerSparqlConnectionClass *conn_class =
+ TRACKER_SPARQL_CONNECTION_CLASS (klass);
+
+ object_class->set_property = tracker_remote_connection_set_property;
+ object_class->get_property = tracker_remote_connection_get_property;
+ object_class->finalize = tracker_remote_connection_finalize;
+
+ conn_class->query = tracker_remote_connection_query;
+ conn_class->query_async = tracker_remote_connection_query_async;
+ conn_class->query_finish = tracker_remote_connection_query_finish;
+ conn_class->query_statement = tracker_remote_connection_query_statement;
+ conn_class->close = tracker_remote_connection_close;
+ conn_class->close_async = tracker_remote_connection_close_async;
+ conn_class->close_finish = tracker_remote_connection_close_finish;
+ conn_class->serialize_async = tracker_remote_connection_serialize_async;
+ conn_class->serialize_finish = tracker_remote_connection_serialize_finish;
+ conn_class->get_namespace_manager = tracker_remote_connection_get_namespace_manager;
+
+ props[PROP_BASE_URI] =
+ g_param_spec_string ("base-uri",
+ "Base URI",
+ "Base URI",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE);
+
+ g_object_class_install_properties (object_class, N_PROPS, props);
+}
+
+static void
+tracker_remote_connection_init (TrackerRemoteConnection *remote)
+{
+ TrackerRemoteConnectionPrivate *priv =
+ tracker_remote_connection_get_instance_private (remote);
+
+ priv->client = tracker_http_client_new ();
+}
+
+TrackerRemoteConnection *
+tracker_remote_connection_new (const gchar *base_uri)
+{
+ return g_object_new (TRACKER_TYPE_REMOTE_CONNECTION,
+ "base-uri", base_uri,
+ NULL);
+}
diff --git a/src/libtracker-sparql/remote/tracker-remote.h b/src/libtracker-sparql/remote/tracker-remote.h
new file mode 100644
index 000000000..f84a4b1dd
--- /dev/null
+++ b/src/libtracker-sparql/remote/tracker-remote.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 Carlos Garnacho <carlosg 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.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#ifndef __TRACKER_REMOTE_H__
+#define __TRACKER_REMOTE_H__
+
+#include <libtracker-sparql/tracker-sparql.h>
+
+#define TRACKER_TYPE_REMOTE_CONNECTION (tracker_remote_connection_get_type())
+
+G_DECLARE_FINAL_TYPE (TrackerRemoteConnection,
+ tracker_remote_connection,
+ TRACKER, REMOTE_CONNECTION,
+ TrackerSparqlConnection)
+
+GType tracker_remote_connection_get_type (void) G_GNUC_CONST;
+
+TrackerRemoteConnection *tracker_remote_connection_new (const gchar *base_uri);
+
+#endif /* __TRACKER_REMOTE_H__ */
diff --git a/src/libtracker-sparql/tracker-backend.vala b/src/libtracker-sparql/tracker-backend.vala
index f2d497f6a..af1102d5a 100644
--- a/src/libtracker-sparql/tracker-backend.vala
+++ b/src/libtracker-sparql/tracker-backend.vala
@@ -82,8 +82,3 @@ public static async Tracker.Sparql.Connection tracker_sparql_connection_new_asyn
yield conn.init_async (Priority.DEFAULT, cancellable);
return conn;
}
-
-public static Tracker.Sparql.Connection tracker_sparql_connection_remote_new (string uri_base) {
- Tracker.get_debug_flags ();
- return new Tracker.Remote.Connection (uri_base);
-}
diff --git a/src/libtracker-sparql/tracker-connection.c b/src/libtracker-sparql/tracker-connection.c
index cb817b765..c52e6c7c4 100644
--- a/src/libtracker-sparql/tracker-connection.c
+++ b/src/libtracker-sparql/tracker-connection.c
@@ -60,6 +60,9 @@
#include "tracker-connection.h"
#include "tracker-private.h"
+#include "tracker-debug.h"
+
+#include "remote/tracker-remote.h"
G_DEFINE_ABSTRACT_TYPE (TrackerSparqlConnection, tracker_sparql_connection,
G_TYPE_OBJECT)
@@ -83,6 +86,9 @@ tracker_sparql_connection_class_init (TrackerSparqlConnectionClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = tracker_sparql_connection_dispose;
+
+ /* Initialize debug flags */
+ tracker_get_debug_flags ();
}
gboolean
@@ -216,17 +222,6 @@ tracker_sparql_connection_lookup_dbus_service (TrackerSparqlConnection *connect
* Since: 3.1
*/
-/**
- * tracker_sparql_connection_remote_new:
- * @uri_base: Base URI of the remote connection
- *
- * Connects to a remote SPARQL endpoint. The connection is made using the libsoup
- * HTTP library. The connection will normally use the http:// or https:// protocol.
- *
- * Returns: (transfer full): a new remote #TrackerSparqlConnection. Call
- * g_object_unref() on the object when no longer used.
- */
-
/**
* tracker_sparql_connection_query:
* @connection: a #TrackerSparqlConnection
@@ -988,3 +983,19 @@ tracker_sparql_connection_map_connection (TrackerSparqlConnection *connection,
handle_name,
service_connection);
}
+
+/**
+ * tracker_sparql_connection_remote_new:
+ * @uri_base: Base URI of the remote connection
+ *
+ * Connects to a remote SPARQL endpoint. The connection is made using the libsoup
+ * HTTP library. The connection will normally use the http:// or https:// protocol.
+ *
+ * Returns: (transfer full): a new remote #TrackerSparqlConnection. Call
+ * g_object_unref() on the object when no longer used.
+ */
+TrackerSparqlConnection *
+tracker_sparql_connection_remote_new (const gchar *uri_base)
+{
+ return TRACKER_SPARQL_CONNECTION (tracker_remote_connection_new (uri_base));
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]