diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2022-12-03 23:07:43 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2022-12-24 01:14:41 +0100 |
commit | f6085ed4e946465e158b6a5ddbe7058cbdf6f624 (patch) | |
tree | 45b9b1c06943a063d08231244331c13028a61b4c | |
parent | 955ad1aa54192ddfb29504697d99fed0ffc44cd6 (diff) | |
download | tracker-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.c | 135 | ||||
-rw-r--r-- | src/libtracker-sparql/direct/tracker-direct-statement.h | 9 | ||||
-rw-r--r-- | src/libtracker-sparql/direct/tracker-direct.c | 115 | ||||
-rw-r--r-- | src/libtracker-sparql/direct/tracker-direct.h | 15 |
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__ */ |