[tracker/collation: 6/9] libtracker-data: integrate collation function if envvar set



commit 28a16214ff728bc249bc35b790c1750259f3f5bd
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Mon Aug 16 16:34:34 2010 +0200

    libtracker-data: integrate collation function if envvar set

 src/libtracker-data/tracker-collation.c           |   89 +++++++++++++--------
 src/libtracker-data/tracker-collation.h           |   13 ++--
 src/libtracker-data/tracker-db-interface-sqlite.c |   34 +++++----
 src/libtracker-data/tracker-db-interface-sqlite.h |    9 +-
 src/libtracker-data/tracker-sparql-pattern.vala   |    2 +-
 5 files changed, 86 insertions(+), 61 deletions(-)
---
diff --git a/src/libtracker-data/tracker-collation.c b/src/libtracker-data/tracker-collation.c
index 441f22b..e12007e 100644
--- a/src/libtracker-data/tracker-collation.c
+++ b/src/libtracker-data/tracker-collation.c
@@ -22,6 +22,25 @@
 
 #include "tracker-collation.h"
 
+/* If defined, will dump some additional logs as prints,
+ *  instead of debugs*/
+#define G_INSTEADOF_LOG 1
+
+#ifdef G_INSTEADOF_LOG
+#undef g_debug
+#define g_debug(message, ...) \
+	g_print ("(debug) %s:%d: " message "\n", \
+	         __FILE__, __LINE__, ##__VA_ARGS__)
+#undef g_warning
+#define g_warning(message, ...) \
+	g_print ("(warning) %s:%d: " message "\n", \
+	         __FILE__, __LINE__, ##__VA_ARGS__)
+#undef g_critical
+#define g_critical(message, ...) \
+	g_print ("(critical) %s:%d: " message "\n", \
+	         __FILE__, __LINE__, ##__VA_ARGS__)
+#endif /* G_INSTEADOF_LOG */
+
 #ifdef HAVE_LIBUNISTRING
 /* libunistring versions prior to 9.1.2 need this hack */
 #define _UNUSED_PARAMETER_
@@ -33,70 +52,68 @@
 
 #ifdef HAVE_LIBUNISTRING /* ---- GNU libunistring based collation ---- */
 
-gboolean
+gpointer
 tracker_collation_init (void)
 {
+	g_debug ("[libunistring collation] Initializing collator");
 	/* Nothing to do */
-	return TRUE;
+	return NULL;
 }
 
 void
-tracker_collation_deinit (void)
+tracker_collation_deinit (gpointer collator)
 {
 	/* Nothing to do */
 }
 
 gint
-tracker_collation_utf8 (gchar *str1,
-                        gint   len1,
-                        gchar *str2,
-                        gint   len2)
+tracker_collation_utf8 (gpointer      collator,
+                        gint          len1,
+                        gconstpointer str1,
+                        gint          len2,
+                        gconstpointer str2)
 {
 	return u8_strcoll (str1, str2);
 }
 
 #elif HAVE_LIBICU /* ---- ICU based collation (UTF-16) ----*/
 
-/* Global collator to be re-used every time */
-UCollator *collator;
-
-gboolean
+gpointer
 tracker_collation_init (void)
 {
+	UCollator *collator = NULL;
 	UErrorCode status = U_ZERO_ERROR;
 	const gchar *locale = setlocale (LC_ALL, NULL);
 
-	g_debug ("Initializing collator for locale '%s'", locale);
+	g_debug ("[ICU collation] Initializing collator for locale '%s'", locale);
 	collator = ucol_open (locale, &status);
 	if (!collator) {
-		g_warning ("Collator for locale '%s' cannot be created: %s",
-		           locale, u_errorName (status));
+		g_warning ("[ICU collation] Collator for locale '%s' cannot be created: %s",
+		               locale, u_errorName (status));
 		/* Try to get UCA collator then... */
 		status = U_ZERO_ERROR;
 		collator = ucol_open ("root", &status);
 		if (!collator) {
-			g_critical ("UCA Collator cannot be created: %s",
-			            u_errorName (status));
-			return FALSE;
+			g_critical ("[ICU collation] UCA Collator cannot be created: %s",
+			                u_errorName (status));
 		}
 	}
-	return TRUE;
+	return collator;
 }
 
 void
-tracker_collation_deinit (void)
+tracker_collation_deinit (gpointer collator)
 {
-	if (collator) {
-		ucol_close (collator);
-		collator = NULL;
-	}
+	if (collator)
+		ucol_close ((UCollator *)collator);
 }
 
 gint
-tracker_collation_utf8 (gchar *str1,
-                        gint   len1,
-                        gchar *str2,
-                        gint   len2)
+tracker_collation_utf8 (gpointer      collator,
+                        gint          len1,
+                        gconstpointer str1,
+                        gint          len2,
+                        gconstpointer str2)
 {
 	UErrorCode status = U_ZERO_ERROR;
 	UCharIterator iter1;
@@ -110,7 +127,7 @@ tracker_collation_utf8 (gchar *str1,
 	uiter_setUTF8 (&iter1, str1, len1);
 	uiter_setUTF8 (&iter2, str2, len2);
 
-	result = ucol_strcollIter (collator,
+	result = ucol_strcollIter ((UCollator *)collator,
 	                           &iter1,
 	                           &iter2,
 	                           &status);
@@ -126,24 +143,26 @@ tracker_collation_utf8 (gchar *str1,
 
 #else /* ---- GLib based collation ---- */
 
-gboolean
+gpointer
 tracker_collation_init (void)
 {
+	g_debug ("[GLib collation] Initializing collator");
 	/* Nothing to do */
-	return TRUE;
+	return NULL;
 }
 
 void
-tracker_collation_deinit (void)
+tracker_collation_deinit (gpointer collator)
 {
 	/* Nothing to do */
 }
 
 gint
-tracker_collation_utf8 (gchar *str1,
-                        gint   len1,
-                        gchar *str2,
-                        gint   len2)
+tracker_collation_utf8 (gpointer      collator,
+                        gint          len1,
+                        gconstpointer str1,
+                        gint          len2,
+                        gconstpointer str2)
 {
 	return g_utf8_collate (str1, str2);
 }
diff --git a/src/libtracker-data/tracker-collation.h b/src/libtracker-data/tracker-collation.h
index 5e3472c..c32b293 100644
--- a/src/libtracker-data/tracker-collation.h
+++ b/src/libtracker-data/tracker-collation.h
@@ -26,12 +26,13 @@ G_BEGIN_DECLS
 #error "only <libtracker-common/tracker-common.h> must be included directly."
 #endif
 
-gboolean tracker_collation_init   (void);
-void     tracker_collation_deinit (void);
-gint     tracker_collation_utf8   (gchar *str1,
-                                   gint   len1,
-                                   gchar *str2,
-                                   gint   len2);
+gpointer tracker_collation_init   (void);
+void     tracker_collation_deinit (gpointer  collator);
+gint     tracker_collation_utf8   (gpointer      collator,
+                                   gint          len1,
+                                   gconstpointer str1,
+                                   gint          len2,
+                                   gconstpointer str2);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c b/src/libtracker-data/tracker-db-interface-sqlite.c
index 207fe73..24cacc1 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -34,8 +34,13 @@
 #include <libtracker-fts/tracker-fts.h>
 #endif
 
+#include "tracker-collation.h"
+
 #include "tracker-db-interface-sqlite.h"
 
+/* Envvar to enable collation in sqlite */
+#define TRACKER_COLLATION_ENABLED "TRACKER_COLLATION_ENABLED"
+
 struct TrackerDBInterface {
 	GObject parent_instance;
 
@@ -46,6 +51,8 @@ struct TrackerDBInterface {
 
 	GSList *function_data;
 
+	gpointer collator;
+
 	guint ro : 1;
 #if HAVE_TRACKER_FTS
 	guint fts_initialized : 1;
@@ -499,6 +506,15 @@ open_database (TrackerDBInterface *db_interface)
 		g_message ("Opened sqlite3 database:'%s'", db_interface->filename);
 	}
 
+	/* Set collation function if envvar set */
+	if (g_getenv (TRACKER_COLLATION_ENABLED) &&
+	    !db_interface->collator) {
+		db_interface->collator = tracker_collation_init ();
+		tracker_db_interface_sqlite_set_collation_function (db_interface,
+		                                                    "TRACKER",
+		                                                    tracker_collation_utf8);
+	}
+
 	sqlite3_progress_handler (db_interface->db, 100,
 	                          check_interrupt, db_interface);
 
@@ -643,6 +659,8 @@ tracker_db_interface_sqlite_finalize (GObject *object)
 
 	g_free (db_interface->filename);
 
+	tracker_collation_deinit (db_interface->collator);
+
 	G_OBJECT_CLASS (tracker_db_interface_parent_class)->finalize (object);
 }
 
@@ -974,20 +992,6 @@ tracker_db_interface_sqlite_new_ro (const gchar *filename)
 	                     NULL);
 }
 
-static gint
-collation_function (gpointer      data,
-                    int           len1,
-                    gconstpointer str1,
-                    int           len2,
-                    gconstpointer str2)
-{
-	TrackerDBCollationFunc func;
-
-	func = (TrackerDBCollationFunc) data;
-
-	return (func) ((gchar *) str1, len1, (gchar *) str2, len2);
-}
-
 gboolean
 tracker_db_interface_sqlite_set_collation_function (TrackerDBInterface       *interface,
                                                     const gchar              *name,
@@ -997,7 +1001,7 @@ tracker_db_interface_sqlite_set_collation_function (TrackerDBInterface       *in
 
 	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (interface), FALSE);
 
-	result = sqlite3_create_collation (interface->db, name, SQLITE_UTF8, func, &collation_function);
+	result = sqlite3_create_collation (interface->db, name, SQLITE_UTF8, interface->collator, func);
 
 	return (result == SQLITE_OK);
 }
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.h b/src/libtracker-data/tracker-db-interface-sqlite.h
index 52a45d2..680397a 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.h
+++ b/src/libtracker-data/tracker-db-interface-sqlite.h
@@ -28,10 +28,11 @@ G_BEGIN_DECLS
 #error "only <libtracker-data/tracker-data.h> must be included directly."
 #endif
 
-typedef gint (* TrackerDBCollationFunc) (gchar *str1,
-                                         gint   len1,
-                                         gchar *str2,
-                                         gint   len2);
+typedef gint (* TrackerDBCollationFunc) (gpointer      collator,
+                                         gint          len1,
+                                         gconstpointer str1,
+                                         gint          len2,
+                                         gconstpointer str2);
 
 TrackerDBInterface *tracker_db_interface_sqlite_new                    (const gchar              *filename);
 TrackerDBInterface *tracker_db_interface_sqlite_new_ro                 (const gchar              *filename);
diff --git a/src/libtracker-data/tracker-sparql-pattern.vala b/src/libtracker-data/tracker-sparql-pattern.vala
index bbc5aeb..e030fa3 100644
--- a/src/libtracker-data/tracker-sparql-pattern.vala
+++ b/src/libtracker-data/tracker-sparql-pattern.vala
@@ -358,7 +358,7 @@ class Tracker.Sparql.Pattern : Object {
 				if (first_order) {
 					first_order = false;
 				} else {
-					sql.append (", ");
+					sql.append (" COLLATE TRACKER, ");
 				}
 				expression.translate_order_condition (sql);
 			} while (current () != SparqlTokenType.LIMIT && current () != SparqlTokenType.OFFSET && current () != SparqlTokenType.CLOSE_BRACE && current () != SparqlTokenType.CLOSE_PARENS && current () != SparqlTokenType.EOF);



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