[tracker/wip/carlosg/service-fixes: 1/8] libtracker-data: Use function to pretty print a IRI



commit 2f0fdccd964c927d8343eb22cef31722090ee993
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Jun 7 20:52:53 2020 +0200

    libtracker-data: Use function to pretty print a IRI
    
    IRIs are sometimes handled as ROWIDs and sometimes handled as strings
    (eg. from SERVICE clauses, or specified deeper in the query). Handle
    both types transparently in a function so both are handled correctly
    regardless at the time of printing the URNs face to the user.
    
    Fixes: https://gitlab.gnome.org/GNOME/tracker/-/issues/225

 src/libtracker-data/tracker-db-interface-sqlite.c | 53 +++++++++++++++++++++++
 src/libtracker-data/tracker-sparql.c              |  4 +-
 2 files changed, 55 insertions(+), 2 deletions(-)
---
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c 
b/src/libtracker-data/tracker-db-interface-sqlite.c
index d294a698a..ff3332367 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -1800,6 +1800,57 @@ function_sparql_bnode (sqlite3_context *context,
        generate_uuid (context, "urn:bnode");
 }
 
+static void
+function_sparql_print_iri (sqlite3_context *context,
+                           int              argc,
+                           sqlite3_value   *argv[])
+{
+       if (argc > 1) {
+               sqlite3_result_error (context, "Invalid argument count", -1);
+               return;
+       }
+
+       if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER) {
+               sqlite3_stmt *stmt;
+               gboolean store_auxdata = FALSE;
+               sqlite3 *db;
+               gint result;
+
+               stmt = sqlite3_get_auxdata (context, 1);
+
+               if (stmt == NULL) {
+                       store_auxdata = TRUE;
+                       db = sqlite3_context_db_handle (context);
+
+                       result = sqlite3_prepare_v2 (db, "SELECT Uri FROM Resource WHERE ID = ?",
+                                                    -1, &stmt, NULL);
+                       if (result != SQLITE_OK) {
+                               sqlite3_result_error (context, sqlite3_errstr (result), -1);
+                               return;
+                       }
+               }
+
+               sqlite3_reset (stmt);
+               sqlite3_bind_value (stmt, 1, argv[0]);
+               result = stmt_step (stmt);
+
+               if (result == SQLITE_DONE) {
+                       sqlite3_result_null (context);
+               } else if (result == SQLITE_ROW) {
+                       sqlite3_result_value (context, sqlite3_column_value (stmt, 0));
+               } else {
+                       sqlite3_result_error (context, sqlite3_errstr (result), -1);
+               }
+
+               if (store_auxdata) {
+                       sqlite3_set_auxdata (context, 1, stmt,
+                                            (void (*) (void*)) sqlite3_finalize);
+               }
+       } else {
+               sqlite3_result_value (context, argv[0]);
+       }
+}
+
 static int
 check_interrupt (void *user_data)
 {
@@ -1874,6 +1925,8 @@ initialize_functions (TrackerDBInterface *db_interface)
                  function_sparql_langmatches },
                { "SparqlStrLang", 2, SQLITE_ANY | SQLITE_DETERMINISTIC,
                  function_sparql_strlang },
+               { "SparqlPrintIRI", 1, SQLITE_ANY | SQLITE_DETERMINISTIC,
+                 function_sparql_print_iri },
                /* Numbers */
                { "SparqlCeil", 1, SQLITE_ANY | SQLITE_DETERMINISTIC,
                  function_sparql_ceil },
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 63abf8055..df9b0c62b 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -1982,8 +1982,8 @@ convert_expression_to_string (TrackerSparql       *sparql,
                 */
                break;
        case TRACKER_PROPERTY_TYPE_RESOURCE:
-               /* ID => Uri */
-               _prepend_string (sparql, "(SELECT Uri FROM Resource WHERE ID = ");
+               /* ID (or string) => Uri */
+               _prepend_string (sparql, "SparqlPrintIRI(");
                _append_string (sparql, ") ");
                break;
        case TRACKER_PROPERTY_TYPE_BOOLEAN:


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