diff options
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/libtracker-data/libtracker-data.vapi | 3 | ||||
-rw-r--r-- | src/libtracker-data/tracker-collation.c | 77 | ||||
-rw-r--r-- | src/libtracker-data/tracker-collation.h | 6 | ||||
-rw-r--r-- | src/libtracker-data/tracker-db-interface-sqlite.c | 10 | ||||
-rw-r--r-- | src/libtracker-data/tracker-db-interface-sqlite.h | 1 | ||||
-rw-r--r-- | src/libtracker-data/tracker-sparql-expression.vala | 4 |
7 files changed, 102 insertions, 0 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in index 886a09f01..47d9b3ee1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -6,6 +6,7 @@ src/libtracker-common/tracker-dbus.c src/libtracker-common/tracker-utils.c src/libtracker-fts/org.freedesktop.Tracker.FTS.gschema.xml.in src/libtracker-data/org.freedesktop.Tracker.DB.gschema.xml.in +src/libtracker-data/tracker-collation.c src/libtracker-data/tracker-data-backup.c src/libtracker-miner/tracker-data-provider.c src/libtracker-miner/tracker-miner-fs.c diff --git a/src/libtracker-data/libtracker-data.vapi b/src/libtracker-data/libtracker-data.vapi index b2582c810..ba0996832 100644 --- a/src/libtracker-data/libtracker-data.vapi +++ b/src/libtracker-data/libtracker-data.vapi @@ -247,6 +247,9 @@ namespace Tracker { [CCode (cheader_filename = "libtracker-data/tracker-db-interface-sqlite.h")] public const string COLLATION_NAME; + [CCode (cheader_filename = "libtracker-data/tracker-db-interface-sqlite.h")] + public const string TITLE_COLLATION_NAME; + [CCode (cheader_filename = "libtracker-data/tracker-collation.h")] public const unichar COLLATION_LAST_CHAR; } diff --git a/src/libtracker-data/tracker-collation.c b/src/libtracker-data/tracker-collation.c index b43ce9111..2e28a170e 100644 --- a/src/libtracker-data/tracker-collation.c +++ b/src/libtracker-data/tracker-collation.c @@ -19,6 +19,7 @@ #include "config.h" #include <glib.h> +#include <glib/gi18n.h> #include <string.h> #include <locale.h> @@ -239,3 +240,79 @@ tracker_collation_utf8 (gpointer collator, } #endif + +static gboolean +check_remove_prefix (const gchar *str, + gint len, + const gchar *prefix, + gint prefix_len, + const gchar **str_out, + gint *len_out) +{ + gboolean substituted = FALSE; + gchar *strstart; + + if (len <= prefix_len) + return FALSE; + + strstart = g_utf8_casefold (str, prefix_len); + if (strcmp (strstart, prefix) == 0) { + *str_out = str + prefix_len; + *len_out = len - prefix_len; + substituted = TRUE; + } + + g_free (strstart); + + return substituted; +} + +/* Helper function valid for all implementations */ +gint +tracker_collation_utf8_title (gpointer collator, + gint len1, + gconstpointer str1, + gint len2, + gconstpointer str2) +{ + const gchar *title_beginnings_str; + static gchar **title_beginnings = NULL; + const gchar *res1 = NULL, *res2 = NULL; + gint i; + + /* Translators: this is a space-separated list of common title + * beginnings. Meant to be skipped for sorting purposes, case + * doesn't matter. Given English media is quite common, it is + * advised to leave the untranslated articles in addition to + * the translated ones. + */ + title_beginnings_str = N_("the a an"); + + if (!title_beginnings) + title_beginnings = g_strsplit (_(title_beginnings_str), " ", -1); + + for (i = 0; title_beginnings[i]; i++) { + gchar *prefix, *str; + gint prefix_len; + + str = g_strdup_printf ("%s ", title_beginnings[i]); + prefix = g_utf8_casefold (str, -1); + prefix_len = strlen (prefix); + + if (!res1) + check_remove_prefix (str1, len1, prefix, prefix_len, + &res1, &len1); + if (!res2) + check_remove_prefix (str2, len2, prefix, prefix_len, + &res2, &len2); + g_free (prefix); + g_free (str); + } + + if (!res1) + res1 = str1; + if (!res2) + res2 = str2; + + return tracker_collation_utf8 (collator, len1, res1, len2, res2); +} diff --git a/src/libtracker-data/tracker-collation.h b/src/libtracker-data/tracker-collation.h index 93afae2ec..d3e5af18d 100644 --- a/src/libtracker-data/tracker-collation.h +++ b/src/libtracker-data/tracker-collation.h @@ -34,6 +34,12 @@ gint tracker_collation_utf8 (gpointer collator, gint len2, gconstpointer str2); +gint tracker_collation_utf8_title (gpointer collator, + gint len1, + gconstpointer str1, + gint len2, + gconstpointer str2); + #ifdef HAVE_LIBICU #define TRACKER_COLLATION_LAST_CHAR ((gunichar) 0x10fffd) #else diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c b/src/libtracker-data/tracker-db-interface-sqlite.c index 2b62d70c0..a001e2f82 100644 --- a/src/libtracker-data/tracker-db-interface-sqlite.c +++ b/src/libtracker-data/tracker-db-interface-sqlite.c @@ -1848,6 +1848,16 @@ tracker_db_interface_sqlite_reset_collator (TrackerDBInterface *db_interface) g_critical ("Couldn't set collation function: %s", sqlite3_errmsg (db_interface->db)); } + + if (sqlite3_create_collation_v2 (db_interface->db, + TRACKER_TITLE_COLLATION_NAME, + SQLITE_UTF8, + tracker_collation_init (), + tracker_collation_utf8_title, + tracker_collation_shutdown) != SQLITE_OK) { + g_critical ("Couldn't set title collation function: %s", + sqlite3_errmsg (db_interface->db)); + } } static gint diff --git a/src/libtracker-data/tracker-db-interface-sqlite.h b/src/libtracker-data/tracker-db-interface-sqlite.h index 5c81c66ae..49fab3c17 100644 --- a/src/libtracker-data/tracker-db-interface-sqlite.h +++ b/src/libtracker-data/tracker-db-interface-sqlite.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS #endif #define TRACKER_COLLATION_NAME "TRACKER" +#define TRACKER_TITLE_COLLATION_NAME "TRACKER_TITLE" typedef void (*TrackerDBWalCallback) (TrackerDBInterface *iface, gint n_pages); diff --git a/src/libtracker-data/tracker-sparql-expression.vala b/src/libtracker-data/tracker-sparql-expression.vala index 27b65a49e..338dc2035 100644 --- a/src/libtracker-data/tracker-sparql-expression.vala +++ b/src/libtracker-data/tracker-sparql-expression.vala @@ -522,6 +522,10 @@ class Tracker.Sparql.Expression : Object { translate_expression_as_string (sql); sql.append (")"); return PropertyType.STRING; + } else if (uri == TRACKER_NS + "title-order") { + translate_expression_as_string (sql); + sql.append_printf (" COLLATE %s", TITLE_COLLATION_NAME); + return PropertyType.STRING; } else if (uri == FN_NS + "lower-case") { // conversion to string sql.append ("SparqlLowerCase ("); |