[tracker/functions] libtracker-db: Removed the boxing from the custom SQLite functions



commit d3d6b676b2e1db9e23565d1b8d5b1b3570dda3db
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Mar 25 11:15:44 2010 +0100

    libtracker-db: Removed the boxing from the custom SQLite functions

 src/libtracker-db/tracker-db-interface-sqlite.c |  319 ++++++++++++++++-------
 src/libtracker-db/tracker-db-interface-sqlite.h |    4 -
 src/libtracker-db/tracker-db-manager.c          |  252 +------------------
 3 files changed, 234 insertions(+), 341 deletions(-)
---
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index 6c6f176..62f8f52 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -23,6 +23,7 @@
 
 #include <sqlite3.h>
 #include <stdlib.h>
+#include <math.h>
 
 #include <libtracker-common/tracker-common.h>
 #include <libtracker-fts/tracker-fts.h>
@@ -148,6 +149,215 @@ tracker_db_interface_sqlite_enable_shared_cache (void)
 }
 
 static void
+function_sparql_string_join (sqlite3_context *context,
+                             int              argc,
+                             sqlite3_value   *argv[])
+{
+	GString *str = NULL;
+	const gchar *separator;
+	gint i;
+
+	/* fn:string-join (str1, str2, ..., separator) */
+
+	if (sqlite3_value_type (argv[argc-1]) != SQLITE_TEXT) {
+		/* Fail */
+		sqlite3_result_null (context);
+		return;
+	}
+
+	separator = sqlite3_value_text (argv[argc-1]);
+
+	for (i = 0;i < argc-1; i++) {
+		if (sqlite3_value_type (argv[argc-1]) == SQLITE_TEXT) {
+			const gchar *text = sqlite3_value_text (argv[i]);
+			
+			if (text != NULL) {
+				if (!str) {
+					str = g_string_new (text);
+				} else {
+					g_string_append_printf (str, "%s%s", separator, text);
+				}
+			}
+		}
+	}
+
+	if (str) {
+		sqlite3_result_text (context, str->str, str->len, g_free);
+		g_string_free (str, FALSE);
+	} else {
+		sqlite3_result_null (context);
+	}
+
+	return;
+}
+
+/* Create a title-type string from the filename for replacing missing ones */
+static void
+function_sparql_string_from_filename (sqlite3_context *context,
+                                      int              argc,
+                                      sqlite3_value   *argv[])
+{
+	gchar  *name = NULL;
+	gchar  *suffix = NULL;
+
+	if (argc != 1) {
+		g_critical ("Invalid argument count");
+		sqlite3_result_null (context);
+		return;
+	}
+
+	/* "/home/user/path/title_of_the_movie.movie" -> "title of the movie"
+	 * Only for local files currently, do we need to change? */
+
+	name = g_filename_display_basename (sqlite3_value_text (argv[0]));
+
+	if (!name) {
+		sqlite3_result_null (context);
+		return;
+	}
+
+	suffix = g_strrstr (name, ".");
+
+	if (suffix) {
+		*suffix = '\0';
+	}
+
+	g_strdelimit (name, "._", ' ');
+
+	sqlite3_result_text (context, name, -1, g_free);
+
+	return;
+}
+
+static void
+function_sparql_cartesian_distance (sqlite3_context *context,
+                                    int              argc,
+                                    sqlite3_value   *argv[])
+{
+	gdouble lat1;
+	gdouble lat2;
+	gdouble lon1;
+	gdouble lon2;
+
+	gdouble R;
+	gdouble a;
+	gdouble b;
+	gdouble c;
+	gdouble d;
+
+	if (argc != 4) {
+		g_critical ("Invalid argument count");
+		sqlite3_result_null (context);
+		return;
+	}
+
+	lat1 = sqlite3_value_double (argv[0])*M_PI/180;
+	lat2 = sqlite3_value_double (argv[1])*M_PI/180;
+	lon1 = sqlite3_value_double (argv[2])*M_PI/180;
+	lon2 = sqlite3_value_double (argv[3])*M_PI/180;
+
+	R = 6371000;
+	a = M_PI/2 - lat1;
+	b = M_PI/2 - lat2;
+	c = sqrt(a*a + b*b - 2*a*b*cos(lon2 - lon1));
+	d = R*c;
+
+	sqlite3_result_double (context, d);
+
+	return;
+}
+
+static void
+function_sparql_haversine_distance (sqlite3_context *context,
+                                    int              argc,
+                                    sqlite3_value   *argv[])
+{
+	gdouble lat1;
+	gdouble lat2;
+	gdouble lon1;
+	gdouble lon2;
+
+	gdouble R;
+	gdouble dLat;
+	gdouble dLon;
+	gdouble a;
+	gdouble c;
+	gdouble d;
+
+	if (argc != 4) {
+		g_critical ("Invalid argument count");
+		sqlite3_result_null (context);
+		return;
+	}
+
+	lat1 = sqlite3_value_double (argv[0])*M_PI/180;
+	lat2 = sqlite3_value_double (argv[1])*M_PI/180;
+	lon1 = sqlite3_value_double (argv[2])*M_PI/180;
+	lon2 = sqlite3_value_double (argv[3])*M_PI/180;
+
+	R = 6371000;
+	dLat = (lat2-lat1);
+	dLon = (lon2-lon1);
+	a = sin(dLat/2) * sin(dLat/2) + cos(lat1) * cos(lat2) *  sin(dLon/2) * sin(dLon/2);
+	c = 2 * atan2(sqrt(a), sqrt(1-a));
+	d = R * c;
+
+	sqlite3_result_double (context, d);
+
+	return;
+}
+
+static void
+function_sparql_regex (sqlite3_context *context,
+                       int              argc,
+                       sqlite3_value   *argv[])
+{
+	gboolean ret;
+	const gchar *text, *pattern, *flags;
+	GRegexCompileFlags regex_flags;
+
+	if (argc != 3) {
+		g_critical ("Invalid argument count");
+		sqlite3_result_null (context);
+		return;
+	}
+
+	text = sqlite3_value_text (argv[0]);
+	pattern = sqlite3_value_text (argv[1]);
+	flags = sqlite3_value_text (argv[2]);
+
+	regex_flags = 0;
+	while (*flags) {
+		switch (*flags) {
+		case 's':
+			regex_flags |= G_REGEX_DOTALL;
+			break;
+		case 'm':
+			regex_flags |= G_REGEX_MULTILINE;
+			break;
+		case 'i':
+			regex_flags |= G_REGEX_CASELESS;
+			break;
+		case 'x':
+			regex_flags |= G_REGEX_EXTENDED;
+			break;
+		default:
+			g_critical ("Invalid SPARQL regex flag '%c'", *flags);
+			sqlite3_result_null (context);
+			return;
+		}
+		flags++;
+	}
+
+	ret = g_regex_match_simple (pattern, text, regex_flags, 0);
+
+	sqlite3_result_int (context, ret);
+
+	return;
+}
+
+
+static void
 open_database (TrackerDBInterfaceSqlitePrivate *priv)
 {
 	g_assert (priv->filename != NULL);
@@ -166,6 +376,26 @@ open_database (TrackerDBInterfaceSqlitePrivate *priv)
 		}
 	}
 
