[tracker/wip/carlosg/graphs-through-with: 6/15] libtracker-data: Iterate through graphs directly in tracker_triples vtab
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/graphs-through-with: 6/15] libtracker-data: Iterate through graphs directly in tracker_triples vtab
- Date: Tue, 10 Dec 2019 12:42:54 +0000 (UTC)
commit b34bc3ef675295392cb2ca9f0265a41f3c671c4d
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
Using the unionGraph views was merely convenient as it saved us from an
extra iteration level. As the unionGraph views will be dropped, just add
such extra level.
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]