[tracker/wip/carlosg/test: 6/10] libtracker-data: Iterate through graphs directly in tracker_triples vtab



commit d4f56b031b961f3846c45f5105b19b3c81b3c73e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Oct 27 21:51:06 2019 +0100

    libtracker-data: Iterate through graphs directly in tracker_triples vtab
    
    Instead of resorting to the unionGraph* views underneath. This will allow
    us moving from views entirely.

 src/libtracker-data/tracker-vtab-triples.c | 100 +++++++++++++++++++++++++----
 1 file changed, 86 insertions(+), 14 deletions(-)
---
diff --git a/src/libtracker-data/tracker-vtab-triples.c b/src/libtracker-data/tracker-vtab-triples.c
index c1f7227f3..a9e868b1d 100644
--- a/src/libtracker-data/tracker-vtab-triples.c
+++ b/src/libtracker-data/tracker-vtab-triples.c
@@ -74,7 +74,9 @@ typedef struct {
                guint idxFlags;
        } match;
 
+       GHashTable *query_graphs;
        GList *properties;
+       GList *graphs;
 
        guint64 rowid;
        guint finished : 1;
@@ -106,6 +108,8 @@ tracker_triples_cursor_reset (TrackerTriplesCursor *cursor)
        g_clear_pointer (&cursor->match.subject, sqlite3_value_free);
        g_clear_pointer (&cursor->match.predicate, sqlite3_value_free);
        g_clear_pointer (&cursor->properties, g_list_free);
+       g_clear_pointer (&cursor->graphs, g_list_free);
+       g_clear_pointer (&cursor->query_graphs, g_hash_table_unref);
        cursor->match.idxFlags = 0;
        cursor->rowid = 0;
        cursor->finished = FALSE;
@@ -281,6 +285,52 @@ collect_properties (TrackerTriplesCursor *cursor)
        }
 }
 
+static int
+collect_graphs (TrackerTriplesCursor *cursor)
+{
+       sqlite3_stmt *stmt;
+       int rc;
+
+       rc = sqlite3_prepare_v2 (cursor->vtab->module->db,
+                                "SELECT 0, \"main\" "
+                                "UNION ALL "
+                                "SELECT ID, "
+                                "       (SELECT Uri from Resource where Resource.ID = Graph.ID) "
+                                "FROM Graph",
+                                -1, &stmt, 0);
+       if (rc != SQLITE_OK)
+               return rc;
+
+       cursor->query_graphs = g_hash_table_new_full (NULL, NULL, NULL, g_free);
+
+       while ((rc = sqlite3_step (stmt)) == SQLITE_ROW) {
+               const gchar *uri;
+               gint id;
+
+               id = sqlite3_column_int (stmt, 0);
+               uri = sqlite3_column_text (stmt, 1);
+
+               if (cursor->match.graph) {
+                       gboolean negated = !!(cursor->match.idxFlags & IDX_MATCH_GRAPH_NEG);
+                       gboolean equals = (sqlite3_value_int64 (cursor->match.graph) == id);
+
+                       if (equals == negated)
+                               continue;
+               }
+
+               g_hash_table_insert (cursor->query_graphs,
+                                    GINT_TO_POINTER (id),
+                                    g_strdup (uri));
+       }
+
+       if (rc == SQLITE_DONE)
+               cursor->graphs = g_hash_table_get_keys (cursor->query_graphs);
+
+       sqlite3_finalize (stmt);
+
+       return rc;
+}
+
 static gchar *
 convert_to_string (const gchar         *table_name,
                   TrackerPropertyType  type)
@@ -348,42 +398,62 @@ bind_arg (sqlite3_stmt  *stmt,
        sqlite3_bind_value (stmt, idx, value);
 }
 
+static gboolean
+iterate_next_stmt (TrackerTriplesCursor  *cursor,
+                   const gchar          **graph,
+                   gint                  *graph_id,
+                   TrackerProperty      **property)
+{
+       while (cursor->properties && !cursor->graphs) {
+               /* Iterate to next property, and redo graph list */
+               cursor->properties = g_list_remove (cursor->properties,
+                                                   cursor->properties->data);
+               cursor->graphs = g_hash_table_get_keys (cursor->query_graphs);
+       }
+
+       if (!cursor->properties)
+               return FALSE;
+
+       *property = cursor->properties->data;
+       *graph_id = GPOINTER_TO_INT (cursor->graphs->data);
+       *graph = g_hash_table_lookup (cursor->query_graphs,
+                                     cursor->graphs->data);
+
+       cursor->graphs = g_list_remove (cursor->graphs, cursor->graphs->data);
+
+       return TRUE;
+}
+
 static int
 init_stmt (TrackerTriplesCursor *cursor)
 {
        TrackerProperty *property;
+       const gchar *graph;
+       gint graph_id;
        GString *sql;
        int rc;
 
-       while (cursor->properties) {
+       while (iterate_next_stmt (cursor, &graph, &graph_id, &property)) {
                gchar *string_expr;
 
-               property = cursor->properties->data;
-               cursor->properties = g_list_remove (cursor->properties, property);
-
                string_expr = convert_to_string (tracker_property_get_name (property),
                                                 tracker_property_get_data_type (property));
 
                sql = g_string_new (NULL);
                g_string_append_printf (sql,
-                                       "SELECT t.graph, t.ID, "
+                                       "SELECT %d, t.ID, "
                                        "       (SELECT ID From Resource WHERE Uri = \"%s\"), "
                                        "       %s, "
                                        "       %d "
-                                       "FROM \"unionGraph_%s\" AS t "
+                                       "FROM \"%s\".\"%s\" AS t "
                                        "WHERE 1 ",
+                                       graph_id,
                                        tracker_property_get_uri (property),
                                        string_expr,
                                        tracker_property_get_data_type (property),
+                                       graph,
                                        tracker_property_get_table_name (property));
 
-               if (cursor->match.graph) {
-                       g_string_append (sql, "AND t.graph ");
-                       add_arg_check (sql, cursor->match.graph,
-                                      !!(cursor->match.idxFlags & IDX_MATCH_GRAPH_NEG),
-                                      "@g");
-               }
-
                if (cursor->match.subject) {
                        g_string_append (sql, "AND t.ID ");
                        add_arg_check (sql, cursor->match.subject,
@@ -443,8 +513,10 @@ triples_filter (sqlite3_vtab_cursor  *vtab_cursor,
 
        cursor->match.idxFlags = idx;
 
-       collect_properties (cursor);
+       if ((rc = collect_graphs (cursor)) != SQLITE_DONE)
+               return rc;
 
+       collect_properties (cursor);
        rc = init_stmt (cursor);
 
        if (rc == SQLITE_DONE)


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