[tracker/wip/carlosg/sparql1.1: 101/145] libtracker-data: Implement STRLANG and LANGMATCHES



commit d4157466fa7d1c24f2e9dbe823b735d6d020c7cd
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Jul 8 01:36:42 2019 +0200

    libtracker-data: Implement STRLANG and LANGMATCHES

 src/libtracker-data/tracker-db-interface-sqlite.c | 66 +++++++++++++++++++++++
 src/libtracker-data/tracker-sparql.c              | 20 ++++++-
 2 files changed, 84 insertions(+), 2 deletions(-)
---
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c 
b/src/libtracker-data/tracker-db-interface-sqlite.c
index a38c2f2c6..e395dca74 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -1588,6 +1588,68 @@ function_sparql_checksum (sqlite3_context *context,
        sqlite3_result_text (context, result, -1, g_free);
 }
 
+static void
+function_sparql_langmatches (sqlite3_context *context,
+                             int              argc,
+                             sqlite3_value   *argv[])
+{
+       const gchar *str, *langtag;
+       gint type;
+
+       if (argc != 2) {
+               sqlite3_result_error (context, "Invalid argument count", -1);
+               return;
+       }
+
+       type = sqlite3_value_type (argv[0]);
+
+       if (type == SQLITE_TEXT) {
+               /* text arguments don't contain any language information */
+               sqlite3_result_int (context, FALSE);
+       } else if (type == SQLITE_BLOB) {
+               gint str_len, len;
+
+               str = sqlite3_value_blob (argv[0]);
+               len = sqlite3_value_bytes (argv[0]);
+               langtag = sqlite3_value_text (argv[1]);
+               str_len = strlen (str) + 1;
+
+               if (str_len + strlen (langtag) != len ||
+                   g_strcmp0 (&str[str_len], langtag) != 0) {
+                       sqlite3_result_int (context, FALSE);
+               } else {
+                       sqlite3_result_int (context, TRUE);
+               }
+       } else {
+               sqlite3_result_null (context);
+       }
+}
+
+static void
+function_sparql_strlang (sqlite3_context *context,
+                         int              argc,
+                         sqlite3_value   *argv[])
+{
+       const gchar *str, *langtag;
+       GString *langstr;
+
+       if (argc != 2) {
+               sqlite3_result_error (context, "Invalid argument count", -1);
+               return;
+       }
+
+       str = sqlite3_value_text (argv[0]);
+       langtag = sqlite3_value_text (argv[1]);
+
+       langstr = g_string_new (str);
+       g_string_append_c (langstr, '\0');
+       g_string_append (langstr, langtag);
+
+       sqlite3_result_blob64 (context, langstr->str,
+                              langstr->len, g_free);
+       g_string_free (langstr, FALSE);
+}
+
 static inline int
 stmt_step (sqlite3_stmt *stmt)
 {
@@ -1728,6 +1790,10 @@ initialize_functions (TrackerDBInterface *db_interface)
                  function_sparql_replace },
                { "SparqlChecksum", 2, SQLITE_ANY | SQLITE_DETERMINISTIC,
                  function_sparql_checksum },
+               { "SparqlLangMatches", 2, SQLITE_ANY | SQLITE_DETERMINISTIC,
+                 function_sparql_langmatches },
+               { "SparqlStrLang", 2, SQLITE_ANY | SQLITE_DETERMINISTIC,
+                 function_sparql_strlang },
                /* 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 215374303..edbce4f44 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -6611,7 +6611,15 @@ translate_BuiltInCall (TrackerSparql  *sparql,
        } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_ISNUMERIC)) {
                _unimplemented ("ISNUMERIC");
        } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_LANGMATCHES)) {
-               _unimplemented ("LANGMATCHES");
+               _append_string (sparql, "SparqlLangMatches (");
+               _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
+               _call_rule (sparql, NAMED_RULE_Expression, error);
+               _expect (sparql, RULE_TYPE_LITERAL, LITERAL_COMMA);
+               _append_string (sparql, ", ");
+               _call_rule (sparql, NAMED_RULE_Expression, error);
+               _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
+               _append_string (sparql, ") ");
+               sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
        } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_CONTAINS)) {
                /* contains('A','B') => 'A' GLOB '*B*' */
                sparql->current_state.convert_to_string = TRUE;
@@ -6683,7 +6691,15 @@ translate_BuiltInCall (TrackerSparql  *sparql,
                _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
                _append_string (sparql, ") ");
        } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_STRLANG)) {
-               _unimplemented ("STRLANG");
+               _append_string (sparql, "SparqlStrLang (");
+               _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
+               _call_rule (sparql, NAMED_RULE_Expression, error);
+               _expect (sparql, RULE_TYPE_LITERAL, LITERAL_COMMA);
+               _append_string (sparql, ", ");
+               _call_rule (sparql, NAMED_RULE_Expression, error);
+               _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
+               _append_string (sparql, ") ");
+               sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_LANGSTRING;
        } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_STRDT)) {
                TrackerParserNode *expr, *node, *iri_node = NULL;
                TrackerPropertyType type;


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