[PATCH 11/14] tracker: make queries parsing fully asynchronous



From: Lionel Landwerlin <lionel g landwerlin linux intel com>

Signed-off-by: Lionel Landwerlin <lionel g landwerlin linux intel com>
---
 src/tracker/grl-tracker.c |  120 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 85 insertions(+), 35 deletions(-)

diff --git a/src/tracker/grl-tracker.c b/src/tracker/grl-tracker.c
index e6fbc38..140e476 100644
--- a/src/tracker/grl-tracker.c
+++ b/src/tracker/grl-tracker.c
@@ -162,8 +162,10 @@ struct OperationSpec {
   const GList            *keys;
   guint                   skip;
   guint                   count;
+  guint                   current;
   GrlMediaSourceResultCb  callback;
   gpointer                user_data;
+  TrackerSparqlCursor    *cursor;
 };
 
 struct _GrlTrackerSourcePriv {
@@ -704,20 +706,88 @@ fill_grilo_media_from_sparql (GrlMedia *media,
 }
 
 static void
-tracker_query_cb (GObject              *source_object,
-                  GAsyncResult         *result,
-                  struct OperationSpec *operation)
+tracker_query_result_cb (GObject              *source_object,
+                         GAsyncResult         *result,
+                         struct OperationSpec *operation)
 {
-  gint                 line, col;
+  gint                 col;
   const gchar         *sparql_type;
   GError              *tracker_error = NULL, *error = NULL;
-  TrackerSparqlCursor *cursor;
   GrlMedia            *media;
 
   GRL_DEBUG ("%s", __FUNCTION__);
 
-  cursor = tracker_sparql_connection_query_finish (operation->priv->tracker_connection,
-                                                   result, &tracker_error);
+  if (!tracker_sparql_cursor_next_finish (operation->cursor,
+                                          result,
+                                          &tracker_error)) {
+    if (tracker_error != NULL) {
+      error = g_error_new (GRL_CORE_ERROR,
+                           GRL_CORE_ERROR_BROWSE_FAILED,
+                           "Failed to start browse action : %s",
+                           tracker_error->message);
+
+      operation->callback (operation->source,
+                           operation->operation_id,
+                           NULL, 0,
+                           operation->user_data, error);
+
+      g_error_free (error);
+      g_error_free (tracker_error);
+    }
+    else {
+      GRL_DEBUG ("\tend of parsing :)");
+
+      /* Only emit this last one if more result than expected */
+      if (operation->count > 1)
+        operation->callback (operation->source,
+                             operation->operation_id,
+                             NULL, 0,
+                             operation->user_data, NULL);
+    }
+
+    g_object_unref (G_OBJECT (operation->cursor));
+    g_slice_free (struct OperationSpec, operation);
+    return;
+  }
+
+  sparql_type = tracker_sparql_cursor_get_string (operation->cursor, 0, NULL);
+
+  GRL_DEBUG ("Parsing line %i of type %s", operation->current, sparql_type);
+
+  media = build_grilo_media (sparql_type);
+
+  for (col = 1 ;
+       col < tracker_sparql_cursor_get_n_columns (operation->cursor) ;
+       col++) {
+    fill_grilo_media_from_sparql (media, operation->cursor, col);
+  }
+
+  operation->callback (operation->source,
+                       operation->operation_id,
+                       media,
+                       --operation->count,
+                       operation->user_data,
+                       NULL);
+
+  /* Schedule the next line to parse */
+  operation->current++;
+  tracker_sparql_cursor_next_async (operation->cursor, NULL,
+                                    (GAsyncReadyCallback) tracker_query_result_cb,
+                                    (gpointer) operation);
+}
+
+static void
+tracker_query_cb (GObject              *source_object,
+                  GAsyncResult         *result,
+                  struct OperationSpec *operation)
+{
+  GError *tracker_error = NULL, *error = NULL;
+
+  GRL_DEBUG ("%s", __FUNCTION__);
+
+  operation->cursor =
+    tracker_sparql_connection_query_finish (operation->priv->tracker_connection,
+                                            result, &tracker_error);
 
   if (tracker_error) {
     GRL_WARNING ("Could not execute sparql query: %s", tracker_error->message);
@@ -732,37 +802,16 @@ tracker_query_cb (GObject              *source_object,
 
     g_error_free (tracker_error);
     g_error_free (error);
+    g_slice_free (struct OperationSpec, operation);
 
-    goto end_operation;
-  }
-
-  /* Translate Sparql results into Grilo results */
-  line = 0;
-  while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
-    sparql_type = tracker_sparql_cursor_get_string (cursor, 0, NULL);
-
-    GRL_DEBUG ("Parsing line %i of type %s", line, sparql_type);
-
-    media = build_grilo_media (sparql_type);
-
-    for (col = 1 ; col < tracker_sparql_cursor_get_n_columns (cursor) ; col++) {
-      fill_grilo_media_from_sparql (media, cursor, col);
-    }
-
-    operation->callback (operation->source,
-                         operation->operation_id,
-                         media,
-                         --operation->count,
-                         operation->user_data,
-                         NULL);
-
-    line++;
+    return;
   }
 
- end_operation:
-  if (cursor)
-    g_object_unref (G_OBJECT (cursor));
-  g_slice_free (struct OperationSpec, operation);
+  /* Start parsing results */
+  operation->current = 0;
+  tracker_sparql_cursor_next_async (operation->cursor, NULL,
+                                    (GAsyncReadyCallback) tracker_query_result_cb,
+                                    (gpointer) operation);
 }
 
 static void
@@ -796,6 +845,7 @@ tracker_metadata_cb (GObject              *source_object,
     goto end_operation;
   }
 
+
   tracker_sparql_cursor_next (cursor, NULL, NULL);
 
   /* Translate Sparql result into Grilo result */
-- 
1.7.2.3



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