1 /*
2  * Copyright (C) 2010, Nokia <ivan.frade@nokia.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19 
20 /**
21  * SECTION: tracker-sparql-connection
22  * @short_description: Connection to SPARQL triple store
23  * @title: TrackerSparqlConnection
24  * @stability: Stable
25  * @include: tracker-sparql.h
26  *
27  * <para>
28  * #TrackerSparqlConnection is an object that represents a connection to a
29  * SPARQL triple store. This store may be local and private (see
30  * tracker_sparql_connection_new()), or it may be a remote connection to a
31  * public endpoint (See tracker_sparql_connection_bus_new() and
32  * tracker_sparql_connection_remote_new()).
33  * </para>
34  *
35  * <para>
36  * A #TrackerSparqlConnection is private to the calling process, it can be
37  * exposed publicly via a #TrackerEndpoint, see tracker_endpoint_dbus_new().
38  * </para>
39  *
40  * <para>
41  * Updates on a connection are performed via the tracker_sparql_connection_update()
42  * family of calls. tracker_sparql_connection_update_array() may be used for batched
43  * updates. All functions have asynchronous variants.
44  * </para>
45  *
46  * <para>
47  * Queries on a connection are performed via tracker_sparql_connection_query()
48  * and tracker_sparql_connection_query_statement(). The first call receives a
49  * query string and returns a #TrackerSparqlCursor to iterate the results. The
50  * second call returns a #TrackerSparqlStatement object that may be reused for
51  * repeatable queries with variable parameters. tracker_sparql_statement_execute()
52  * will returns a #TrackerSparqlCursor.
53  * </para>
54  *
55  * <para>
56  * Depending on the ontology definition, #TrackerSparqlConnection may emit
57  * notifications whenever changes happen in the stored data. These notifications
58  * can be processed via a #TrackerNotifier obtained with
59  * tracker_sparql_connection_create_notifier().
60  * </para>
61  *
62  * <para>
63  * After use, a #TrackerSparqlConnection should be closed. See
64  * tracker_sparql_connection_close() and tracker_sparql_connection_close_async().
65  * </para>
66  */
67 #include "config.h"
68 
69 #include "tracker-connection.h"
70 #include "tracker-private.h"
71 
G_DEFINE_ABSTRACT_TYPE(TrackerSparqlConnection,tracker_sparql_connection,G_TYPE_OBJECT)72 G_DEFINE_ABSTRACT_TYPE (TrackerSparqlConnection, tracker_sparql_connection,
73                         G_TYPE_OBJECT)
74 
75 static void
76 tracker_sparql_connection_init (TrackerSparqlConnection *connection)
77 {
78 }
79 
80 static void
tracker_sparql_connection_dispose(GObject * object)81 tracker_sparql_connection_dispose (GObject *object)
82 {
83 	tracker_sparql_connection_close (TRACKER_SPARQL_CONNECTION (object));
84 
85 	G_OBJECT_CLASS (tracker_sparql_connection_parent_class)->dispose (object);
86 }
87 
88 static void
tracker_sparql_connection_class_init(TrackerSparqlConnectionClass * klass)89 tracker_sparql_connection_class_init (TrackerSparqlConnectionClass *klass)
90 {
91 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
92 
93 	object_class->dispose = tracker_sparql_connection_dispose;
94 }
95 
96 gboolean
tracker_sparql_connection_lookup_dbus_service(TrackerSparqlConnection * connection,const gchar * dbus_name,const gchar * dbus_path,gchar ** name,gchar ** path)97 tracker_sparql_connection_lookup_dbus_service (TrackerSparqlConnection  *connection,
98                                                const gchar              *dbus_name,
99                                                const gchar              *dbus_path,
100                                                gchar                   **name,
101                                                gchar                   **path)
102 {
103 	TrackerSparqlConnectionClass *connection_class;
104 
105 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
106 	g_return_val_if_fail (dbus_name != NULL, FALSE);
107 
108 	connection_class = TRACKER_SPARQL_CONNECTION_GET_CLASS (connection);
109 	if (!connection_class->lookup_dbus_service)
110 		return FALSE;
111 
112 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->lookup_dbus_service (connection,
113 	                                                                              dbus_name,
114 	                                                                              dbus_path,
115 	                                                                              name,
116 	                                                                              path);
117 }
118 
119 /* The constructor functions are defined in the libtracker-sparql-backend, but
120  * documented here. */
121 
122 /**
123  * tracker_sparql_connection_new:
124  * @flags: values from #TrackerSparqlConnectionFlags
125  * @store: (nullable): the directory that contains the database as a #GFile, or %NULL
126  * @ontology: (nullable): the directory that contains the database schemas as a #GFile, or %NULL
127  * @cancellable: (nullable): a #GCancellable, or %NULL
128  * @error: pointer to a #GError
129  *
130  * Creates or opens a database.
131  *
132  * This method should only be used for databases owned by the current process.
133  * To connect to databases managed by other processes, use
134  * tracker_sparql_connection_bus_new().
135  *
136  * If @store is %NULL, the database will be created in memory.
137  *
138  * The @ontologies parameter must point to a location containing suitable
139  * `.ontology` files in Turtle format. These control the database schema that
140  * is used. You can use the default Nepomuk ontologies by calling
141  * tracker_sparql_get_ontology_nepomuk ().
142  *
143  * If you open an existing database using a different @ontology to the one it
144  * was created with, Tracker will attempt to migrate the existing data to the
145  * new schema. This may raise an error. In particular, not all migrations are
146  * possible without causing data loss and Tracker will refuse to delete data
147  * during a migration.
148  *
149  * You can also pass %NULL for @ontologies to mean "use the ontologies that the
150  * database was created with". This will fail if the database doesn't already
151  * exist.
152  *
153  * Returns: (transfer full): a new #TrackerSparqlConnection. Call
154  * g_object_unref() on the object when no longer used.
155  *
156  * Since: 3.0
157  */
158 
159 /**
160  * tracker_sparql_connection_new_async:
161  * @flags: values from #TrackerSparqlConnectionFlags
162  * @store: (nullable): the directory that contains the database as a #GFile, or %NULL
163  * @ontology: (nullable): the directory that contains the database schemas as a #GFile, or %NULL
164  * @cancellable: (nullable): a #GCancellable, or %NULL
165  * @callback: the #GAsyncReadyCallback called when the operation completes
166  * @user_data: data passed to @callback
167  *
168  * Asynchronous version of tracker_sparql_connection_new().
169  *
170  * Since: 3.0
171  */
172 
173 /**
174  * tracker_sparql_connection_new_finish:
175  * @result: the #GAsyncResult
176  * @error: pointer to a #GError
177  *
178  * Completion function for tracker_sparql_connection_new_async().
179  *
180  * Since: 3.0
181  */
182 
183 /**
184  * tracker_sparql_connection_bus_new:
185  * @service_name: The name of the D-Bus service to connect to.
186  * @object_path: (nullable): The path to the object, or %NULL to use the default.
187  * @dbus_connection: (nullable): The #GDBusConnection to use, or %NULL to use the session bus
188  * @error: pointer to a #GError
189  *
190  * Connects to a database owned by another process on the
191  * local machine.
192  *
193  * Returns: (transfer full): a new #TrackerSparqlConnection. Call g_object_unref() on the
194  * object when no longer used.
195  *
196  * Since: 3.0
197  */
198 
199 /**
200  * tracker_sparql_connection_bus_new_async:
201  * @service_name: The name of the D-Bus service to connect to.
202  * @object_path: (nullable): The path to the object, or %NULL to use the default.
203  * @dbus_connection: (nullable): The #GDBusConnection to use, or %NULL to use the session bus
204  * @cancellable: (nullable): a #GCancellable, or %NULL
205  * @callback: the #GAsyncReadyCallback called when the operation completes
206  * @user_data: data passed to @callback
207  *
208  * Connects to a database owned by another process on the
209  * local machine. This is an asynchronous operation.
210  *
211  * Since: 3.1
212  */
213 
214 /**
215  * tracker_sparql_connection_bus_new_finish:
216  * @result: the #GAsyncResult
217  * @error: pointer to a #GError
218  *
219  * Completion function for tracker_sparql_connection_bus_new_async().
220  *
221  * Returns: (transfer full): a new #TrackerSparqlConnection. Call g_object_unref() on the
222  * object when no longer used.
223  *
224  * Since: 3.1
225  */
226 
227 /**
228  * tracker_sparql_connection_remote_new:
229  * @uri_base: Base URI of the remote connection
230  *
231  * Connects to a remote SPARQL endpoint. The connection is made using the libsoup
232  * HTTP library. The connection will normally use the http:// or https:// protocol.
233  *
234  * Returns: (transfer full): a new remote #TrackerSparqlConnection. Call
235  * g_object_unref() on the object when no longer used.
236  */
237 
238 /**
239  * tracker_sparql_connection_query:
240  * @connection: a #TrackerSparqlConnection
241  * @sparql: string containing the SPARQL query
242  * @cancellable: a #GCancellable used to cancel the operation
243  * @error: #GError for error reporting.
244  *
245  * Executes a SPARQL query on. The API call is completely synchronous, so
246  * it may block.
247  *
248  * The @sparql query should be built with #TrackerResource, or
249  * its parts correctly escaped using tracker_sparql_escape_string(),
250  * otherwise SPARQL injection is possible.
251  *
252  * Returns: (transfer full): a #TrackerSparqlCursor if results were found.
253  * On error, #NULL is returned and the @error is set accordingly.
254  * Call g_object_unref() on the returned cursor when no longer needed.
255  */
256 TrackerSparqlCursor *
tracker_sparql_connection_query(TrackerSparqlConnection * connection,const gchar * sparql,GCancellable * cancellable,GError ** error)257 tracker_sparql_connection_query (TrackerSparqlConnection  *connection,
258                                  const gchar              *sparql,
259                                  GCancellable             *cancellable,
260                                  GError                  **error)
261 {
262 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
263 	g_return_val_if_fail (sparql != NULL, NULL);
264 	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
265 	g_return_val_if_fail (!error || !*error, NULL);
266 
267 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query (connection,
268 	                                                                sparql,
269 	                                                                cancellable,
270 	                                                                error);
271 }
272 
273 /**
274  * tracker_sparql_connection_query_async:
275  * @connection: a #TrackerSparqlConnection
276  * @sparql: string containing the SPARQL query
277  * @cancellable: a #GCancellable used to cancel the operation
278  * @callback: user-defined #GAsyncReadyCallback to be called when
279  *            asynchronous operation is finished.
280  * @user_data: user-defined data to be passed to @callback
281  *
282  * Executes asynchronously a SPARQL query.
283  */
284 void
tracker_sparql_connection_query_async(TrackerSparqlConnection * connection,const gchar * sparql,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)285 tracker_sparql_connection_query_async (TrackerSparqlConnection *connection,
286                                        const gchar             *sparql,
287                                        GCancellable            *cancellable,
288                                        GAsyncReadyCallback      callback,
289                                        gpointer                 user_data)
290 {
291 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
292 	g_return_if_fail (sparql != NULL);
293 	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
294 
295 	TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query_async (connection,
296 	                                                               sparql,
297 	                                                               cancellable,
298 	                                                               callback,
299 	                                                               user_data);
300 }
301 
302 /**
303  * tracker_sparql_connection_query_finish:
304  * @connection: a #TrackerSparqlConnection
305  * @res: a #GAsyncResult with the result of the operation
306  * @error: #GError for error reporting.
307  *
308  * Finishes the asynchronous SPARQL query operation.
309  *
310  * Returns: (transfer full): a #TrackerSparqlCursor if results were found.
311  * On error, #NULL is returned and the @error is set accordingly.
312  * Call g_object_unref() on the returned cursor when no longer needed.
313  */
314 TrackerSparqlCursor *
tracker_sparql_connection_query_finish(TrackerSparqlConnection * connection,GAsyncResult * res,GError ** error)315 tracker_sparql_connection_query_finish (TrackerSparqlConnection  *connection,
316                                         GAsyncResult             *res,
317                                         GError                  **error)
318 {
319 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
320 	g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
321 	g_return_val_if_fail (!error || !*error, NULL);
322 
323 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query_finish (connection,
324 	                                                                       res,
325 	                                                                       error);
326 }
327 
328 /**
329  * tracker_sparql_connection_update:
330  * @connection: a #TrackerSparqlConnection
331  * @sparql: string containing the SPARQL update query
332  * @cancellable: a #GCancellable used to cancel the operation
333  * @error: #GError for error reporting.
334  *
335  * Executes a SPARQL update. The API call is completely
336  * synchronous, so it may block.
337  *
338  * The @sparql query should be built with #TrackerResource, or
339  * its parts correctly escaped using tracker_sparql_escape_string(),
340  * otherwise SPARQL injection is possible.
341  */
342 void
tracker_sparql_connection_update(TrackerSparqlConnection * connection,const gchar * sparql,GCancellable * cancellable,GError ** error)343 tracker_sparql_connection_update (TrackerSparqlConnection  *connection,
344                                   const gchar              *sparql,
345                                   GCancellable             *cancellable,
346                                   GError                  **error)
347 {
348 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
349 	g_return_if_fail (sparql != NULL);
350 	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
351 	g_return_if_fail (!error || !*error);
352 
353 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update (connection,
354 	                                                                 sparql,
355 	                                                                 cancellable,
356 	                                                                 error);
357 }
358 
359 /**
360  * tracker_sparql_connection_update_async:
361  * @connection: a #TrackerSparqlConnection
362  * @sparql: string containing the SPARQL update query
363  * @cancellable: a #GCancellable used to cancel the operation
364  * @callback: user-defined #GAsyncReadyCallback to be called when
365  *            asynchronous operation is finished.
366  * @user_data: user-defined data to be passed to @callback
367  *
368  * Executes asynchronously a SPARQL update.
369  */
370 void
tracker_sparql_connection_update_async(TrackerSparqlConnection * connection,const gchar * sparql,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)371 tracker_sparql_connection_update_async (TrackerSparqlConnection *connection,
372                                         const gchar             *sparql,
373                                         GCancellable            *cancellable,
374                                         GAsyncReadyCallback      callback,
375                                         gpointer                 user_data)
376 {
377 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
378 	g_return_if_fail (sparql != NULL);
379 	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
380 
381 	TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_async (connection,
382 	                                                                sparql,
383 	                                                                cancellable,
384 	                                                                callback,
385 	                                                                user_data);
386 }
387 
388 /**
389  * tracker_sparql_connection_update_finish:
390  * @connection: a #TrackerSparqlConnection
391  * @res: a #GAsyncResult with the result of the operation
392  * @error: #GError for error reporting.
393  *
394  * Finishes the asynchronous SPARQL update operation.
395  */
396 void
tracker_sparql_connection_update_finish(TrackerSparqlConnection * connection,GAsyncResult * res,GError ** error)397 tracker_sparql_connection_update_finish (TrackerSparqlConnection  *connection,
398                                          GAsyncResult             *res,
399                                          GError                  **error)
400 {
401 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
402 	g_return_if_fail (G_IS_ASYNC_RESULT (res));
403 	g_return_if_fail (!error || !*error);
404 
405 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_finish (connection,
406 	                                                                        res,
407 	                                                                        error);
408 }
409 
410 /**
411  * tracker_sparql_connection_update_array_async:
412  * @connection: a #TrackerSparqlConnection
413  * @sparql: an array of strings containing the SPARQL update queries
414  * @sparql_length: the amount of strings you pass as @sparql
415  * @cancellable: a #GCancellable used to cancel the operation
416  * @callback: user-defined #GAsyncReadyCallback to be called when
417  *            asynchronous operation is finished.
418  * @user_data: user-defined data to be passed to @callback
419  *
420  * Executes asynchronously an array of SPARQL updates. All updates in the
421  * array are handled within a single transaction.
422  */
423 void
tracker_sparql_connection_update_array_async(TrackerSparqlConnection * connection,gchar ** sparql,gint sparql_length,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)424 tracker_sparql_connection_update_array_async (TrackerSparqlConnection  *connection,
425                                               gchar                   **sparql,
426                                               gint                      sparql_length,
427                                               GCancellable             *cancellable,
428                                               GAsyncReadyCallback       callback,
429                                               gpointer                  user_data)
430 {
431 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
432 	g_return_if_fail (sparql != NULL || sparql_length == 0);
433 	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
434 
435 	TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_array_async (connection,
436 	                                                                      sparql,
437 	                                                                      sparql_length,
438 	                                                                      cancellable,
439 	                                                                      callback,
440 	                                                                      user_data);
441 }
442 
443 /**
444  * tracker_sparql_connection_update_array_finish:
445  * @connection: a #TrackerSparqlConnection
446  * @res: a #GAsyncResult with the result of the operation
447  * @error: #GError for error reporting.
448  *
449  * Finishes the asynchronous SPARQL update_array operation.
450  *
451  * Returns: #TRUE if there were no errors.
452  */
453 gboolean
tracker_sparql_connection_update_array_finish(TrackerSparqlConnection * connection,GAsyncResult * res,GError ** error)454 tracker_sparql_connection_update_array_finish (TrackerSparqlConnection  *connection,
455                                                GAsyncResult             *res,
456                                                GError                  **error)
457 {
458 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
459 	g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
460 	g_return_val_if_fail (!error || !*error, FALSE);
461 
462 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_array_finish (connection,
463 	                                                                              res,
464 	                                                                              error);
465 
466 }
467 
468 /**
469  * tracker_sparql_connection_update_blank:
470  * @connection: a #TrackerSparqlConnection
471  * @sparql: string containing the SPARQL update query
472  * @cancellable: a #GCancellable used to cancel the operation
473  * @error: #GError for error reporting.
474  *
475  * Executes a SPARQL update and returns the URNs of the generated nodes,
476  * if any. The API call is completely synchronous, so it may block.
477  *
478  * The @sparql query should be built with #TrackerResource, or
479  * its parts correctly escaped using tracker_sparql_escape_string(),
480  * otherwise SPARQL injection is possible.
481  *
482  * Returns: a #GVariant with the generated URNs, which should be freed with
483  * g_variant_unref() when no longer used.
484  */
485 GVariant *
tracker_sparql_connection_update_blank(TrackerSparqlConnection * connection,const gchar * sparql,GCancellable * cancellable,GError ** error)486 tracker_sparql_connection_update_blank (TrackerSparqlConnection  *connection,
487                                         const gchar              *sparql,
488                                         GCancellable             *cancellable,
489                                         GError                  **error)
490 {
491 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
492 	g_return_val_if_fail (sparql != NULL, NULL);
493 	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
494 	g_return_val_if_fail (!error || !*error, NULL);
495 
496 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_blank (connection,
497 	                                                                       sparql,
498 	                                                                       cancellable,
499 	                                                                       error);
500 }
501 
502 /**
503  * tracker_sparql_connection_update_blank_async:
504  * @connection: a #TrackerSparqlConnection
505  * @sparql: string containing the SPARQL update query
506  * @cancellable: a #GCancellable used to cancel the operation
507  * @callback: user-defined #GAsyncReadyCallback to be called when
508  *            asynchronous operation is finished.
509  * @user_data: user-defined data to be passed to @callback
510  *
511  * Executes asynchronously a SPARQL update.
512  */
513 void
tracker_sparql_connection_update_blank_async(TrackerSparqlConnection * connection,const gchar * sparql,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)514 tracker_sparql_connection_update_blank_async (TrackerSparqlConnection *connection,
515                                               const gchar             *sparql,
516                                               GCancellable            *cancellable,
517                                               GAsyncReadyCallback      callback,
518                                               gpointer                 user_data)
519 {
520 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
521 	g_return_if_fail (sparql != NULL);
522 	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
523 
524 	TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_blank_async (connection,
525 	                                                                      sparql,
526 	                                                                      cancellable,
527 	                                                                      callback,
528 	                                                                      user_data);
529 }
530 
531 /**
532  * tracker_sparql_connection_update_blank_finish:
533  * @connection: a #TrackerSparqlConnection
534  * @res: a #GAsyncResult with the result of the operation
535  * @error: #GError for error reporting.
536  *
537  * Finishes the asynchronous SPARQL update operation, and returns
538  * the URNs of the generated nodes, if any.
539  *
540  * Returns: a #GVariant with the generated URNs, which should be freed with
541  * g_variant_unref() when no longer used.
542  */
543 GVariant *
tracker_sparql_connection_update_blank_finish(TrackerSparqlConnection * connection,GAsyncResult * res,GError ** error)544 tracker_sparql_connection_update_blank_finish (TrackerSparqlConnection  *connection,
545                                                GAsyncResult             *res,
546                                                GError                  **error)
547 {
548 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
549 	g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
550 	g_return_val_if_fail (!error || !*error, NULL);
551 
552 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_blank_finish (connection,
553 	                                                                        res,
554 	                                                                        error);
555 }
556 
557 /**
558  * tracker_sparql_connection_update_resource:
559  * @connection: a #TrackerSparqlConnection
560  * @graph: (nullable): RDF graph where the resource should be inserted/updated, or %NULL for the default graph
561  * @resource: a #TrackerResource
562  * @cancellable: (nullable): a #GCancellable, or %NULL
563  * @error: pointer to a #GError, or %NULL
564  *
565  * Inserts a resource as described by @resource, on the graph described by @graph.
566  * This operation blocks until done.
567  *
568  * Returns: #TRUE if there were no errors.
569  *
570  * Since: 3.1
571  **/
572 gboolean
tracker_sparql_connection_update_resource(TrackerSparqlConnection * connection,const gchar * graph,TrackerResource * resource,GCancellable * cancellable,GError ** error)573 tracker_sparql_connection_update_resource (TrackerSparqlConnection  *connection,
574                                            const gchar              *graph,
575                                            TrackerResource          *resource,
576                                            GCancellable             *cancellable,
577                                            GError                  **error)
578 {
579 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
580 	g_return_val_if_fail (TRACKER_IS_RESOURCE (resource), FALSE);
581 	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
582 	g_return_val_if_fail (!error || !*error, FALSE);
583 
584 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource (connection,
585 	                                                                          graph,
586 	                                                                          resource,
587 	                                                                          cancellable,
588 	                                                                          error);
589 }
590 
591 /**
592  * tracker_sparql_connection_update_resource_async:
593  * @connection: a #TrackerSparqlConnection
594  * @graph: (nullable): RDF graph where the resource should be inserted/updated, or %NULL for the default graph
595  * @resource: a #TrackerResource
596  * @cancellable: (nullable): a #GCancellable, or %NULL
597  * @callback: the #GAsyncReadyCallback called when the operation completes
598  * @user_data: data passed to @callback
599  *
600  * Inserts a resource as described by @resource, on the graph described by @graph.
601  * This operation is executed asynchronously, when finished @callback will be
602  * executed.
603  *
604  * Since: 3.1
605  **/
606 void
tracker_sparql_connection_update_resource_async(TrackerSparqlConnection * connection,const gchar * graph,TrackerResource * resource,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)607 tracker_sparql_connection_update_resource_async (TrackerSparqlConnection *connection,
608                                                  const gchar             *graph,
609                                                  TrackerResource         *resource,
610                                                  GCancellable            *cancellable,
611                                                  GAsyncReadyCallback      callback,
612                                                  gpointer                 user_data)
613 {
614 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
615 	g_return_if_fail (TRACKER_IS_RESOURCE (resource));
616 	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
617 	g_return_if_fail (callback != NULL);
618 
619 	TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource_async (connection,
620 	                                                                         graph,
621 	                                                                         resource,
622 	                                                                         cancellable,
623 	                                                                         callback,
624 	                                                                         user_data);
625 }
626 
627 /**
628  * tracker_sparql_connection_update_resource_finish:
629  * @connection: a #TrackerSparqlConnection
630  * @res: a #GAsyncResult with the result of the operation
631  * @error: pointer to a #GError, or %NULL
632  *
633  * Finishes a tracker_sparql_connection_update_resource_async() operation.
634  *
635  * Returns: #TRUE if there were no errors.
636  *
637  * Since: 3.1
638  **/
639 gboolean
tracker_sparql_connection_update_resource_finish(TrackerSparqlConnection * connection,GAsyncResult * res,GError ** error)640 tracker_sparql_connection_update_resource_finish (TrackerSparqlConnection  *connection,
641                                                   GAsyncResult             *res,
642                                                   GError                  **error)
643 {
644 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
645 	g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
646 	g_return_val_if_fail (!error || !*error, FALSE);
647 
648 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource_finish (connection,
649 	                                                                                 res,
650 	                                                                                 error);
651 }
652 
653 /**
654  * tracker_sparql_connection_get_namespace_manager:
655  * @connection: a #TrackerSparqlConnection
656  *
657  * Retrieves a #TrackerNamespaceManager that contains all
658  * prefixes in the ontology of @connection.
659  *
660  * Returns: (transfer none): a #TrackerNamespaceManager for this
661  * connection. This object is owned by @connection and must not be freed.
662  */
663 TrackerNamespaceManager *
tracker_sparql_connection_get_namespace_manager(TrackerSparqlConnection * connection)664 tracker_sparql_connection_get_namespace_manager (TrackerSparqlConnection *connection)
665 {
666 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
667 
668 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->get_namespace_manager (connection);
669 }
670 
671 /**
672  * tracker_sparql_connection_query_statement:
673  * @connection: a #TrackerSparqlConnection
674  * @sparql: the SPARQL query
675  * @cancellable: a #GCancellable used to cancel the operation, or %NULL
676  * @error: a #TrackerSparqlError or %NULL if no error occured
677  *
678  * Prepares the given @sparql as a #TrackerSparqlStatement.
679  *
680  * Returns: (transfer full) (nullable): a prepared statement
681  */
682 TrackerSparqlStatement *
tracker_sparql_connection_query_statement(TrackerSparqlConnection * connection,const gchar * sparql,GCancellable * cancellable,GError ** error)683 tracker_sparql_connection_query_statement (TrackerSparqlConnection  *connection,
684                                            const gchar              *sparql,
685                                            GCancellable             *cancellable,
686                                            GError                  **error)
687 {
688 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
689 	g_return_val_if_fail (sparql != NULL, NULL);
690 	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
691 	g_return_val_if_fail (!error || !*error, NULL);
692 
693 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query_statement (connection,
694 	                                                                          sparql,
695 	                                                                          cancellable,
696 	                                                                          error);
697 }
698 
699 /**
700  * tracker_sparql_connection_create_notifier:
701  * @connection: a #TrackerSparqlConnection
702  *
703  * Creates a new #TrackerNotifier to notify about changes in @connection.
704  * See #TrackerNotifier documentation for information about how to use this
705  * object.
706  *
707  * Returns: (transfer full): a newly created notifier. Free with g_object_unref()
708  *          when no longer needed.
709  **/
710 TrackerNotifier *
tracker_sparql_connection_create_notifier(TrackerSparqlConnection * connection)711 tracker_sparql_connection_create_notifier (TrackerSparqlConnection *connection)
712 {
713 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
714 
715 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->create_notifier (connection);
716 }
717 
718 /**
719  * tracker_sparql_connection_close:
720  * @connection: a #TrackerSparqlConnection
721  *
722  * Closes a SPARQL connection. No other API calls than g_object_unref()
723  * should happen after this call.
724  *
725  * This call is blocking. All pending updates will be flushed, and the
726  * store databases will be closed orderly. All ongoing SELECT queries
727  * will be cancelled. Notifiers will no longer emit events.
728  *
729  * Since: 3.0
730  */
731 void
tracker_sparql_connection_close(TrackerSparqlConnection * connection)732 tracker_sparql_connection_close (TrackerSparqlConnection *connection)
733 {
734 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
735 
736 	TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->close (connection);
737 }
738 
739 /**
740  * tracker_sparql_connection_close_async:
741  * @connection: a #TrackerSparqlConnection
742  * @cancellable: a #GCancellable, or %NULL
743  * @callback: user-defined #GAsyncReadyCallback to be called when
744  *            asynchronous operation is finished.
745  * @user_data: user-defined data to be passed to @callback
746  *
747  * Closes a connection asynchronously. No other API calls than g_object_unref()
748  * should happen after this call. See tracker_sparql_connection_close() for more
749  * information.
750  *
751  * Since: 3.0
752  **/
753 void
tracker_sparql_connection_close_async(TrackerSparqlConnection * connection,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)754 tracker_sparql_connection_close_async (TrackerSparqlConnection *connection,
755                                        GCancellable            *cancellable,
756                                        GAsyncReadyCallback      callback,
757                                        gpointer                 user_data)
758 {
759 	g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
760 
761 	TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->close_async (connection,
762 	                                                               cancellable,
763 	                                                               callback,
764 	                                                               user_data);
765 }
766 
767 /**
768  * tracker_sparql_connection_close_finish:
769  * @connection: a #TrackerSparqlConnection
770  * @res: the #GAsyncResult
771  * @error: pointer to a #GError
772  *
773  * Finishes the asynchronous connection close.
774  *
775  * Returns: %FALSE if some error occurred, %TRUE otherwise
776  *
777  * Since: 3.0
778  **/
779 gboolean
tracker_sparql_connection_close_finish(TrackerSparqlConnection * connection,GAsyncResult * res,GError ** error)780 tracker_sparql_connection_close_finish (TrackerSparqlConnection  *connection,
781                                         GAsyncResult             *res,
782                                         GError                  **error)
783 {
784 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
785 
786 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->close_finish (connection,
787 	                                                                       res, error);
788 }
789 
790 /**
791  * tracker_sparql_connection_create_batch:
792  * @connection: a #TrackerSparqlConnection
793  *
794  * Creates a new batch to store and execute update commands. If the connection
795  * is readonly or cannot issue SPARQL updates, %NULL will be returned.
796  *
797  * Returns: (transfer full): (nullable): A new #TrackerBatch
798  **/
799 TrackerBatch *
tracker_sparql_connection_create_batch(TrackerSparqlConnection * connection)800 tracker_sparql_connection_create_batch (TrackerSparqlConnection *connection)
801 {
802 	g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
803 
804 	if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->create_batch)
805 		return NULL;
806 
807 	return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->create_batch (connection);
808 }
809