tracker r2985 - in trunk: . src/libtracker-data src/libtracker-db
- From: mottela svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r2985 - in trunk: . src/libtracker-data src/libtracker-db
- Date: Fri, 27 Feb 2009 02:18:00 +0000 (UTC)
Author: mottela
Date: Fri Feb 27 02:18:00 2009
New Revision: 2985
URL: http://svn.gnome.org/viewvc/tracker?rev=2985&view=rev
Log:
Abstraction layer to sqlite aggregate function-creation, new version of GROUP_CONCAT and some minor fixes
Modified:
trunk/ChangeLog
trunk/src/libtracker-data/tracker-data-backup.c
trunk/src/libtracker-data/tracker-data-search.c
trunk/src/libtracker-db/tracker-db-interface-sqlite.c
trunk/src/libtracker-db/tracker-db-interface-sqlite.h
trunk/src/libtracker-db/tracker-db-manager.c
Modified: trunk/src/libtracker-data/tracker-data-backup.c
==============================================================================
--- trunk/src/libtracker-data/tracker-data-backup.c (original)
+++ trunk/src/libtracker-data/tracker-data-backup.c Fri Feb 27 02:18:00 2009
@@ -98,10 +98,10 @@
(gchar *)triple->predicate,
(gchar *)triple->object);
- (data.func) ((const gchar *) triple->subject,
- (const gchar *) triple->predicate,
- (const gchar *) triple->object,
- data->user_data);
+ (data->func) ((const gchar *) triple->subject,
+ (const gchar *) triple->predicate,
+ (const gchar *) triple->object,
+ data->user_data);
}
#endif /* HAVE_RAPTOR */
@@ -160,10 +160,10 @@
if (!g_file_test (turtle_filename, G_FILE_TEST_EXISTS)) {
g_set_error (error, 0, 0,
"Turtle file does not exist");
- return;
+ return FALSE;
}
- tracker_turtle_process (backup_file,
+ tracker_turtle_process (turtle_filename,
"/",
(TurtleTripleCallback) restore_backup_triple,
&data);
Modified: trunk/src/libtracker-data/tracker-data-search.c
==============================================================================
--- trunk/src/libtracker-data/tracker-data-search.c (original)
+++ trunk/src/libtracker-data/tracker-data-search.c Fri Feb 27 02:18:00 2009
@@ -1315,7 +1315,7 @@
g_string_free (sql_group, TRUE);
g_set_error (error, TRACKER_DBUS_ERROR, 0,
- "Cannot sum '%s': this metadata type is not text",
+ "Cannot concatenate '%s': this metadata type is not text",
sum_field);
return NULL;
}
Modified: trunk/src/libtracker-db/tracker-db-interface-sqlite.c
==============================================================================
--- trunk/src/libtracker-db/tracker-db-interface-sqlite.c (original)
+++ trunk/src/libtracker-db/tracker-db-interface-sqlite.c Fri Feb 27 02:18:00 2009
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* Tracker - Sqlite implementation
* Copyright (C) 2008 Nokia
*
@@ -24,6 +25,7 @@
typedef struct TrackerDBInterfaceSqlitePrivate TrackerDBInterfaceSqlitePrivate;
typedef struct SqliteFunctionData SqliteFunctionData;
+typedef struct SqliteAggregateData SqliteAggregateData;
struct TrackerDBInterfaceSqlitePrivate {
gchar *filename;
@@ -33,6 +35,7 @@
GHashTable *procedures;
GSList *function_data;
+ GSList *aggregate_data;
guint in_transaction : 1;
guint ro : 1;
@@ -43,6 +46,14 @@
TrackerDBFunc func;
};
+struct SqliteAggregateData {
+ TrackerDBInterface *interface;
+ guint context_size;
+ TrackerDBFuncStep step;
+ TrackerDBFuncFinal final;
+
+};
+
static void tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface);
enum {
@@ -59,7 +70,7 @@
void
tracker_db_interface_sqlite_enable_shared_cache (void)
{
- sqlite3_enable_shared_cache (1);
+ sqlite3_enable_shared_cache (1);
}
static GObject *
@@ -162,6 +173,9 @@
g_slist_foreach (priv->function_data, (GFunc) g_free, NULL);
g_slist_free (priv->function_data);
+ g_slist_foreach (priv->aggregate_data, (GFunc) g_free, NULL);
+ g_slist_free (priv->aggregate_data);
+
sqlite3_close (priv->db);
g_message ("Closed sqlite3 database:'%s'", priv->filename);
@@ -347,6 +361,114 @@
}
static void
+internal_sqlite3_aggregate_step (sqlite3_context *context,
+ int argc,
+ sqlite3_value *argv[])
+{
+ SqliteAggregateData *data;
+ void *aggregate_context;
+ GValue *values;
+ GByteArray *blob_array;
+ gint i;
+
+ data = (SqliteAggregateData *) 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_BLOB: {
+ gconstpointer blob;
+ gint size;
+
+ blob = sqlite3_value_blob (argv[i]);
+ size = sqlite3_value_bytes (argv[i]);
+
+ blob_array = g_byte_array_sized_new (size);
+ g_byte_array_append (blob_array, blob, size);
+
+ g_value_init (&values[i], TRACKER_TYPE_DB_BLOB);
+ g_value_take_boxed (&values[i], blob_array);
+
+ break;
+ }
+ default:
+ g_critical ("Unknown sqlite3 database value type:%d",
+ sqlite3_value_type (argv[i]));
+ }
+ }
+
+ aggregate_context = sqlite3_aggregate_context(context, data->context_size);
+
+ /* Call the function */
+ data->step (data->interface, aggregate_context, argc, values);
+
+ /* Now free all this mess */
+ for (i = 0; i < argc; i++) {
+ g_value_unset (&values[i]);
+ }
+
+ g_free (values);
+}
+
+static void
+internal_sqlite3_aggregate_final (sqlite3_context *context)
+{
+ SqliteAggregateData *data;
+ void *aggregate_context;
+ GValue result;
+ GByteArray *blob_array;
+
+ data = (SqliteAggregateData *) sqlite3_user_data (context);
+
+ aggregate_context = sqlite3_aggregate_context(context, 0);
+
+ /* Call the function */
+ result = data->final (data->interface, aggregate_context);
+
+ /* 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, TRACKER_TYPE_DB_BLOB)) {
+ blob_array = g_value_get_boxed (&result);
+ sqlite3_result_blob (context,
+ g_memdup (blob_array->data, blob_array->len),
+ blob_array->len,
+ 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 */
+
+ if (! G_VALUE_HOLDS (&result, G_TYPE_INVALID)) {
+ g_value_unset (&result);
+ }
+}
+
+static void
tracker_db_interface_sqlite_set_procedure_table (TrackerDBInterface *db_interface,
GHashTable *procedure_table)
{
@@ -642,6 +764,32 @@
sqlite3_create_function (priv->db, name, n_args, SQLITE_ANY, data, &internal_sqlite3_function, NULL, NULL);
}
+void
+tracker_db_interface_sqlite_create_aggregate (TrackerDBInterface *interface,
+ const gchar *name,
+ TrackerDBFuncStep step,
+ gint n_args,
+ TrackerDBFuncFinal final,
+ guint context_size)
+{
+ SqliteAggregateData *data;
+ TrackerDBInterfaceSqlitePrivate *priv;
+
+ priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (interface);
+
+ data = g_new0 (SqliteAggregateData, 1);
+ data->interface = interface;
+ data->context_size = context_size;
+ data->step = step;
+ data->final = final;
+
+ priv->aggregate_data = g_slist_prepend (priv->aggregate_data, data);
+
+ sqlite3_create_function (priv->db, name, n_args, SQLITE_ANY, data, NULL,
+ &internal_sqlite3_aggregate_step,
+ &internal_sqlite3_aggregate_final);
+}
+
gboolean
tracker_db_interface_sqlite_set_collation_function (TrackerDBInterfaceSqlite *interface,
const gchar *name,
Modified: trunk/src/libtracker-db/tracker-db-interface-sqlite.h
==============================================================================
--- trunk/src/libtracker-db/tracker-db-interface-sqlite.h (original)
+++ trunk/src/libtracker-db/tracker-db-interface-sqlite.h Fri Feb 27 02:18:00 2009
@@ -42,6 +42,14 @@
gint argc,
GValue argv[]);
+typedef void (* TrackerDBFuncStep) (TrackerDBInterface *interface,
+ void *aggregate_context,
+ gint argc,
+ GValue argv[]);
+
+typedef GValue (* TrackerDBFuncFinal) (TrackerDBInterface *interface,
+ void *aggregate_context);
+
struct TrackerDBInterfaceSqlite {
GObject parent_instance;
};
@@ -59,6 +67,12 @@
const gchar *name,
TrackerDBFunc func,
gint n_args);
+void tracker_db_interface_sqlite_create_aggregate (TrackerDBInterface *interface,
+ const gchar *name,
+ TrackerDBFuncStep step,
+ gint n_args,
+ TrackerDBFuncFinal final,
+ guint context_size);
gboolean tracker_db_interface_sqlite_set_collation_function (TrackerDBInterfaceSqlite *interface,
const gchar *name,
TrackerDBCollationFunc func);
Modified: trunk/src/libtracker-db/tracker-db-manager.c
==============================================================================
--- trunk/src/libtracker-db/tracker-db-manager.c (original)
+++ trunk/src/libtracker-db/tracker-db-manager.c Fri Feb 27 02:18:00 2009
@@ -79,6 +79,10 @@
guint64 mtime;
} TrackerDBDefinition;
+typedef struct {
+ GString *string; /* The string we are accumulating */
+} AggregateData;
+
static TrackerDBDefinition dbs[] = {
{ TRACKER_DB_UNKNOWN,
TRACKER_DB_LOCATION_USER_DATA_DIR,
@@ -1325,6 +1329,41 @@
return result;
}
+static void
+function_group_concat_step (TrackerDBInterface *interface,
+ void *aggregate_context,
+ gint argc,
+ GValue values[])
+{
+ AggregateData *p = (AggregateData *)aggregate_context;
+
+ g_assert (argc==1);
+
+ if (!p->string) {
+ p->string = g_string_new ("");
+ } else {
+ p->string = g_string_append (p->string, "|");
+ }
+
+ p->string = g_string_append (p->string, g_value_get_string (&values[0]));
+}
+
+static GValue
+function_group_concat_final (TrackerDBInterface *interface,
+ void *aggregate_context)
+{
+ GValue result = { 0, };
+ AggregateData *p = (AggregateData *)aggregate_context;
+
+ g_value_init (&result, G_TYPE_STRING);
+ g_value_set_string (&result, p->string->str);
+
+ g_string_free (p->string, TRUE);
+
+ return result;
+}
+
+
static GValue
function_get_service_name (TrackerDBInterface *interface,
gint argc,
@@ -1697,6 +1736,14 @@
"replace",
function_replace,
3);
+
+ tracker_db_interface_sqlite_create_aggregate (iface,
+ "group_concat",
+ function_group_concat_step,
+ 1,
+ function_group_concat_final,
+ sizeof(AggregateData));
+
tracker_db_interface_sqlite_create_function (iface,
"CollateKey",
function_collate_key,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]