+	sqlite3_create_function (priv->db, "SparqlRegex", 3, SQLITE_ANY,
+	                         priv, &function_sparql_regex, 
+	                         NULL, NULL);
+
+	sqlite3_create_function (priv->db, "SparqlHaversineDistance", 4, SQLITE_ANY,
+	                         priv, &function_sparql_haversine_distance,
+	                         NULL, NULL);
+
+	sqlite3_create_function (priv->db, "SparqlCartesianDistance", 4, SQLITE_ANY,
+	                         priv, &function_sparql_cartesian_distance,
+	                         NULL, NULL);
+
+	sqlite3_create_function (priv->db, "SparqlStringFromFilename", 1, SQLITE_ANY,
+	                         priv, &function_sparql_string_from_filename,
+	                         NULL, NULL);
+
+	sqlite3_create_function (priv->db, "SparqlStringJoin", -1, SQLITE_ANY,
+	                         priv, &function_sparql_string_join,
+	                         NULL, NULL);
+
 	sqlite3_extended_result_codes (priv->db, 0);
 	sqlite3_busy_timeout (priv->db, 100000);
 }
@@ -380,75 +610,6 @@ add_row (TrackerDBResultSet *result_set,
 	}
 }
 
-static void
-internal_sqlite3_function (sqlite3_context *context,
-                           int              argc,
-                           sqlite3_value   *argv[])
-{
-	SqliteFunctionData *data;
-	GValue *values, result;
-	gint i;
-
-	data = (SqliteFunctionData *) sqlite3_user_data (context);
-	values = g_new0 (GValue, argc);
-
-	/* Transform the arguments */
-	for (i = 0; i < argc; i++) {
-		switch (sqlite3_value_type (argv[i])) {
-		case SQLITE_TEXT:
-			g_value_init (&values[i], G_TYPE_STRING);
-			g_value_set_string (&values[i], (gchar *) sqlite3_value_text (argv[i]));
-			break;
-		case SQLITE_INTEGER:
-			g_value_init (&values[i], G_TYPE_INT);
-			g_value_set_int (&values[i], sqlite3_value_int (argv[i]));
-			break;
-		case SQLITE_FLOAT:
-			g_value_init (&values[i], G_TYPE_DOUBLE);
-			g_value_set_double (&values[i], sqlite3_value_double (argv[i]));
-			break;
-		case SQLITE_NULL:
-			/* Unset GValues as NULLs */
-			break;
-		default:
-			g_critical ("Unknown sqlite3 database value type:%d",
-			            sqlite3_value_type (argv[i]));
-		}
-	}
-
-	/* Call the function */
-	result = data->func (data->interface, argc, values);
-
-	/* And return something appropriate to the context */
-	if (G_VALUE_HOLDS_INT (&result)) {
-		sqlite3_result_int (context, g_value_get_int (&result));
-	} else if (G_VALUE_HOLDS_DOUBLE (&result)) {
-		sqlite3_result_double (context, g_value_get_double (&result));
-	} else if (G_VALUE_HOLDS_STRING (&result)) {
-		sqlite3_result_text (context,
-		                     g_value_dup_string (&result),
-		                     -1, g_free);
-	} else if (G_VALUE_HOLDS (&result, G_TYPE_INVALID)) {
-		sqlite3_result_null (context);
-	} else {
-		g_critical ("Sqlite3 returned type not managed:'%s'",
-		            G_VALUE_TYPE_NAME (&result));
-		sqlite3_result_null (context);
-	}
-
-	/* Now free all this mess */
-	for (i = 0; i < argc; i++) {
-		if (G_IS_VALUE (&values[i])) {
-			g_value_unset (&values[i]);
-		}
-	}
-
-	if (! G_VALUE_HOLDS (&result, G_TYPE_INVALID)) {
-		g_value_unset (&result);
-	}
-
-	g_free (values);
-}
 
 static TrackerDBStatement *
 tracker_db_interface_sqlite_create_statement (TrackerDBInterface *db_interface,
@@ -644,26 +805,6 @@ collation_function (gpointer      data,
 	return (func) ((gchar *) str1, len1, (gchar *) str2, len2);
 }
 
-void
-tracker_db_interface_sqlite_create_function (TrackerDBInterface *interface,
-                                             const gchar        *name,
-                                             TrackerDBFunc       func,
-                                             gint                n_args)
-{
-	SqliteFunctionData *data;
-	TrackerDBInterfaceSqlitePrivate *priv;
-
-	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (interface);
-
-	data = g_new0 (SqliteFunctionData, 1);
-	data->interface = interface;
-	data->func = func;
-
-	priv->function_data = g_slist_prepend (priv->function_data, data);
-
-	sqlite3_create_function (priv->db, name, n_args, SQLITE_ANY, data, &internal_sqlite3_function, NULL, NULL);
-}
-
 gboolean
 tracker_db_interface_sqlite_set_collation_function (TrackerDBInterfaceSqlite *interface,
                                                     const gchar                      *name,
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.h b/src/libtracker-db/tracker-db-interface-sqlite.h
index f3d3bc4..c104b35 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.h
+++ b/src/libtracker-db/tracker-db-interface-sqlite.h
@@ -58,10 +58,6 @@ GType               tracker_db_interface_sqlite_get_type               (void);
 
 TrackerDBInterface *tracker_db_interface_sqlite_new                    (const gchar              *filename);
 TrackerDBInterface *tracker_db_interface_sqlite_new_ro                 (const gchar              *filename);
-void                tracker_db_interface_sqlite_create_function        (TrackerDBInterface       *interface,
-                                                                        const gchar              *name,
-                                                                        TrackerDBFunc             func,
-                                                                        gint                      n_args);
 gboolean            tracker_db_interface_sqlite_set_collation_function (TrackerDBInterfaceSqlite *interface,
                                                                         const gchar              *name,
                                                                         TrackerDBCollationFunc    func);
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 5af00e2..0fb46a3 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -29,7 +29,6 @@
 #include <sys/types.h>
 #include <stdio.h>
 #include <fcntl.h>
-#include <math.h>
 
 #include <glib/gstdio.h>
 
@@ -88,7 +87,6 @@ typedef struct {
 	gchar              *abs_filename;
 	gint                cache_size;
 	gint                page_size;
-	gboolean            add_functions;
 	gboolean            attached;
 	gboolean            is_index;
 	guint64             mtime;
@@ -105,7 +103,6 @@ static TrackerDBDefinition dbs[] = {
 	  TRACKER_DB_PAGE_SIZE_DONT_SET,
 	  FALSE,
 	  FALSE,
-	  FALSE,
 	  0 },
 	{ TRACKER_DB_METADATA,
 	  TRACKER_DB_LOCATION_DATA_DIR,
@@ -115,7 +112,6 @@ static TrackerDBDefinition dbs[] = {
 	  NULL,
 	  2000,
 	  TRACKER_DB_PAGE_SIZE_DONT_SET,
-	  TRUE,
 	  FALSE,
 	  FALSE,
 	  0 },
@@ -129,7 +125,6 @@ static TrackerDBDefinition dbs[] = {
 	  TRACKER_DB_PAGE_SIZE_DONT_SET,
 	  FALSE,
 	  FALSE,
-	  FALSE,
 	  0 },
 	{ TRACKER_DB_FULLTEXT,
 	  TRACKER_DB_LOCATION_DATA_DIR,
@@ -139,7 +134,6 @@ static TrackerDBDefinition dbs[] = {
 	  NULL,
 	  512,
 	  TRACKER_DB_PAGE_SIZE_DONT_SET,
-	  TRUE,
 	  FALSE,
 	  TRUE,
 	  0 },
@@ -254,220 +248,10 @@ tracker_db_manager_get_flags (void)
 	return old_flags;
 }
 
-static GValue
-function_sparql_string_join (TrackerDBInterface *interface,
-			     gint                argc,
-			     GValue              values[])
-{
-	GValue result = { 0, };
-	GString *str = NULL;
-	const gchar *separator;
-	gint i;
-
-	/* fn:string-join (str1, str2, ..., separator) */
-
-	if (!G_VALUE_HOLDS_STRING (&values[argc-1])) {
-		/* Fail */
-		return result;
-	}
-
-	separator = g_value_get_string (&values[argc-1]);
-
-	for (i = 0;i < argc-1; i++) {
-		if (G_VALUE_HOLDS_STRING (&values[i])) {
-			if (!str) {
-				str = g_string_new (g_value_get_string (&values[i]));
-			} else {
-				g_string_append_printf (str, "%s%s",
-							separator,
-							g_value_get_string (&values[i]));
-			}
-		}
-	}
-
-	if (str) {
-		g_value_init (&result, G_TYPE_STRING);
-		g_value_set_string (&result, str->str);
-
-		g_string_free (str, TRUE);
-	}
-
-	return result;
-}
-
-/* Create a title-type string from the filename for replacing missing ones */
-static GValue
-function_sparql_string_from_filename (TrackerDBInterface *interface,
-				      gint                argc,
-				      GValue              values[])
-{
-	GValue  result = { 0, };
-	gchar  *name = NULL;
-	gchar  *suffix = NULL;
-
-	if (argc != 1) {
-		g_critical ("Invalid argument count");
-		return result;
-	}
-
-	/* "/home/user/path/title_of_the_movie.movie" -> "title of the movie"
-	   Only for local files currently, do we need to change? */
-
-	name = g_filename_display_basename (g_value_get_string (&values[0]));
-	if (!name) {
-		return result;
-	}
-
-	suffix = g_strrstr (name, ".");
-
-	if (suffix) {
-		*suffix = '\0';
-	}
-
-	g_strdelimit (name, "._", ' ');
-
-	g_value_init (&result, G_TYPE_STRING);
-	g_value_set_string (&result, name);
-
-	g_free (name);
-
-	return result;
-}
-
-static GValue
-function_sparql_cartesian_distance (TrackerDBInterface *interface,
-				    gint                argc,
-				    GValue              values[])
-{
-	GValue result = { 0, };
-	gdouble lat1;
-	gdouble lat2;
-	gdouble lon1;
-	gdouble lon2;
-
-	gdouble R;
-	gdouble a;
-	gdouble b;
-	gdouble c;
-	gdouble d;
-
-	if (argc != 4) {
-		g_critical ("Invalid argument count");
-		return result;
-	}
-
-	lat1 = g_value_get_double (&values[0])*M_PI/180;
-	lat2 = g_value_get_double (&values[1])*M_PI/180;
-	lon1 = g_value_get_double (&values[2])*M_PI/180;
-	lon2 = g_value_get_double (&values[3])*M_PI/180;
-
-	R = 6371000;
-	a = M_PI/2 - lat1;
-	b = M_PI/2 - lat2;
-	c = sqrt(a*a + b*b - 2*a*b*cos(lon2 - lon1));
-	d = R*c;
-
-	g_value_init (&result, G_TYPE_DOUBLE);
-	g_value_set_double (&result, d);
-
-	return result;
-}
-
-static GValue
-function_sparql_haversine_distance (TrackerDBInterface *interface,
-				    gint                argc,
-				    GValue              values[])
-{
-	GValue result = { 0, };
-	gdouble lat1;
-	gdouble lat2;
-	gdouble lon1;
-	gdouble lon2;
-
-	gdouble R;
-	gdouble dLat;
-	gdouble dLon;
-	gdouble a;
-	gdouble c;
-	gdouble d;
-
-	if (argc != 4) {
-		g_critical ("Invalid argument count");
-		return result;
-	}
-
-	lat1 = g_value_get_double (&values[0])*M_PI/180;
-	lat2 = g_value_get_double (&values[1])*M_PI/180;
-	lon1 = g_value_get_double (&values[2])*M_PI/180;
-	lon2 = g_value_get_double (&values[3])*M_PI/180;
-
-	R = 6371000;
-	dLat = (lat2-lat1);
-	dLon = (lon2-lon1);
-	a = sin(dLat/2) * sin(dLat/2) + cos(lat1) * cos(lat2) *  sin(dLon/2) * sin(dLon/2);
-	c = 2 * atan2(sqrt(a), sqrt(1-a));
-	d = R * c;
-
-	g_value_init (&result, G_TYPE_DOUBLE);
-	g_value_set_double (&result, d);
-
-	return result;
-}
-
-static GValue
-function_sparql_regex (TrackerDBInterface *interface,
-                       gint                  argc,
-                       GValue                values[])
-{
-	GValue  result = { 0, };
-	gboolean        ret;
-	const gchar *text, *pattern, *flags;
-	GRegexCompileFlags regex_flags;
-
-	if (argc != 3) {
-		g_critical ("Invalid argument count");
-		return result;
-	}
-
-	text = g_value_get_string (&values[0]);
-	pattern = g_value_get_string (&values[1]);
-	flags = g_value_get_string (&values[2]);
-
-	regex_flags = 0;
-	while (*flags) {
-		switch (*flags) {
-		case 's':
-			regex_flags |= G_REGEX_DOTALL;
-			break;
-		case 'm':
-			regex_flags |= G_REGEX_MULTILINE;
-			break;
-		case 'i':
-			regex_flags |= G_REGEX_CASELESS;
-			break;
-		case 'x':
-			regex_flags |= G_REGEX_EXTENDED;
-			break;
-		default:
-			g_critical ("Invalid SPARQL regex flag '%c'", *flags);
-			return result;
-		}
-		flags++;
-	}
-
-	ret = g_regex_match_simple (pattern, text, regex_flags, 0);
-
-	g_value_init (&result, G_TYPE_INT);
-	g_value_set_int (&result, ret);
-
-	return result;
-}
-
 static void
 db_set_params (TrackerDBInterface *iface,
                gint                cache_size,
-               gint                page_size,
-               gboolean                    add_functions)
+               gint                page_size)
 {
 	tracker_db_interface_execute_query (iface, NULL, "PRAGMA synchronous = OFF;");
 	tracker_db_interface_execute_query (iface, NULL, "PRAGMA count_changes = 0;");
@@ -483,31 +267,6 @@ db_set_params (TrackerDBInterface *iface,
 	tracker_db_interface_execute_query (iface, NULL, "PRAGMA cache_size = %d", cache_size);
 	g_message ("  Setting cache size to %d", cache_size);
 
-	if (add_functions) {
-		g_message ("  Adding functions");
-
-		/* Create user defined functions that can be used in sql */
-		tracker_db_interface_sqlite_create_function (iface,
-		                                             "SparqlRegex",
-		                                             function_sparql_regex,
-		                                             3);
-		tracker_db_interface_sqlite_create_function (iface,
-		                                             "SparqlStringJoin",
-		                                             function_sparql_string_join,
-		                                             -1);
-		tracker_db_interface_sqlite_create_function (iface,
-		                                             "SparqlStringFromFilename",
-		                                             function_sparql_string_from_filename,
-		                                             1);
-		tracker_db_interface_sqlite_create_function (iface,
-		                                             "SparqlCartesianDistance",
-		                                             function_sparql_cartesian_distance,
-		                                             4);
-		tracker_db_interface_sqlite_create_function (iface,
-		                                             "SparqlHaversineDistance",
-		                                             function_sparql_haversine_distance,
-		                                             4);
-	}
 }
 
 
@@ -553,8 +312,7 @@ db_interface_get (TrackerDB  type,
 
 	db_set_params (iface,
 	               dbs[type].cache_size,
-	               dbs[type].page_size,
-	               dbs[type].add_functions);
+	               dbs[type].page_size);
 
 	return iface;
 }
@@ -1364,8 +1122,7 @@ tracker_db_manager_get_db_interfaces (gint num, ...)
 
 			db_set_params (connection,
 			               dbs[db].cache_size,
-			               dbs[db].page_size,
-			               TRUE);
+			               dbs[db].page_size);
 
 		} else {
 			db_exec_no_reply (connection,
@@ -1397,8 +1154,7 @@ tracker_db_manager_get_db_interfaces_ro (gint num, ...)
 			connection = tracker_db_interface_sqlite_new_ro (dbs[db].abs_filename);
 			db_set_params (connection,
 			               dbs[db].cache_size,
-			               dbs[db].page_size,
-			               TRUE);
+			               dbs[db].page_size);
 		} else {
 			db_exec_no_reply (connection,
 			                  "ATTACH '%s' as '%s'",



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