diff options
author | Sam Thursfield <sam@afuera.me.uk> | 2023-03-23 18:14:24 +0000 |
---|---|---|
committer | Sam Thursfield <sam@afuera.me.uk> | 2023-03-23 18:14:24 +0000 |
commit | ba6a9608f3b82d7708eae5b6477719668830e7e6 (patch) | |
tree | e90447c58310bfe6f6e135c4026e7f5c56503a7f /src/libtracker-sparql/core/tracker-db-interface-sqlite.c | |
parent | 6409812d31697ba430ebb843133304b46991d637 (diff) | |
parent | 827ba585eec44cf3710a82406783f47bcb64f9c3 (diff) | |
download | tracker-ba6a9608f3b82d7708eae5b6477719668830e7e6.tar.gz |
Merge branch 'wip/carlosg/orderless-fts-terms' into 'master'
core: handle FTS search terms individually
See merge request https://gitlab.gnome.org/GNOME/tracker/-/merge_requests/585
Diffstat (limited to 'src/libtracker-sparql/core/tracker-db-interface-sqlite.c')
-rw-r--r-- | src/libtracker-sparql/core/tracker-db-interface-sqlite.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/libtracker-sparql/core/tracker-db-interface-sqlite.c b/src/libtracker-sparql/core/tracker-db-interface-sqlite.c index 24c863616..2aa493ca9 100644 --- a/src/libtracker-sparql/core/tracker-db-interface-sqlite.c +++ b/src/libtracker-sparql/core/tracker-db-interface-sqlite.c @@ -1681,6 +1681,66 @@ function_sparql_print_value (sqlite3_context *context, } } +static void +function_sparql_fts_tokenize (sqlite3_context *context, + int argc, + sqlite3_value *argv[]) +{ + const gchar *fn = "SparqlFtsTokenizer helper"; + gchar *text; + const gchar *p; + gboolean in_quote = FALSE; + gboolean in_space = FALSE; + gboolean started = FALSE; + int n_output_quotes = 0; + gunichar ch; + GString *str; + int len; + gchar *result; + + if (argc > 1) { + result_context_function_error (context, fn, "Invalid argument count"); + return; + } + + text = g_strstrip (g_strdup (sqlite3_value_text (argv[0]))); + str = g_string_new (NULL); + p = text; + + while ((ch = g_utf8_get_char (p)) != 0) { + if (ch == '\"') { + n_output_quotes++; + in_quote = !in_quote; + } else if ((ch == ' ') != !!in_space) { + /* Ensure terms get independently quoted, unless + * they are within a explicitly quoted part of the text. + */ + if (!in_quote && started) { + g_string_append_c (str, '"'); + n_output_quotes++; + } + + in_space = ch == ' '; + } else if (!started) { + /* Not a quote, nor a space at the first char. Add the starting quote */ + g_string_append_c (str, '"'); + n_output_quotes++; + } + + g_string_append_unichar (str, ch); + started = TRUE; + p = g_utf8_next_char (p); + } + + if (n_output_quotes % 2 != 0) + g_string_append_c (str, '"'); + + len = str->len; + result = g_string_free (str, FALSE); + sqlite3_result_text (context, result, len, g_free); + g_free (text); +} + static int check_interrupt (void *user_data) { @@ -1757,6 +1817,8 @@ initialize_functions (TrackerDBInterface *db_interface) function_sparql_strlang }, { "SparqlPrintValue", 2, SQLITE_ANY | SQLITE_DETERMINISTIC, function_sparql_print_value }, + { "SparqlFtsTokenize", 1, SQLITE_ANY | SQLITE_DETERMINISTIC, + function_sparql_fts_tokenize }, /* Numbers */ { "SparqlCeil", 1, SQLITE_ANY | SQLITE_DETERMINISTIC, function_sparql_ceil }, |