summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2022-12-03 23:07:43 +0100
committerCarlos Garnacho <carlosg@gnome.org>2022-12-24 01:14:41 +0100
commitf6085ed4e946465e158b6a5ddbe7058cbdf6f624 (patch)
tree45b9b1c06943a063d08231244331c13028a61b4c
parent955ad1aa54192ddfb29504697d99fed0ffc44cd6 (diff)
downloadtracker-f6085ed4e946465e158b6a5ddbe7058cbdf6f624.tar.gz
direct: Implement update statements vmethods
Underneath, query and update statements are backed by TrackerSparql created through different API/parser entrypoints. This means they cannot be mixed together.
-rw-r--r--src/libtracker-sparql/direct/tracker-direct-statement.c135
-rw-r--r--src/libtracker-sparql/direct/tracker-direct-statement.h9
-rw-r--r--src/libtracker-sparql/direct/tracker-direct.c115
-rw-r--r--src/libtracker-sparql/direct/tracker-direct.h15
4 files changed, 244 insertions, 30 deletions
diff --git a/src/libtracker-sparql/direct/tracker-direct-statement.c b/src/libtracker-sparql/direct/tracker-direct-statement.c
index 20ac22a4b..36ff5d198 100644
--- a/src/libtracker-sparql/direct/tracker-direct-statement.c
+++ b/src/libtracker-sparql/direct/tracker-direct-statement.c
@@ -55,28 +55,6 @@ tracker_direct_statement_finalize (GObject *object)
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,
@@ -380,6 +358,58 @@ tracker_direct_statement_serialize_finish (TrackerSparqlStatement *stmt,
return istream;
}
+static gboolean
+tracker_direct_statement_update (TrackerSparqlStatement *stmt,
+ GCancellable *cancellable,
+ GError **error)
+{
+ TrackerSparqlConnection *conn;
+ TrackerDirectStatementPrivate *priv;
+
+ priv = tracker_direct_statement_get_instance_private (TRACKER_DIRECT_STATEMENT (stmt));
+ conn = tracker_sparql_statement_get_connection (stmt);
+
+ return tracker_direct_connection_execute_update_statement (TRACKER_DIRECT_CONNECTION (conn),
+ stmt,
+ priv->values,
+ error);
+}
+
+static void
+tracker_direct_statement_update_async (TrackerSparqlStatement *stmt,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TrackerDirectStatementPrivate *priv;
+ TrackerSparqlConnection *conn;
+ GHashTable *values;
+
+ priv = tracker_direct_statement_get_instance_private (TRACKER_DIRECT_STATEMENT (stmt));
+ conn = tracker_sparql_statement_get_connection (stmt);
+ values = copy_values_deep (priv->values);
+
+ tracker_direct_connection_execute_update_statement_async (TRACKER_DIRECT_CONNECTION (conn),
+ stmt,
+ values,
+ cancellable,
+ callback,
+ user_data);
+}
+
+static gboolean
+tracker_direct_statement_update_finish (TrackerSparqlStatement *stmt,
+ GAsyncResult *res,
+ GError **error)
+{
+ TrackerSparqlConnection *conn;
+
+ conn = tracker_sparql_statement_get_connection (stmt);
+
+ return tracker_direct_connection_execute_update_statement_finish (TRACKER_DIRECT_CONNECTION (conn),
+ res, error);
+}
+
static void
tracker_direct_statement_class_init (TrackerDirectStatementClass *klass)
{
@@ -387,7 +417,6 @@ tracker_direct_statement_class_init (TrackerDirectStatementClass *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;
@@ -400,6 +429,9 @@ tracker_direct_statement_class_init (TrackerDirectStatementClass *klass)
stmt_class->execute_finish = tracker_direct_statement_execute_finish;
stmt_class->serialize_async = tracker_direct_statement_serialize_async;
stmt_class->serialize_finish = tracker_direct_statement_serialize_finish;
+ stmt_class->update = tracker_direct_statement_update;
+ stmt_class->update_async = tracker_direct_statement_update_async;
+ stmt_class->update_finish = tracker_direct_statement_update_finish;
}
static void
@@ -411,13 +443,62 @@ tracker_direct_statement_init (TrackerDirectStatement *stmt)
priv->values = create_values_ht ();
}
+/* Executes with the update lock held */
+gboolean
+tracker_direct_statement_execute_update (TrackerSparqlStatement *stmt,
+ GHashTable *parameters,
+ GHashTable *bnode_labels,
+ GError **error)
+{
+ TrackerDirectStatement *direct;
+ TrackerDirectStatementPrivate *priv;
+
+ direct = TRACKER_DIRECT_STATEMENT (stmt);
+ priv = tracker_direct_statement_get_instance_private (direct);
+
+ return tracker_sparql_execute_update (priv->sparql,
+ parameters,
+ bnode_labels,
+ NULL,
+ error);
+}
+
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);
+ TrackerDirectStatement *direct;
+ TrackerDirectStatementPrivate *priv;
+
+ direct = g_object_new (TRACKER_TYPE_DIRECT_STATEMENT,
+ "sparql", sparql,
+ "connection", conn,
+ NULL);
+
+ priv = tracker_direct_statement_get_instance_private (direct);
+ priv->sparql = tracker_sparql_new (tracker_direct_connection_get_data_manager (TRACKER_DIRECT_CONNECTION (conn)),
+ sparql);
+
+ return direct;
+}
+
+TrackerDirectStatement *
+tracker_direct_statement_new_update (TrackerSparqlConnection *conn,
+ const gchar *sparql,
+ GError **error)
+{
+ TrackerDirectStatement *direct;
+ TrackerDirectStatementPrivate *priv;
+
+ direct = g_object_new (TRACKER_TYPE_DIRECT_STATEMENT,
+ "sparql", sparql,
+ "connection", conn,
+ NULL);
+
+ priv = tracker_direct_statement_get_instance_private (direct);
+ priv->sparql = tracker_sparql_new_update (tracker_direct_connection_get_data_manager (TRACKER_DIRECT_CONNECTION (conn)),
+ sparql);
+
+ return direct;
}
diff --git a/src/libtracker-sparql/direct/tracker-direct-statement.h b/src/libtracker-sparql/direct/tracker-direct-statement.h
index d68bb6bc8..62794d3a4 100644
--- a/src/libtracker-sparql/direct/tracker-direct-statement.h
+++ b/src/libtracker-sparql/direct/tracker-direct-statement.h
@@ -49,4 +49,13 @@ TrackerDirectStatement * tracker_direct_statement_new (TrackerSparqlConnection
const gchar *sparql,
GError **error);
+TrackerDirectStatement * tracker_direct_statement_new_update (TrackerSparqlConnection *conn,
+ const gchar *sparql,
+ GError **error);
+
+gboolean tracker_direct_statement_execute_update (TrackerSparqlStatement *stmt,
+ GHashTable *parameters,
+ GHashTable *bnode_labels,
+ GError **error);
+
#endif /* __TRACKER_DIRECT_STATEMENT_H__ */
diff --git a/src/libtracker-sparql/direct/tracker-direct.c b/src/libtracker-sparql/direct/tracker-direct.c
index 51e08a32b..a84bc3990 100644
--- a/src/libtracker-sparql/direct/tracker-direct.c
+++ b/src/libtracker-sparql/direct/tracker-direct.c
@@ -62,6 +62,11 @@ typedef struct {
} UpdateResource;
typedef struct {
+ TrackerSparqlStatement *stmt;
+ GHashTable *parameters;
+} UpdateStatement;
+
+typedef struct {
gchar *query;
TrackerRdfFormat format;
} SerializeRdf;
@@ -88,6 +93,7 @@ typedef enum {
TASK_TYPE_UPDATE_BLANK,
TASK_TYPE_UPDATE_RESOURCE,
TASK_TYPE_UPDATE_BATCH,
+ TASK_TYPE_UPDATE_STATEMENT,
TASK_TYPE_RELEASE_MEMORY,
TASK_TYPE_SERIALIZE,
TASK_TYPE_DESERIALIZE,
@@ -283,6 +289,15 @@ update_thread_func (gpointer data,
case TASK_TYPE_UPDATE_BATCH:
tracker_direct_batch_update (task_data->data, priv->data_manager, &error);
break;
+ case TASK_TYPE_UPDATE_STATEMENT: {
+ UpdateStatement *data = task_data->data;
+
+ tracker_direct_statement_execute_update (data->stmt,
+ data->parameters,
+ NULL,
+ &error);
+ break;
+ }
case TASK_TYPE_RELEASE_MEMORY:
tracker_data_manager_release_memory (priv->data_manager);
update_timestamp = FALSE;
@@ -900,13 +915,22 @@ tracker_direct_connection_query_finish (TrackerSparqlConnection *self,
static TrackerSparqlStatement *
tracker_direct_connection_query_statement (TrackerSparqlConnection *self,
- const gchar *query,
- GCancellable *cancellable,
- GError **error)
+ const gchar *query,
+ GCancellable *cancellable,
+ GError **error)
{
return TRACKER_SPARQL_STATEMENT (tracker_direct_statement_new (self, query, error));
}
+static TrackerSparqlStatement *
+tracker_direct_connection_update_statement (TrackerSparqlConnection *self,
+ const gchar *query,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return TRACKER_SPARQL_STATEMENT (tracker_direct_statement_new_update (self, query, error));
+}
+
static void
tracker_direct_connection_update (TrackerSparqlConnection *self,
const gchar *sparql,
@@ -1501,6 +1525,7 @@ tracker_direct_connection_class_init (TrackerDirectConnectionClass *klass)
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_statement = tracker_direct_connection_update_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;
@@ -1676,3 +1701,87 @@ tracker_direct_connection_update_batch_finish (TrackerDirectConnection *conn,
return TRUE;
}
+
+static UpdateStatement *
+update_statement_data_new (TrackerSparqlStatement *stmt,
+ GHashTable *parameters)
+{
+ UpdateStatement *data;
+
+ data = g_new0 (UpdateStatement, 1);
+ data->stmt = g_object_ref (stmt);
+ data->parameters = parameters ? g_hash_table_ref (parameters) : NULL;
+
+ return data;
+}
+
+static void
+update_statement_data_free (UpdateStatement *data)
+{
+ g_object_unref (data->stmt);
+ g_clear_pointer (&data->parameters, g_hash_table_unref);
+ g_free (data);
+}
+
+gboolean
+tracker_direct_connection_execute_update_statement (TrackerDirectConnection *conn,
+ TrackerSparqlStatement *stmt,
+ GHashTable *parameters,
+ GError **error)
+{
+ TrackerDirectConnectionPrivate *priv;
+ GError *inner_error = NULL;
+
+ priv = tracker_direct_connection_get_instance_private (conn);
+
+ g_mutex_lock (&priv->mutex);
+ tracker_direct_statement_execute_update (stmt, parameters, NULL, &inner_error);
+ tracker_direct_connection_update_timestamp (conn);
+ g_mutex_unlock (&priv->mutex);
+
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+tracker_direct_connection_execute_update_statement_async (TrackerDirectConnection *conn,
+ TrackerSparqlStatement *stmt,
+ GHashTable *parameters,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TrackerDirectConnectionPrivate *priv;
+ GTask *task;
+
+ priv = tracker_direct_connection_get_instance_private (conn);
+
+ task = g_task_new (stmt, cancellable, callback, user_data);
+ g_task_set_task_data (task,
+ task_data_query_new (TASK_TYPE_UPDATE_STATEMENT,
+ update_statement_data_new (stmt, parameters),
+ (GDestroyNotify) update_statement_data_free),
+ (GDestroyNotify) task_data_free);
+
+ g_thread_pool_push (priv->update_thread, task, NULL);
+}
+
+gboolean
+tracker_direct_connection_execute_update_statement_finish (TrackerDirectConnection *conn,
+ GAsyncResult *res,
+ GError **error)
+{
+ GError *inner_error = NULL;
+
+ g_task_propagate_boolean (G_TASK (res), &inner_error);
+ if (inner_error) {
+ g_propagate_error (error, _translate_internal_error (inner_error));
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/libtracker-sparql/direct/tracker-direct.h b/src/libtracker-sparql/direct/tracker-direct.h
index 8b8da5780..d63a50f6f 100644
--- a/src/libtracker-sparql/direct/tracker-direct.h
+++ b/src/libtracker-sparql/direct/tracker-direct.h
@@ -25,6 +25,7 @@
#include <libtracker-sparql/core/tracker-data.h>
#include "tracker-direct-batch.h"
+#include "tracker-direct-statement.h"
#define TRACKER_TYPE_DIRECT_CONNECTION (tracker_direct_connection_get_type())
#define TRACKER_DIRECT_CONNECTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DIRECT_CONNECTION, TrackerDirectConnection))
@@ -80,4 +81,18 @@ gboolean tracker_direct_connection_update_batch_finish (TrackerDirectConnection
GAsyncResult *res,
GError **error);
+gboolean tracker_direct_connection_execute_update_statement (TrackerDirectConnection *conn,
+ TrackerSparqlStatement *stmt,
+ GHashTable *parameters,
+ GError **error);
+void tracker_direct_connection_execute_update_statement_async (TrackerDirectConnection *conn,
+ TrackerSparqlStatement *stmt,
+ GHashTable *parameters,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean tracker_direct_connection_execute_update_statement_finish (TrackerDirectConnection *conn,
+ GAsyncResult *res,
+ GError **error);
+
#endif /* __TRACKER_LOCAL_CONNECTION_H__ */