diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2018-10-15 23:10:31 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2018-11-13 11:17:31 +0100 |
commit | cdbdff7ff9b3507b5454bf2e65cbeb0a7040f809 (patch) | |
tree | 0797e2b13a25e2e46254fe4424de2351de93c5d4 | |
parent | 3822a5502099874c1b52243da7d324fe71595d45 (diff) | |
download | tracker-cdbdff7ff9b3507b5454bf2e65cbeb0a7040f809.tar.gz |
libtracker-direct: Implement query_statement()
This uses an internal TrackerSparql to hold the query.
-rw-r--r-- | src/libtracker-direct/meson.build | 1 | ||||
-rw-r--r-- | src/libtracker-direct/tracker-direct-statement.c | 265 | ||||
-rw-r--r-- | src/libtracker-direct/tracker-direct-statement.h | 52 | ||||
-rw-r--r-- | src/libtracker-direct/tracker-direct.c | 11 | ||||
-rw-r--r-- | src/libtracker-direct/tracker-direct.h | 2 |
5 files changed, 331 insertions, 0 deletions
diff --git a/src/libtracker-direct/meson.build b/src/libtracker-direct/meson.build index 0c515eaa7..aff19a885 100644 --- a/src/libtracker-direct/meson.build +++ b/src/libtracker-direct/meson.build @@ -1,5 +1,6 @@ libtracker_direct = static_library('tracker-direct', 'tracker-direct.c', + 'tracker-direct-statement.c', c_args: tracker_c_args, dependencies: [ glib, gio, tracker_data_dep ], include_directories: [commoninc, configinc, srcinc], diff --git a/src/libtracker-direct/tracker-direct-statement.c b/src/libtracker-direct/tracker-direct-statement.c new file mode 100644 index 000000000..68ede258f --- /dev/null +++ b/src/libtracker-direct/tracker-direct-statement.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2018, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "tracker-direct-statement.h" +#include "tracker-data.h" + +typedef struct _TrackerDirectStatementPrivate TrackerDirectStatementPrivate; + +struct _TrackerDirectStatementPrivate +{ + TrackerSparql *sparql; + GHashTable *values; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (TrackerDirectStatement, + tracker_direct_statement, + TRACKER_SPARQL_TYPE_STATEMENT) + +static void +tracker_direct_statement_finalize (GObject *object) +{ + TrackerDirectStatementPrivate *priv; + + priv = tracker_direct_statement_get_instance_private (TRACKER_DIRECT_STATEMENT (object)); + g_hash_table_destroy (priv->values); + g_clear_object (&priv->sparql); + + G_OBJECT_CLASS (tracker_direct_statement_parent_class)->finalize (object); +} + +static void +tracker_direct_statement_constructed (GObject *object) +{ + TrackerDirectStatementPrivate *priv; + TrackerSparqlConnection *conn; + gchar *sparql; + + priv = tracker_direct_statement_get_instance_private (TRACKER_DIRECT_STATEMENT (object)); + + g_object_get (object, + "sparql", &sparql, + "connection", &conn, + NULL); + + priv->sparql = tracker_sparql_new (tracker_direct_connection_get_data_manager (TRACKER_DIRECT_CONNECTION (conn)), + sparql); + g_object_unref (conn); + g_free (sparql); + + G_OBJECT_CLASS (tracker_direct_statement_parent_class)->constructed (object); +} + +static GValue * +insert_value (TrackerDirectStatement *stmt, + const gchar *name, + GType type) +{ + TrackerDirectStatementPrivate *priv; + GValue *value; + + priv = tracker_direct_statement_get_instance_private (stmt); + value = g_new0 (GValue, 1); + g_value_init (value, type); + + g_hash_table_insert (priv->values, g_strdup (name), value); + + return value; +} + +static void +tracker_direct_statement_bind_int (TrackerSparqlStatement *stmt, + const gchar *name, + gint64 value) +{ + GValue *gvalue; + + gvalue = insert_value (TRACKER_DIRECT_STATEMENT (stmt), name, G_TYPE_INT64); + g_value_set_int64 (gvalue, value); +} + +static void +tracker_direct_statement_bind_double (TrackerSparqlStatement *stmt, + const gchar *name, + double value) +{ + GValue *gvalue; + + gvalue = insert_value (TRACKER_DIRECT_STATEMENT (stmt), name, G_TYPE_DOUBLE); + g_value_set_double (gvalue, value); +} + +static void +tracker_direct_statement_bind_boolean (TrackerSparqlStatement *stmt, + const gchar *name, + gboolean value) +{ + GValue *gvalue; + + gvalue = insert_value (TRACKER_DIRECT_STATEMENT (stmt), name, G_TYPE_BOOLEAN); + g_value_set_boolean (gvalue, value); +} + +static void +tracker_direct_statement_bind_string (TrackerSparqlStatement *stmt, + const gchar *name, + const gchar *value) +{ + GValue *gvalue; + + gvalue = insert_value (TRACKER_DIRECT_STATEMENT (stmt), name, G_TYPE_STRING); + g_value_set_string (gvalue, value); +} + +static TrackerSparqlCursor * +tracker_direct_statement_execute (TrackerSparqlStatement *stmt, + GCancellable *cancellable, + GError **error) +{ + TrackerDirectStatementPrivate *priv; + + priv = tracker_direct_statement_get_instance_private (TRACKER_DIRECT_STATEMENT (stmt)); + + return tracker_sparql_execute_cursor (priv->sparql, priv->values, error); +} + +static void +execute_in_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + TrackerDirectStatementPrivate *priv; + TrackerSparqlCursor *cursor; + GHashTable *values = task_data; + GError *error = NULL; + + priv = tracker_direct_statement_get_instance_private (object); + cursor = tracker_sparql_execute_cursor (priv->sparql, values, &error); + + if (error) + g_task_return_error (task, error); + else + g_task_return_pointer (task, cursor, g_object_unref); + + g_object_unref (task); +} + +static void +free_gvalue (gpointer data) +{ + g_value_unset (data); + g_free (data); +} + +static GHashTable * +create_values_ht (void) +{ + return g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, free_gvalue); +} + +static GHashTable * +copy_values_deep (GHashTable *values) +{ + GHashTable *copy; + GHashTableIter iter; + gpointer key, val; + + copy = create_values_ht (); + g_hash_table_iter_init (&iter, values); + + while (g_hash_table_iter_next (&iter, &key, &val)) { + GValue *copy_value; + + copy_value = g_new0 (GValue, 1); + g_value_init (copy_value, G_VALUE_TYPE (val)); + g_value_copy (copy_value, val); + + g_hash_table_insert (copy, g_strdup (key), copy_value); + } + + return copy; +} + +static void +tracker_direct_statement_execute_async (TrackerSparqlStatement *stmt, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + TrackerDirectStatementPrivate *priv; + GHashTable *values; + GTask *task; + + priv = tracker_direct_statement_get_instance_private (TRACKER_DIRECT_STATEMENT (stmt)); + + values = copy_values_deep (priv->values); + + task = g_task_new (stmt, cancellable, callback, user_data); + g_task_set_task_data (task, values, (GDestroyNotify) g_hash_table_unref); + g_task_run_in_thread (task, execute_in_thread); +} + +static TrackerSparqlCursor * +tracker_direct_statement_execute_finish (TrackerSparqlStatement *stmt, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +tracker_direct_statement_class_init (TrackerDirectStatementClass *klass) +{ + TrackerSparqlStatementClass *stmt_class = (TrackerSparqlStatementClass *) klass; + GObjectClass *object_class = (GObjectClass *) klass; + + object_class->finalize = tracker_direct_statement_finalize; + object_class->constructed = tracker_direct_statement_constructed; + + stmt_class->bind_int = tracker_direct_statement_bind_int; + stmt_class->bind_boolean = tracker_direct_statement_bind_boolean; + stmt_class->bind_double = tracker_direct_statement_bind_double; + stmt_class->bind_string = tracker_direct_statement_bind_string; + stmt_class->execute = tracker_direct_statement_execute; + stmt_class->execute_async = tracker_direct_statement_execute_async; + stmt_class->execute_finish = tracker_direct_statement_execute_finish; +} + +static void +tracker_direct_statement_init (TrackerDirectStatement *stmt) +{ + TrackerDirectStatementPrivate *priv; + + priv = tracker_direct_statement_get_instance_private (stmt); + priv->values = create_values_ht (); +} + +TrackerDirectStatement * +tracker_direct_statement_new (TrackerSparqlConnection *conn, + const gchar *sparql, + GError **error) +{ + return g_object_new (TRACKER_TYPE_DIRECT_STATEMENT, + "sparql", sparql, + "connection", conn, + NULL); +} diff --git a/src/libtracker-direct/tracker-direct-statement.h b/src/libtracker-direct/tracker-direct-statement.h new file mode 100644 index 000000000..d68bb6bc8 --- /dev/null +++ b/src/libtracker-direct/tracker-direct-statement.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __TRACKER_DIRECT_STATEMENT_H__ +#define __TRACKER_DIRECT_STATEMENT_H__ + +#include "tracker-direct.h" +#include <libtracker-sparql/tracker-sparql.h> + +#define TRACKER_TYPE_DIRECT_STATEMENT (tracker_direct_statement_get_type ()) +#define TRACKER_DIRECT_STATEMENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DIRECT_STATEMENT, TrackerDirectStatement)) +#define TRACKER_DIRECT_STATEMENT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DIRECT_STATEMENT, TrackerDirectStatementClass)) +#define TRACKER_IS_DIRECT_STATEMENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DIRECT_STATEMENT)) +#define TRACKER_IS_DIRECT_STATEMENT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_DIRECT_STATEMENT)) +#define TRACKER_DIRECT_STATEMENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DIRECT_STATEMENT, TrackerDirectStatementClass)) + +typedef struct _TrackerDirectStatement TrackerDirectStatement; +typedef struct _TrackerDirectStatementClass TrackerDirectStatementClass; + +struct _TrackerDirectStatementClass +{ + TrackerSparqlStatementClass parent_class; +}; + +struct _TrackerDirectStatement +{ + TrackerSparqlStatement parent_instance; +}; + +GType tracker_direct_statement_get_type (void) G_GNUC_CONST; + +TrackerDirectStatement * tracker_direct_statement_new (TrackerSparqlConnection *conn, + const gchar *sparql, + GError **error); + +#endif /* __TRACKER_DIRECT_STATEMENT_H__ */ diff --git a/src/libtracker-direct/tracker-direct.c b/src/libtracker-direct/tracker-direct.c index 9bec7429b..7d62c6f30 100644 --- a/src/libtracker-direct/tracker-direct.c +++ b/src/libtracker-direct/tracker-direct.c @@ -21,6 +21,7 @@ #include "config.h" #include "tracker-direct.h" +#include "tracker-direct-statement.h" #include <libtracker-data/tracker-data.h> #include <libtracker-data/tracker-sparql.h> @@ -480,6 +481,15 @@ tracker_direct_connection_query_finish (TrackerSparqlConnection *self, return g_task_propagate_pointer (G_TASK (res), error); } +static TrackerSparqlStatement * +tracker_direct_connection_query_statement (TrackerSparqlConnection *self, + const gchar *query, + GCancellable *cancellable, + GError **error) +{ + return TRACKER_SPARQL_STATEMENT (tracker_direct_statement_new (self, query, error)); +} + static void tracker_direct_connection_update (TrackerSparqlConnection *self, const gchar *sparql, @@ -745,6 +755,7 @@ tracker_direct_connection_class_init (TrackerDirectConnectionClass *klass) sparql_connection_class->query = tracker_direct_connection_query; sparql_connection_class->query_async = tracker_direct_connection_query_async; sparql_connection_class->query_finish = tracker_direct_connection_query_finish; + sparql_connection_class->query_statement = tracker_direct_connection_query_statement; sparql_connection_class->update = tracker_direct_connection_update; sparql_connection_class->update_async = tracker_direct_connection_update_async; sparql_connection_class->update_finish = tracker_direct_connection_update_finish; diff --git a/src/libtracker-direct/tracker-direct.h b/src/libtracker-direct/tracker-direct.h index 0b66fdb1f..950db3975 100644 --- a/src/libtracker-direct/tracker-direct.h +++ b/src/libtracker-direct/tracker-direct.h @@ -44,6 +44,8 @@ struct _TrackerDirectConnection TrackerSparqlConnection parent_instance; }; +GType tracker_direct_connection_get_type (void) G_GNUC_CONST; + TrackerDirectConnection *tracker_direct_connection_new (TrackerSparqlConnectionFlags flags, GFile *store, GFile *journal, |