[tracker/wip/carlosg/fixes: 2/8] libtracker-sparql: Add "arguments" parameter to Query endpoint DBus method



commit ccc37e1c0158ae6bc5bc392bcb1547e504ee5f79
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Mar 1 15:01:57 2020 +0100

    libtracker-sparql: Add "arguments" parameter to Query endpoint DBus method
    
    If it is set and arguments are provided, we create a single-use
    TrackerSparqlStatement to handle it. This will allow using prepared
    statements across bus connections, but is unused at the moment.

 src/libtracker-bus/tracker-bus.vala           |  2 +-
 src/libtracker-sparql/tracker-endpoint-dbus.c | 90 +++++++++++++++++++++++++--
 2 files changed, 85 insertions(+), 7 deletions(-)
---
diff --git a/src/libtracker-bus/tracker-bus.vala b/src/libtracker-bus/tracker-bus.vala
index 03b3030f1..ea32e4e0a 100644
--- a/src/libtracker-bus/tracker-bus.vala
+++ b/src/libtracker-bus/tracker-bus.vala
@@ -60,7 +60,7 @@ public class Tracker.Bus.Connection : Tracker.Sparql.Connection {
        void send_query (string sparql, UnixOutputStream output, Cancellable? cancellable, 
AsyncReadyCallback? callback) throws GLib.IOError, GLib.Error {
                var message = new DBusMessage.method_call (dbus_name, object_path, ENDPOINT_IFACE, "Query");
                var fd_list = new UnixFDList ();
-               message.set_body (new Variant ("(sh)", sparql, fd_list.append (output.fd)));
+               message.set_body (new Variant ("(sha{sv})", sparql, fd_list.append (output.fd), null));
                message.set_unix_fd_list (fd_list);
 
                bus.send_message_with_reply.begin (message, DBusSendMessageFlags.NONE, int.MAX, null, 
cancellable, callback);
diff --git a/src/libtracker-sparql/tracker-endpoint-dbus.c b/src/libtracker-sparql/tracker-endpoint-dbus.c
index 89e12fa98..1668aa97e 100644
--- a/src/libtracker-sparql/tracker-endpoint-dbus.c
+++ b/src/libtracker-sparql/tracker-endpoint-dbus.c
@@ -36,6 +36,7 @@ static const gchar introspection_xml[] =
        "    <method name='Query'>"
        "      <arg type='s' name='query' direction='in' />"
        "      <arg type='h' name='output_stream' direction='in' />"
+       "      <arg type='a{sv}' name='arguments' direction='in' />"
        "      <arg type='as' name='result' direction='out' />"
        "    </method>"
        "    <method name='Update'>"
@@ -303,6 +304,21 @@ query_cb (GObject      *object,
        query_request_free (request);
 }
 
+static void
+stmt_execute_cb (GObject      *object,
+                 GAsyncResult *res,
+                 gpointer      user_data)
+{
+       QueryRequest *request = user_data;
+       TrackerSparqlCursor *cursor;
+       GError *error = NULL;
+
+       cursor = tracker_sparql_statement_execute_finish (TRACKER_SPARQL_STATEMENT (object),
+                                                         res, &error);
+       handle_cursor_reply (request, cursor, error);
+       query_request_free (request);
+}
+
 static void
 update_cb (GObject      *object,
            GAsyncResult *res,
@@ -400,6 +416,47 @@ read_update_blank_cb (GObject      *object,
                                                      request);
 }
 
+static TrackerSparqlStatement *
+create_statement (TrackerSparqlConnection  *conn,
+                  const gchar              *query,
+                  GVariantIter             *arguments,
+                  GCancellable             *cancellable,
+                  GError                  **error)
+{
+       TrackerSparqlStatement *stmt;
+       GVariant *value;
+       const gchar *arg;
+
+       stmt = tracker_sparql_connection_query_statement (conn,
+                                                         query,
+                                                         cancellable,
+                                                         error);
+       if (!stmt)
+               return NULL;
+
+       while (g_variant_iter_loop (arguments, "{sv}", &arg, &value)) {
+               if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) {
+                       tracker_sparql_statement_bind_string (stmt, arg,
+                                                             g_variant_get_string (value, NULL));
+               } else if (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)) {
+                       tracker_sparql_statement_bind_double (stmt, arg,
+                                                             g_variant_get_double (value));
+               } else if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT64)) {
+                       tracker_sparql_statement_bind_double (stmt, arg,
+                                                             g_variant_get_int64 (value));
+               } else if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) {
+                       tracker_sparql_statement_bind_double (stmt, arg,
+                                                             g_variant_get_boolean (value));
+               } else {
+                       g_warning ("Unhandled type '%s' for argument %s",
+                                  g_variant_get_type_string (value),
+                                  arg);
+               }
+       }
+
+       return stmt;
+}
+
 static void
 endpoint_dbus_iface_method_call (GDBusConnection       *connection,
                                  const gchar           *sender,
@@ -414,6 +471,7 @@ endpoint_dbus_iface_method_call (GDBusConnection       *connection,
        TrackerSparqlConnection *conn;
        GUnixFDList *fd_list;
        GError *error = NULL;
+       GVariantIter *arguments;
        gchar *query;
        gint handle, fd = -1;
 
@@ -421,7 +479,7 @@ endpoint_dbus_iface_method_call (GDBusConnection       *connection,
        fd_list = g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation));
 
        if (g_strcmp0 (method_name, "Query") == 0) {
-               g_variant_get (parameters, "(sh)", &query, &handle);
+               g_variant_get (parameters, "(sha{sv})", &query, &handle, &arguments);
 
                if (fd_list)
                        fd = g_unix_fd_list_get (fd_list, handle, &error);
@@ -435,11 +493,31 @@ endpoint_dbus_iface_method_call (GDBusConnection       *connection,
                        QueryRequest *request;
 
                        request = query_request_new (endpoint_dbus, invocation, fd);
-                       tracker_sparql_connection_query_async (conn,
-                                                              query,
-                                                              endpoint_dbus->cancellable,
-                                                              query_cb,
-                                                              request);
+
+                       if (arguments) {
+                               TrackerSparqlStatement *stmt;
+
+                               stmt = create_statement (conn, query, arguments,
+                                                        endpoint_dbus->cancellable,
+                                                        &error);
+                               if (stmt) {
+                                       tracker_sparql_statement_execute_async (stmt,
+                                                                               endpoint_dbus->cancellable,
+                                                                               stmt_execute_cb,
+                                                                               request);
+                                       /* Statements are single use here... */
+                                       g_object_unref (stmt);
+                               } else {
+                                       g_dbus_method_invocation_return_gerror (invocation,
+                                                                               error);
+                               }
+                       } else {
+                               tracker_sparql_connection_query_async (conn,
+                                                                      query,
+                                                                      endpoint_dbus->cancellable,
+                                                                      query_cb,
+                                                                      request);
+                       }
                }
 
                g_free (query);


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