Coverage Report

Created: 2026-05-16 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tinysparql/src/libtinysparql/tracker-connection.c
Line
Count
Source
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
 * TrackerSparqlConnection:
22
 *
23
 * `TrackerSparqlConnection` holds a connection to a RDF triple store.
24
 *
25
 * This triple store may be of three types:
26
 *
27
 *  - Local to the process, created through [ctor@SparqlConnection.new].
28
 *  - A HTTP SPARQL endpoint over the network, created through
29
 *    [ctor@SparqlConnection.remote_new]
30
 *  - A DBus SPARQL endpoint owned by another process in the same machine, created
31
 *    through [ctor@SparqlConnection.bus_new]
32
 *
33
 * When creating a local triple store, it is required to give details about its
34
 * structure. This is done by passing a location to an ontology, see more
35
 * on how are [ontologies defined](ontologies.html). A local database may be
36
 * stored in a filesystem location, or it may reside in memory.
37
 *
38
 * A `TrackerSparqlConnection` is private to the calling process, it can be
39
 * exposed to other hosts/processes via a [class@Endpoint], see
40
 * [ctor@EndpointDBus.new] and [ctor@EndpointHttp.new].
41
 *
42
 * When issuing SPARQL queries and updates, it is recommended that these are
43
 * created through [class@SparqlStatement] to avoid the SPARQL
44
 * injection class of bugs, see [method@SparqlConnection.query_statement]
45
 * and [method@SparqlConnection.update_statement]. For SPARQL updates
46
 * it is also possible to use a "builder" approach to generate RDF data, see
47
 * [class@Resource]. It is also possible to create [class@SparqlStatement]
48
 * objects for SPARQL queries and updates from SPARQL strings embedded in a
49
 * [struct@Gio.Resource], see [method@SparqlConnection.load_statement_from_gresource].
50
 *
51
 * To get the best performance, it is recommended that SPARQL updates are clustered
52
 * through [class@Batch].
53
 *
54
 * `TrackerSparqlConnection` also offers a number of methods for the simple cases,
55
 * [method@SparqlConnection.query] may be used when there is a SPARQL
56
 * query string directly available, and the [method@SparqlConnection.update]
57
 * family of functions may be used for one-off updates. All functions have asynchronous
58
 * variants.
59
 *
60
 * When a SPARQL query is executed, a [class@SparqlCursor] will be obtained
61
 * to iterate over the query results.
62
 *
63
 * Depending on the ontology definition, `TrackerSparqlConnection` may emit
64
 * notifications whenever resources of certain types get insert, modified or
65
 * deleted from the triple store (see [nrl:notify](nrl-ontology.html#nrl:notify).
66
 * These notifications can be handled via a [class@Notifier] obtained with
67
 * [method@SparqlConnection.create_notifier].
68
 *
69
 * After done with a connection, it is recommended to call [method@SparqlConnection.close]
70
 * or [method@SparqlConnection.close_async] explicitly to cleanly close the
71
 * connection and prevent consistency checks on future runs. The triple store
72
 * connection will be implicitly closed when the `TrackerSparqlConnection` object
73
 * is disposed.
74
 *
75
 * A `TrackerSparqlConnection` may be used from multiple threads, asynchronous
76
 * updates are executed sequentially on arrival order, asynchronous
77
 * queries are dispatched in a thread pool.
78
 *
79
 * If you ever have the need to procedurally compose SPARQL query strings, consider
80
 * the use of [func@sparql_escape_string] for literal strings and
81
 * the [func@sparql_escape_uri] family of functions for URIs.
82
 */
83
#include "config.h"
84
85
#include "tracker-connection.h"
86
#include "tracker-private.h"
87
#include "tracker-debug.h"
88
89
#include "bus/tracker-bus.h"
90
#include "direct/tracker-direct.h"
91
#include "remote/tracker-remote.h"
92
93
typedef struct
94
{
95
  gboolean closing;
96
} TrackerSparqlConnectionPrivate;
97
98
24.9k
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (TrackerSparqlConnection, tracker_sparql_connection,
99
24.9k
                                     G_TYPE_OBJECT)
100
24.9k
101
24.9k
static void
102
24.9k
tracker_sparql_connection_init (TrackerSparqlConnection *connection)
103
24.9k
{
104
1.23k
}
105
106
static void
107
tracker_sparql_connection_dispose (GObject *object)
108
1.23k
{
109
1.23k
  tracker_sparql_connection_close (TRACKER_SPARQL_CONNECTION (object));
110
111
1.23k
  G_OBJECT_CLASS (tracker_sparql_connection_parent_class)->dispose (object);
112
1.23k
}
113
114
static void
115
tracker_sparql_connection_class_init (TrackerSparqlConnectionClass *klass)
116
1
{
117
1
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
118
119
1
  object_class->dispose = tracker_sparql_connection_dispose;
120
121
  /* Initialize debug flags */
122
1
  tracker_get_debug_flags ();
123
124
  /* Initialize GResources */
125
1
  tracker_ensure_resources ();
126
1
}
127
128
gboolean
129
tracker_sparql_connection_lookup_dbus_service (TrackerSparqlConnection  *connection,
130
                                               const gchar              *dbus_name,
131
                                               const gchar              *dbus_path,
132
                                               gchar                   **name,
133
                                               gchar                   **path)
134
0
{
135
0
  TrackerSparqlConnectionClass *connection_class;
136
137
0
  connection_class = TRACKER_SPARQL_CONNECTION_GET_CLASS (connection);
138
0
  if (!connection_class->lookup_dbus_service)
139
0
    return FALSE;
140
141
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->lookup_dbus_service (connection,
142
0
                                                                                dbus_name,
143
0
                                                                                dbus_path,
144
0
                                                                                name,
145
0
                                                                                path);
146
0
}
147
148
gboolean
149
tracker_sparql_connection_set_error_on_closed (TrackerSparqlConnection  *connection,
150
                                               GError                  **error)
151
7.06k
{
152
7.06k
  TrackerSparqlConnectionPrivate *priv =
153
7.06k
    tracker_sparql_connection_get_instance_private (connection);
154
155
7.06k
  if (priv->closing) {
156
0
    g_set_error (error,
157
0
                 G_IO_ERROR,
158
0
                 G_IO_ERROR_CONNECTION_CLOSED,
159
0
                 "Connection is closed");
160
0
    return TRUE;
161
0
  }
162
163
7.06k
  return FALSE;
164
7.06k
}
165
166
gboolean
167
tracker_sparql_connection_report_async_error_on_closed (TrackerSparqlConnection *connection,
168
                                                        GAsyncReadyCallback      callback,
169
                                                        gpointer                 user_data)
170
0
{
171
0
  TrackerSparqlConnectionPrivate *priv =
172
0
    tracker_sparql_connection_get_instance_private (connection);
173
174
0
  if (priv->closing) {
175
0
    g_task_report_new_error (connection, callback, user_data, NULL,
176
0
                             G_IO_ERROR,
177
0
                             G_IO_ERROR_CONNECTION_CLOSED,
178
0
                             "Connection is closed");
179
0
    return TRUE;
180
0
  }
181
182
0
  return FALSE;
183
0
}
184
185
/**
186
 * tracker_sparql_connection_query:
187
 * @connection: A `TrackerSparqlConnection`
188
 * @sparql: String containing the SPARQL query
189
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
190
 * @error: Error location
191
 *
192
 * Executes a SPARQL query on @connection.
193
 *
194
 * This method is synchronous and will block until the query
195
 * is executed. See [method@SparqlConnection.query_async]
196
 * for an asynchronous variant.
197
 *
198
 * If the query is partially built from user input or other
199
 * untrusted sources, special care is required about possible
200
 * SPARQL injection. In order to avoid it entirely, it is recommended
201
 * to use [class@SparqlStatement]. The function
202
 * [func@sparql_escape_string] exists as a last resort,
203
 * but its use is not recommended.
204
 *
205
 * Returns: (transfer full): a [class@SparqlCursor] with the results.
206
 */
207
TrackerSparqlCursor *
208
tracker_sparql_connection_query (TrackerSparqlConnection  *connection,
209
                                 const gchar              *sparql,
210
                                 GCancellable             *cancellable,
211
                                 GError                  **error)
212
0
{
213
0
  TrackerSparqlCursor *cursor;
214
215
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
216
0
  g_return_val_if_fail (sparql != NULL, NULL);
217
0
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
218
0
  g_return_val_if_fail (!error || !*error, NULL);
219
220
0
  if (tracker_sparql_connection_set_error_on_closed (connection, error))
221
0
    return NULL;
222
223
0
  cursor = TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query (connection,
224
0
                                                                    sparql,
225
0
                                                                    cancellable,
226
0
                                                                    error);
227
0
  if (cursor)
228
0
    tracker_sparql_cursor_set_connection (cursor, connection);
229
230
0
  return cursor;
231
0
}
232
233
/**
234
 * tracker_sparql_connection_query_async:
235
 * @connection: A `TrackerSparqlConnection`
236
 * @sparql: String containing the SPARQL query
237
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
238
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
239
 *            the asynchronous operation is finished.
240
 * @user_data: User-defined data to be passed to @callback
241
 *
242
 * Executes asynchronously a SPARQL query on @connection
243
 *
244
 * If the query is partially built from user input or other
245
 * untrusted sources, special care is required about possible
246
 * SPARQL injection. In order to avoid it entirely, it is recommended
247
 * to use [class@SparqlStatement]. The function
248
 * [func@sparql_escape_string] exists as a last resort,
249
 * but its use is not recommended.
250
 */
251
void
252
tracker_sparql_connection_query_async (TrackerSparqlConnection *connection,
253
                                       const gchar             *sparql,
254
                                       GCancellable            *cancellable,
255
                                       GAsyncReadyCallback      callback,
256
                                       gpointer                 user_data)
257
0
{
258
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
259
0
  g_return_if_fail (sparql != NULL);
260
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
261
262
0
  if (tracker_sparql_connection_report_async_error_on_closed (connection,
263
0
                                                              callback,
264
0
                                                              user_data))
265
0
    return;
266
267
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query_async (connection,
268
0
                                                                 sparql,
269
0
                                                                 cancellable,
270
0
                                                                 callback,
271
0
                                                                 user_data);
272
0
}
273
274
/**
275
 * tracker_sparql_connection_query_finish:
276
 * @connection: A `TrackerSparqlConnection`
277
 * @res: A [type@Gio.AsyncResult] with the result of the operation
278
 * @error: Error location
279
 *
280
 * Finishes the operation started with [method@SparqlConnection.query_async].
281
 *
282
 * Returns: (transfer full): a [class@SparqlCursor] with the results.
283
 */
284
TrackerSparqlCursor *
285
tracker_sparql_connection_query_finish (TrackerSparqlConnection  *connection,
286
                                        GAsyncResult             *res,
287
                                        GError                  **error)
288
0
{
289
0
  TrackerSparqlCursor *cursor;
290
291
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
292
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
293
0
  g_return_val_if_fail (!error || !*error, NULL);
294
295
0
  cursor = TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query_finish (connection,
296
0
                                                                           res,
297
0
                                                                           error);
298
0
  if (cursor)
299
0
    tracker_sparql_cursor_set_connection (cursor, connection);
300
301
0
  return cursor;
302
0
}
303
304
/**
305
 * tracker_sparql_connection_update:
306
 * @connection: A `TrackerSparqlConnection`
307
 * @sparql: String containing the SPARQL update query
308
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
309
 * @error: Error location
310
 *
311
 * Executes a SPARQL update on @connection.
312
 *
313
 * This method is synchronous and will block until the update
314
 * is finished. See [method@SparqlConnection.update_async]
315
 * for an asynchronous variant.
316
 *
317
 * It is recommented to consider the usage of [class@Batch]
318
 * to cluster database updates. Frequent isolated SPARQL updates
319
 * through this method will have a degraded performance in comparison.
320
 *
321
 * If the query is partially built from user input or other
322
 * untrusted sources, special care is required about possible
323
 * SPARQL injection. In order to avoid it entirely, it is recommended
324
 * to use [class@SparqlStatement], or to build the SPARQL
325
 * input through [class@Resource]. The function
326
 * [func@sparql_escape_string] exists as a last resort,
327
 * but its use is not recommended.
328
 */
329
void
330
tracker_sparql_connection_update (TrackerSparqlConnection  *connection,
331
                                  const gchar              *sparql,
332
                                  GCancellable             *cancellable,
333
                                  GError                  **error)
334
0
{
335
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
336
0
  g_return_if_fail (sparql != NULL);
337
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
338
0
  g_return_if_fail (!error || !*error);
339
340
0
  if (tracker_sparql_connection_set_error_on_closed (connection, error))
341
0
    return;
342
343
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update (connection,
344
0
                                                            sparql,
345
0
                                                            cancellable,
346
0
                                                            error);
347
0
}
348
349
/**
350
 * tracker_sparql_connection_update_async:
351
 * @connection: A `TrackerSparqlConnection`
352
 * @sparql: String containing the SPARQL update query
353
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
354
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
355
 *            the asynchronous operation is finished.
356
 * @user_data: User-defined data to be passed to @callback
357
 *
358
 * Executes asynchronously a SPARQL update.
359
 *
360
 * It is recommented to consider the usage of [class@Batch]
361
 * to cluster database updates. Frequent isolated SPARQL updates
362
 * through this method will have a degraded performance in comparison.
363
 *
364
 * If the query is partially built from user input or other
365
 * untrusted sources, special care is required about possible
366
 * SPARQL injection. In order to avoid it entirely, it is recommended
367
 * to use [class@SparqlStatement], or to build the SPARQL
368
 * input through [class@Resource]. The function
369
 * [func@sparql_escape_string] exists as a last resort,
370
 * but its use is not recommended.
371
 */
372
void
373
tracker_sparql_connection_update_async (TrackerSparqlConnection *connection,
374
                                        const gchar             *sparql,
375
                                        GCancellable            *cancellable,
376
                                        GAsyncReadyCallback      callback,
377
                                        gpointer                 user_data)
378
0
{
379
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
380
0
  g_return_if_fail (sparql != NULL);
381
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
382
383
0
  if (tracker_sparql_connection_report_async_error_on_closed (connection,
384
0
                                                              callback,
385
0
                                                              user_data))
386
0
    return;
387
388
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_async (connection,
389
0
                                                                  sparql,
390
0
                                                                  cancellable,
391
0
                                                                  callback,
392
0
                                                                  user_data);
393
0
}
394
395
/**
396
 * tracker_sparql_connection_update_finish:
397
 * @connection: A `TrackerSparqlConnection`
398
 * @res: A [type@Gio.AsyncResult] with the result of the operation
399
 * @error: Error location
400
 *
401
 * Finishes the operation started with [method@SparqlConnection.update_async].
402
 */
403
void
404
tracker_sparql_connection_update_finish (TrackerSparqlConnection  *connection,
405
                                         GAsyncResult             *res,
406
                                         GError                  **error)
407
0
{
408
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
409
0
  g_return_if_fail (G_IS_ASYNC_RESULT (res));
410
0
  g_return_if_fail (!error || !*error);
411
412
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_finish (connection,
413
0
                                                                   res,
414
0
                                                                   error);
415
0
}
416
417
/**
418
 * tracker_sparql_connection_update_array_async:
419
 * @connection: A `TrackerSparqlConnection`
420
 * @sparql: An array of strings containing the SPARQL update queries
421
 * @sparql_length: The amount of strings you pass as @sparql
422
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
423
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
424
 *            the asynchronous operation is finished.
425
 * @user_data: User-defined data to be passed to @callback
426
 *
427
 * Executes asynchronously an array of SPARQL updates. All updates in the
428
 * array are handled within a single transaction.
429
 *
430
 * If the query is partially built from user input or other
431
 * untrusted sources, special care is required about possible
432
 * SPARQL injection. In order to avoid it entirely, it is recommended
433
 * to use [class@SparqlStatement], or to build the SPARQL
434
 * input through [class@Resource]. The function
435
 * [func@sparql_escape_string] exists as a last resort,
436
 * but its use is not recommended.
437
 */
438
void
439
tracker_sparql_connection_update_array_async (TrackerSparqlConnection  *connection,
440
                                              gchar                   **sparql,
441
                                              gint                      sparql_length,
442
                                              GCancellable             *cancellable,
443
                                              GAsyncReadyCallback       callback,
444
                                              gpointer                  user_data)
445
0
{
446
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
447
0
  g_return_if_fail (sparql != NULL || sparql_length == 0);
448
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
449
450
0
  if (tracker_sparql_connection_report_async_error_on_closed (connection,
451
0
                                                              callback,
452
0
                                                              user_data))
453
0
    return;
454
455
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_array_async) {
456
0
    g_task_report_new_error (G_OBJECT (connection), callback, user_data,
457
0
                             connection,
458
0
                             TRACKER_SPARQL_ERROR,
459
0
                             TRACKER_SPARQL_ERROR_UNSUPPORTED,
460
0
                             "Updates unsupported by this connection");
461
0
    return;
462
0
  }
463
464
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_array_async (connection,
465
0
                                                                        sparql,
466
0
                                                                        sparql_length,
467
0
                                                                        cancellable,
468
0
                                                                        callback,
469
0
                                                                        user_data);
470
0
}
471
472
/**
473
 * tracker_sparql_connection_update_array_finish:
474
 * @connection: A `TrackerSparqlConnection`
475
 * @res: A [type@Gio.AsyncResult] with the result of the operation
476
 * @error: Error location
477
 *
478
 * Finishes the operation started with [method@SparqlConnection.update_array_async].
479
 *
480
 * Returns: #TRUE if there were no errors.
481
 */
482
gboolean
483
tracker_sparql_connection_update_array_finish (TrackerSparqlConnection  *connection,
484
                                               GAsyncResult             *res,
485
                                               GError                  **error)
486
0
{
487
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
488
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
489
0
  g_return_val_if_fail (!error || !*error, FALSE);
490
491
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_array_finish)
492
0
    return g_task_propagate_boolean (G_TASK (res), error);
493
494
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_array_finish (connection,
495
0
                                                                                res,
496
0
                                                                                error);
497
498
0
}
499
500
/**
501
 * tracker_sparql_connection_update_blank:
502
 * @connection: A `TrackerSparqlConnection`
503
 * @sparql: String containing the SPARQL update query
504
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
505
 * @error: Error location
506
 *
507
 * Executes a SPARQL update and returns the names of the generated blank nodes.
508
 *
509
 * This method is synchronous and will block until the update
510
 * is finished. See [method@SparqlConnection.update_blank_async]
511
 * for an asynchronous variant.
512
 *
513
 * The @sparql query should be built with [class@Resource], or
514
 * its parts correctly escaped using [func@sparql_escape_string],
515
 * otherwise SPARQL injection is possible.
516
 *
517
 * The format string of the `GVariant` is `aaa{ss}` (an array of an array
518
 * of dictionaries). The first array represents each INSERT that may exist in
519
 * the SPARQL string. The second array represents each new node for a given
520
 * WHERE clause. The last array holds a string pair with the blank node name
521
 * (e.g. `foo` for the blank node `_:foo`) and the URN that was generated for
522
 * it. For most updates the first two outer arrays will only contain one item.
523
 *
524
 * Returns: a [type@GLib.Variant] with the generated URNs.
525
 *
526
 * Deprecated: 3.5: This function makes the expectation that blank nodes have
527
 * a durable name that persist. The SPARQL and RDF specs define a much more
528
 * reduced scope for blank node labels. This function advises a behavior that
529
 * goes against that reduced scope, and will directly make the returned values
530
 * meaningless if the #TRACKER_SPARQL_CONNECTION_FLAGS_ANONYMOUS_BNODES flag
531
 * is defined in the connection.
532
 *
533
 * Users that want names generated for them, should look for other methods
534
 * (e.g. IRIs containing UUIDv4 strings).
535
 */
536
GVariant *
537
tracker_sparql_connection_update_blank (TrackerSparqlConnection  *connection,
538
                                        const gchar              *sparql,
539
                                        GCancellable             *cancellable,
540
                                        GError                  **error)
541
0
{
542
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
543
0
  g_return_val_if_fail (sparql != NULL, NULL);
544
0
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
545
0
  g_return_val_if_fail (!error || !*error, NULL);
546
547
0
  if (tracker_sparql_connection_set_error_on_closed (connection, error))
548
0
    return NULL;
549
550
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_blank (connection,
551
0
                                                                         sparql,
552
0
                                                                         cancellable,
553
0
                                                                         error);
554
0
}
555
556
/**
557
 * tracker_sparql_connection_update_blank_async:
558
 * @connection: A `TrackerSparqlConnection`
559
 * @sparql: String containing the SPARQL update query
560
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
561
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
562
 *            the asynchronous operation is finished.
563
 * @user_data: User-defined data to be passed to @callback
564
 *
565
 *
566
 * Executes asynchronously a SPARQL update and returns the names of the generated blank nodes.
567
 *
568
 * See the [method@SparqlConnection.update_blank] documentation to
569
 * learn the differences with [method@SparqlConnection.update].
570
 *
571
 * Deprecated: 3.5: See [method@SparqlConnection.update_blank].
572
 */
573
void
574
tracker_sparql_connection_update_blank_async (TrackerSparqlConnection *connection,
575
                                              const gchar             *sparql,
576
                                              GCancellable            *cancellable,
577
                                              GAsyncReadyCallback      callback,
578
                                              gpointer                 user_data)
579
0
{
580
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
581
0
  g_return_if_fail (sparql != NULL);
582
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
583
584
0
  if (tracker_sparql_connection_report_async_error_on_closed (connection,
585
0
                                                              callback,
586
0
                                                              user_data))
587
0
    return;
588
589
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_blank_async (connection,
590
0
                                                                        sparql,
591
0
                                                                        cancellable,
592
0
                                                                        callback,
593
0
                                                                        user_data);
594
0
}
595
596
/**
597
 * tracker_sparql_connection_update_blank_finish:
598
 * @connection: A `TrackerSparqlConnection`
599
 * @res: A [type@Gio.AsyncResult] with the result of the operation
600
 * @error: Error location
601
 *
602
 * Finishes the operation started with [method@SparqlConnection.update_blank_async].
603
 *
604
 * This method returns the URNs of the generated nodes, if any. See the
605
 * [method@SparqlConnection.update_blank] documentation for the interpretation
606
 * of the returned [type@GLib.Variant].
607
 *
608
 * Returns: a [type@GLib.Variant] with the generated URNs.
609
 *
610
 * Deprecated: 3.5: See [method@SparqlConnection.update_blank].
611
 */
612
GVariant *
613
tracker_sparql_connection_update_blank_finish (TrackerSparqlConnection  *connection,
614
                                               GAsyncResult             *res,
615
                                               GError                  **error)
616
0
{
617
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
618
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
619
0
  g_return_val_if_fail (!error || !*error, NULL);
620
621
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_blank_finish (connection,
622
0
                                                                          res,
623
0
                                                                          error);
624
0
}
625
626
/**
627
 * tracker_sparql_connection_update_resource:
628
 * @connection: A `TrackerSparqlConnection`
629
 * @graph: (nullable): RDF graph where the resource should be inserted/updated, or %NULL for the default graph
630
 * @resource: A [class@Resource]
631
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
632
 * @error: Error location
633
 *
634
 * Inserts a resource as described by @resource on the given @graph.
635
 *
636
 * This method is synchronous and will block until the update
637
 * is finished. See [method@SparqlConnection.update_resource_async]
638
 * for an asynchronous variant.
639
 *
640
 * It is recommented to consider the usage of [class@Batch]
641
 * to cluster database updates. Frequent isolated SPARQL updates
642
 * through this method will have a degraded performance in comparison.
643
 *
644
 * Returns: #TRUE if there were no errors.
645
 *
646
 * Since: 3.1
647
 **/
648
gboolean
649
tracker_sparql_connection_update_resource (TrackerSparqlConnection  *connection,
650
                                           const gchar              *graph,
651
                                           TrackerResource          *resource,
652
                                           GCancellable             *cancellable,
653
                                           GError                  **error)
654
0
{
655
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
656
0
  g_return_val_if_fail (TRACKER_IS_RESOURCE (resource), FALSE);
657
0
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
658
0
  g_return_val_if_fail (!error || !*error, FALSE);
659
660
0
  if (tracker_sparql_connection_set_error_on_closed (connection, error))
661
0
    return FALSE;
662
663
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource) {
664
0
    g_set_error (error,
665
0
                 TRACKER_SPARQL_ERROR,
666
0
                 TRACKER_SPARQL_ERROR_UNSUPPORTED,
667
0
                 "Updates unsupported by this connection");
668
0
    return FALSE;
669
0
  }
670
671
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource (connection,
672
0
                                                                            graph,
673
0
                                                                            resource,
674
0
                                                                            cancellable,
675
0
                                                                            error);
676
0
}
677
678
/**
679
 * tracker_sparql_connection_update_resource_async:
680
 * @connection: A `TrackerSparqlConnection`
681
 * @graph: (nullable): RDF graph where the resource should be inserted/updated, or %NULL for the default graph
682
 * @resource: A [class@Resource]
683
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
684
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
685
 *            the asynchronous operation is finished.
686
 * @user_data: User-defined data to be passed to @callback
687
 *
688
 * Inserts asynchronously a resource as described by @resource on the given @graph.
689
 *
690
 * It is recommented to consider the usage of [class@Batch]
691
 * to cluster database updates. Frequent isolated SPARQL updates
692
 * through this method will have a degraded performance in comparison.
693
 *
694
 * Since: 3.1
695
 **/
696
void
697
tracker_sparql_connection_update_resource_async (TrackerSparqlConnection *connection,
698
                                                 const gchar             *graph,
699
                                                 TrackerResource         *resource,
700
                                                 GCancellable            *cancellable,
701
                                                 GAsyncReadyCallback      callback,
702
                                                 gpointer                 user_data)
703
0
{
704
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
705
0
  g_return_if_fail (TRACKER_IS_RESOURCE (resource));
706
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
707
0
  g_return_if_fail (callback != NULL);
708
709
0
  if (tracker_sparql_connection_report_async_error_on_closed (connection,
710
0
                                                              callback,
711
0
                                                              user_data))
712
0
    return;
713
714
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource_async) {
715
0
    g_task_report_new_error (G_OBJECT (connection), callback, user_data,
716
0
                             connection,
717
0
                             TRACKER_SPARQL_ERROR,
718
0
                             TRACKER_SPARQL_ERROR_UNSUPPORTED,
719
0
                             "Updates unsupported by this connection");
720
0
    return;
721
0
  }
722
723
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource_async (connection,
724
0
                                                                           graph,
725
0
                                                                           resource,
726
0
                                                                           cancellable,
727
0
                                                                           callback,
728
0
                                                                           user_data);
729
0
}
730
731
/**
732
 * tracker_sparql_connection_update_resource_finish:
733
 * @connection: A `TrackerSparqlConnection`
734
 * @res: A [type@Gio.AsyncResult] with the result of the operation
735
 * @error: Error location
736
 *
737
 * Finishes the operation started with [method@SparqlConnection.update_resource_async].
738
 *
739
 * Returns: #TRUE if there were no errors.
740
 *
741
 * Since: 3.1
742
 **/
743
gboolean
744
tracker_sparql_connection_update_resource_finish (TrackerSparqlConnection  *connection,
745
                                                  GAsyncResult             *res,
746
                                                  GError                  **error)
747
0
{
748
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
749
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
750
0
  g_return_val_if_fail (!error || !*error, FALSE);
751
752
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->deserialize_finish)
753
0
    return g_task_propagate_boolean (G_TASK (res), error);
754
755
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_resource_finish (connection,
756
0
                                                                                   res,
757
0
                                                                                   error);
758
0
}
759
760
/**
761
 * tracker_sparql_connection_get_namespace_manager:
762
 * @connection: A `TrackerSparqlConnection`
763
 *
764
 * Returns a [class@NamespaceManager] that contains all
765
 * prefixes in the ontology of @connection.
766
 *
767
 * Returns: (transfer none): a [class@NamespaceManager] with the prefixes of @connection.
768
 */
769
TrackerNamespaceManager *
770
tracker_sparql_connection_get_namespace_manager (TrackerSparqlConnection *connection)
771
0
{
772
0
  TrackerNamespaceManager *manager;
773
774
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
775
776
0
  manager = TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->get_namespace_manager (connection);
777
0
  tracker_namespace_manager_seal (manager);
778
779
0
  return manager;
780
0
}
781
782
/**
783
 * tracker_sparql_connection_query_statement:
784
 * @connection: A `TrackerSparqlConnection`
785
 * @sparql: The SPARQL query
786
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
787
 * @error: Error location
788
 *
789
 * Prepares the given `SELECT`/`ASK`/`DESCRIBE`/`CONSTRUCT` SPARQL query as a
790
 * [class@SparqlStatement].
791
 *
792
 * This prepared statement can be executed through [method@SparqlStatement.execute]
793
 * or [method@SparqlStatement.serialize_async] families of functions.
794
 *
795
 * Returns: (transfer full): A prepared statement
796
 */
797
TrackerSparqlStatement *
798
tracker_sparql_connection_query_statement (TrackerSparqlConnection  *connection,
799
                                           const gchar              *sparql,
800
                                           GCancellable             *cancellable,
801
                                           GError                  **error)
802
0
{
803
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
804
0
  g_return_val_if_fail (sparql != NULL, NULL);
805
0
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
806
0
  g_return_val_if_fail (!error || !*error, NULL);
807
808
0
  if (tracker_sparql_connection_set_error_on_closed (connection, error))
809
0
    return NULL;
810
811
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query_statement (connection,
812
0
                                                                            sparql,
813
0
                                                                            cancellable,
814
0
                                                                            error);
815
0
}
816
817
/**
818
 * tracker_sparql_connection_update_statement:
819
 * @connection: A `TrackerSparqlConnection`
820
 * @sparql: The SPARQL update
821
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
822
 * @error: Error location
823
 *
824
 * Prepares the given `INSERT`/`DELETE` SPARQL as a [class@SparqlStatement].
825
 *
826
 * This prepared statement can be executed through
827
 * the [method@SparqlStatement.update] family of functions.
828
 *
829
 * Returns: (transfer full): A prepared statement
830
 *
831
 * Since: 3.5
832
 */
833
TrackerSparqlStatement *
834
tracker_sparql_connection_update_statement (TrackerSparqlConnection  *connection,
835
                                            const gchar              *sparql,
836
                                            GCancellable             *cancellable,
837
                                            GError                  **error)
838
0
{
839
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
840
0
  g_return_val_if_fail (sparql != NULL, NULL);
841
0
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
842
0
  g_return_val_if_fail (!error || !*error, NULL);
843
844
0
  if (tracker_sparql_connection_set_error_on_closed (connection, error))
845
0
    return NULL;
846
847
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_statement) {
848
0
    g_set_error (error,
849
0
                 TRACKER_SPARQL_ERROR,
850
0
                 TRACKER_SPARQL_ERROR_UNSUPPORTED,
851
0
                 "Updates unsupported by this connection");
852
0
    return NULL;
853
0
  }
854
855
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_statement (connection,
856
0
                                                                             sparql,
857
0
                                                                             cancellable,
858
0
                                                                             error);
859
0
}
860
861
/**
862
 * tracker_sparql_connection_create_notifier:
863
 * @connection: A `TrackerSparqlConnection`
864
 *
865
 * Creates a new [class@Notifier] to receive notifications about changes in @connection.
866
 *
867
 * See [class@Notifier] documentation for information about how to use this
868
 * object.
869
 *
870
 * Connections to HTTP endpoints will return %NULL.
871
 *
872
 * Returns: (transfer full) (nullable): A newly created notifier.
873
 **/
874
TrackerNotifier *
875
tracker_sparql_connection_create_notifier (TrackerSparqlConnection *connection)
876
0
{
877
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
878
879
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->create_notifier)
880
0
    return NULL;
881
882
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->create_notifier (connection);
883
0
}
884
885
/**
886
 * tracker_sparql_connection_close:
887
 * @connection: A `TrackerSparqlConnection`
888
 *
889
 * Closes a SPARQL connection.
890
 *
891
 * No other API calls than g_object_unref() should happen after this call.
892
 *
893
 * This call is blocking. All pending updates will be flushed, and the
894
 * store databases will be closed orderly. All ongoing SELECT queries
895
 * will be cancelled. Notifiers will no longer emit events.
896
 */
897
void
898
tracker_sparql_connection_close (TrackerSparqlConnection *connection)
899
1.23k
{
900
1.23k
  TrackerSparqlConnectionPrivate *priv =
901
1.23k
    tracker_sparql_connection_get_instance_private (connection);
902
903
1.23k
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
904
905
1.23k
  priv->closing = TRUE;
906
907
1.23k
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->close (connection);
908
1.23k
}
909
910
/**
911
 * tracker_sparql_connection_close_async:
912
 * @connection: A `TrackerSparqlConnection`
913
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
914
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
915
 *            the asynchronous operation is finished.
916
 * @user_data: User-defined data to be passed to @callback
917
 *
918
 * Closes a SPARQL connection asynchronously.
919
 *
920
 * No other API calls than g_object_unref() should happen after this call.
921
 **/
922
void
923
tracker_sparql_connection_close_async (TrackerSparqlConnection *connection,
924
                                       GCancellable            *cancellable,
925
                                       GAsyncReadyCallback      callback,
926
                                       gpointer                 user_data)
927
0
{
928
0
  TrackerSparqlConnectionPrivate *priv =
929
0
    tracker_sparql_connection_get_instance_private (connection);
930
931
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
932
933
0
  priv->closing = TRUE;
934
935
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->close_async (connection,
936
0
                                                                 cancellable,
937
0
                                                                 callback,
938
0
                                                                 user_data);
939
0
}
940
941
/**
942
 * tracker_sparql_connection_close_finish:
943
 * @connection: A `TrackerSparqlConnection`
944
 * @res: A [type@Gio.AsyncResult] with the result of the operation
945
 * @error: Error location
946
 *
947
 * Finishes the operation started with [method@SparqlConnection.close_async].
948
 *
949
 * Returns: %FALSE if some error occurred, %TRUE otherwise
950
 **/
951
gboolean
952
tracker_sparql_connection_close_finish (TrackerSparqlConnection  *connection,
953
                                        GAsyncResult             *res,
954
                                        GError                  **error)
955
0
{
956
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
957
958
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->close_finish (connection,
959
0
                                                                         res, error);
960
0
}
961
962
/**
963
 * tracker_sparql_connection_create_batch:
964
 * @connection: a `TrackerSparqlConnection`
965
 *
966
 * Creates a new [class@Batch] to store and execute SPARQL updates.
967
 *
968
 * If the connection is readonly or cannot issue SPARQL updates, %NULL will be returned.
969
 *
970
 * Returns: (transfer full): (nullable): A new [class@Batch]
971
 **/
972
TrackerBatch *
973
tracker_sparql_connection_create_batch (TrackerSparqlConnection *connection)
974
7.06k
{
975
7.06k
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
976
977
7.06k
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->create_batch)
978
0
    return NULL;
979
980
7.06k
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->create_batch (connection);
981
7.06k
}
982
983
/**
984
 * tracker_sparql_connection_load_statement_from_gresource:
985
 * @connection: A `TrackerSparqlConnection`
986
 * @resource_path: The resource path of the file to parse.
987
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
988
 * @error: Error location
989
 *
990
 * Prepares a [class@SparqlStatement] for the SPARQL contained as a [struct@Gio.Resource]
991
 * file at @resource_path.
992
 *
993
 * SPARQL Query files typically have the .rq extension. This will use
994
 * [method@SparqlConnection.query_statement] or [method@SparqlConnection.update_statement]
995
 * underneath to indistinctly return SPARQL query or update statements.
996
 *
997
 * Returns: (transfer full): A prepared statement
998
 *
999
 * Since: 3.3
1000
 **/
1001
TrackerSparqlStatement *
1002
tracker_sparql_connection_load_statement_from_gresource (TrackerSparqlConnection  *connection,
1003
                                                         const gchar              *resource_path,
1004
                                                         GCancellable             *cancellable,
1005
                                                         GError                  **error)
1006
0
{
1007
0
  TrackerSparqlStatement *stmt;
1008
0
  GBytes *query;
1009
0
  GError *inner_error1 = NULL, *inner_error2 = NULL;
1010
1011
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
1012
0
  g_return_val_if_fail (resource_path && *resource_path, NULL);
1013
0
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
1014
0
  g_return_val_if_fail (!error || !*error, NULL);
1015
1016
0
  if (tracker_sparql_connection_set_error_on_closed (connection, error))
1017
0
    return NULL;
1018
1019
0
  query = g_resources_lookup_data (resource_path,
1020
0
                                   G_RESOURCE_LOOKUP_FLAGS_NONE,
1021
0
                                   error);
1022
0
  if (!query)
1023
0
    return NULL;
1024
1025
0
  stmt = TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->query_statement (connection,
1026
0
                                                                            g_bytes_get_data (query,
1027
0
                                                                                              NULL),
1028
0
                                                                            cancellable,
1029
0
                                                                            &inner_error1);
1030
1031
0
  if (inner_error1 && TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_statement) {
1032
0
    stmt = TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->update_statement (connection,
1033
0
                                                                               g_bytes_get_data (query,
1034
0
                                                                                                 NULL),
1035
0
                                                                               cancellable,
1036
0
                                                                               &inner_error2);
1037
0
    if (inner_error1 && inner_error2) {
1038
      /* Pick one */
1039
0
      g_propagate_error (error, inner_error1);
1040
0
      g_clear_error (&inner_error2);
1041
0
    } else {
1042
0
      g_clear_error (&inner_error1);
1043
0
    }
1044
0
  }
1045
1046
0
  g_bytes_unref (query);
1047
1048
0
  return stmt;
1049
0
}
1050
1051
/**
1052
 * tracker_sparql_connection_serialize_async:
1053
 * @connection: A `TrackerSparqlConnection`
1054
 * @flags: Serialization flags
1055
 * @format: Output RDF format
1056
 * @query: SPARQL query
1057
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
1058
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
1059
 *            the asynchronous operation is finished.
1060
 * @user_data: User-defined data to be passed to @callback
1061
 *
1062
 * Serializes a `DESCRIBE` or `CONSTRUCT` query into the specified RDF format.
1063
 *
1064
 * This is an asynchronous operation, @callback will be invoked when
1065
 * the data is available for reading.
1066
 *
1067
 * The SPARQL endpoint may not support the specified format, in that case
1068
 * an error will be raised.
1069
 *
1070
 * The @flags argument is reserved for future expansions, currently
1071
 * %TRACKER_SERIALIZE_FLAGS_NONE must be passed.
1072
 *
1073
 * Since: 3.3
1074
 **/
1075
void
1076
tracker_sparql_connection_serialize_async (TrackerSparqlConnection *connection,
1077
                                           TrackerSerializeFlags    flags,
1078
                                           TrackerRdfFormat         format,
1079
                                           const gchar             *query,
1080
                                           GCancellable            *cancellable,
1081
                                           GAsyncReadyCallback      callback,
1082
                                           gpointer                 user_data)
1083
0
{
1084
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
1085
0
  g_return_if_fail (flags == TRACKER_SERIALIZE_FLAGS_NONE);
1086
0
  g_return_if_fail (format < TRACKER_N_RDF_FORMATS);
1087
0
  g_return_if_fail (query != NULL);
1088
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
1089
0
  g_return_if_fail (callback != NULL);
1090
1091
0
  if (tracker_sparql_connection_report_async_error_on_closed (connection,
1092
0
                                                              callback,
1093
0
                                                              user_data))
1094
0
    return;
1095
1096
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->serialize_async (connection,
1097
0
                                                                     flags,
1098
0
                                                                     format,
1099
0
                                                                     query,
1100
0
                                                                     cancellable,
1101
0
                                                                     callback,
1102
0
                                                                     user_data);
1103
0
}
1104
1105
/**
1106
 * tracker_sparql_connection_serialize_finish:
1107
 * @connection: A `TrackerSparqlConnection`
1108
 * @result: A [type@Gio.AsyncResult] with the result of the operation
1109
 * @error: Error location
1110
 *
1111
 * Finishes the operation started with [method@SparqlConnection.serialize_async].
1112
 *
1113
 * Returns: (transfer full): A [class@Gio.InputStream] to read RDF content.
1114
 *
1115
 * Since: 3.3
1116
 **/
1117
GInputStream *
1118
tracker_sparql_connection_serialize_finish (TrackerSparqlConnection  *connection,
1119
                                            GAsyncResult             *result,
1120
                                            GError                  **error)
1121
0
{
1122
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), NULL);
1123
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
1124
0
  g_return_val_if_fail (!error || !*error, NULL);
1125
1126
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->serialize_finish (connection,
1127
0
                                                                             result,
1128
0
                                                                             error);
1129
0
}
1130
1131
/**
1132
 * tracker_sparql_connection_deserialize_async:
1133
 * @connection: A `TrackerSparqlConnection`
1134
 * @flags: Deserialization flags
1135
 * @format: RDF format of data in stream
1136
 * @default_graph: Default graph that will receive the RDF data
1137
 * @stream: Input stream with RDF data
1138
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
1139
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
1140
 *            the asynchronous operation is finished.
1141
 * @user_data: User-defined data to be passed to @callback
1142
 *
1143
 * Loads the RDF data contained in @stream into the given @connection.
1144
1145
 * This is an asynchronous operation, @callback will be invoked when the
1146
 * data has been fully inserted to @connection.
1147
 *
1148
 * The RDF data will be inserted in the given @default_graph if one is provided,
1149
 * or the anonymous graph if @default_graph is %NULL. Any RDF data that has a
1150
 * graph specified (e.g. using the `GRAPH` clause in the Trig format) will
1151
 * be inserted in the specified graph instead of @default_graph.
1152
 *
1153
 * The @flags argument is reserved for future expansions, currently
1154
 * %TRACKER_DESERIALIZE_FLAGS_NONE must be passed.
1155
 *
1156
 * Since: 3.4
1157
 **/
1158
void
1159
tracker_sparql_connection_deserialize_async (TrackerSparqlConnection *connection,
1160
                                             TrackerDeserializeFlags  flags,
1161
                                             TrackerRdfFormat         format,
1162
                                             const gchar             *default_graph,
1163
                                             GInputStream            *stream,
1164
                                             GCancellable            *cancellable,
1165
                                             GAsyncReadyCallback      callback,
1166
                                             gpointer                 user_data)
1167
0
{
1168
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
1169
0
  g_return_if_fail (flags == TRACKER_DESERIALIZE_FLAGS_NONE);
1170
0
  g_return_if_fail (format < TRACKER_N_RDF_FORMATS);
1171
0
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
1172
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
1173
0
  g_return_if_fail (callback != NULL);
1174
1175
0
  if (tracker_sparql_connection_report_async_error_on_closed (connection,
1176
0
                                                              callback,
1177
0
                                                              user_data))
1178
0
    return;
1179
1180
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->deserialize_async) {
1181
0
    g_task_report_new_error (G_OBJECT (connection), callback, user_data,
1182
0
                             connection,
1183
0
                             TRACKER_SPARQL_ERROR,
1184
0
                             TRACKER_SPARQL_ERROR_UNSUPPORTED,
1185
0
                             "Updates unsupported by this connection");
1186
0
    return;
1187
0
  }
1188
1189
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->deserialize_async (connection,
1190
0
                                                                       flags,
1191
0
                                                                       format,
1192
0
                                                                       default_graph,
1193
0
                                                                       stream,
1194
0
                                                                       cancellable,
1195
0
                                                                       callback,
1196
0
                                                                       user_data);
1197
0
}
1198
1199
/**
1200
 * tracker_sparql_connection_deserialize_finish:
1201
 * @connection: A `TrackerSparqlConnection`
1202
 * @result: A [type@Gio.AsyncResult] with the result of the operation
1203
 * @error: Error location
1204
 *
1205
 * Finishes the operation started with [method@SparqlConnection.deserialize_async].
1206
 *
1207
 * Returns: %TRUE if all data was inserted successfully.
1208
 *
1209
 * Since: 3.4
1210
 **/
1211
gboolean
1212
tracker_sparql_connection_deserialize_finish (TrackerSparqlConnection  *connection,
1213
                                              GAsyncResult             *result,
1214
                                              GError                  **error)
1215
0
{
1216
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection), FALSE);
1217
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1218
0
  g_return_val_if_fail (!error || !*error, FALSE);
1219
1220
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->deserialize_finish)
1221
0
    return g_task_propagate_boolean (G_TASK (result), error);
1222
1223
0
  return TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->deserialize_finish (connection,
1224
0
                                                                               result,
1225
0
                                                                               error);
1226
0
}
1227
1228
/**
1229
 * tracker_sparql_connection_map_connection:
1230
 * @connection: A `TrackerSparqlConnection`
1231
 * @handle_name: Handle name for @service_connection
1232
 * @service_connection: a `TrackerSparqlConnection` to use from @connection
1233
 *
1234
 * Maps a `TrackerSparqlConnection` onto another through a `private:@handle_name` URI.
1235
 *
1236
 * This can be accessed via the SERVICE SPARQL syntax in
1237
 * queries from @connection. E.g.:
1238
 *
1239
 * ```c
1240
 * tracker_sparql_connection_map_connection (connection,
1241
 *                                           "other-connection",
1242
 *                                           other_connection);
1243
 * ```
1244
 *
1245
 * ```sparql
1246
 * SELECT ?u {
1247
 *   SERVICE <private:other-connection> {
1248
 *     ?u a rdfs:Resource
1249
 *   }
1250
 * }
1251
 * ```
1252
 *
1253
 * This is useful to interrelate data from multiple
1254
 * `TrackerSparqlConnection` instances maintained by the same process,
1255
 * without creating a public endpoint for @service_connection.
1256
 *
1257
 * @connection may only be a `TrackerSparqlConnection` created via
1258
 * [ctor@SparqlConnection.new] and [func@SparqlConnection.new_async].
1259
 *
1260
 * Since: 3.3
1261
 **/
1262
void
1263
tracker_sparql_connection_map_connection (TrackerSparqlConnection *connection,
1264
            const gchar             *handle_name,
1265
            TrackerSparqlConnection *service_connection)
1266
0
{
1267
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
1268
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (service_connection));
1269
0
  g_return_if_fail (handle_name && *handle_name);
1270
1271
0
  if (!TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->map_connection)
1272
0
    return;
1273
1274
0
  TRACKER_SPARQL_CONNECTION_GET_CLASS (connection)->map_connection (connection,
1275
0
                                                                    handle_name,
1276
0
                                                                    service_connection);
1277
0
}
1278
1279
/**
1280
 * tracker_sparql_connection_remote_new:
1281
 * @uri_base: Base URI of the remote connection
1282
 *
1283
 * Creates a connection to a remote HTTP SPARQL endpoint.
1284
 *
1285
 * The connection is made using the libsoup HTTP library. The connection will
1286
 * normally use the `https://` or `http://` protocols.
1287
 *
1288
 * Returns: (transfer full): a new remote `TrackerSparqlConnection`.
1289
 */
1290
TrackerSparqlConnection *
1291
tracker_sparql_connection_remote_new (const gchar *uri_base)
1292
0
{
1293
0
  return TRACKER_SPARQL_CONNECTION (tracker_remote_connection_new (uri_base));
1294
0
}
1295
1296
/**
1297
 * tracker_sparql_connection_new:
1298
 * @flags: Connection flags to define the SPARQL connection behavior
1299
 * @store: (nullable): The database location as a [iface@Gio.File], or %NULL
1300
 * @ontology: (nullable): The directory that contains the database schemas as a [iface@Gio.File], or %NULL
1301
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
1302
 * @error: Error location
1303
 *
1304
 * Creates or opens a process-local database.
1305
 *
1306
 * This method should only be used for databases owned by the current process.
1307
 * To connect to databases managed by other processes, use
1308
 * [ctor@SparqlConnection.bus_new].
1309
 *
1310
 * The @store argument determines where in the local filesystem the database
1311
 * will be stored. If @store is %NULL, the database will be created in memory.
1312
 * Traditionally, @store describes a directory where a file named `meta.db`
1313
 * contains the data. Starting with version 3.10, if the basename of @store
1314
 * contains a `.` extension separator, it will be considered as the database
1315
 * file itself.
1316
 *
1317
 * If defined, the @ontology argument must point to a location containing
1318
 * suitable `.ontology` files in Turtle format. These define the structure of
1319
 * the triple store. You can learn more about [ontologies](ontologies.html),
1320
 * or you can use the stock Nepomuk ontologies by calling
1321
 * [func@sparql_get_ontology_nepomuk].
1322
 *
1323
 * If opening an existing database, it is possible to pass %NULL as the
1324
 * @ontology location, the ontology will be introspected from the database.
1325
 * Passing a %NULL @ontology will raise an error if the database does not exist.
1326
 *
1327
 * If a database is opened without the `READONLY` [flags@SparqlConnectionFlags]
1328
 * flag enabled, and the given @ontology holds differences with the current
1329
 * data layout, migration to the new structure will be attempted. This operation
1330
 * may raise an error. In particular, not all migrations are possible without
1331
 * causing data loss and Tracker will refuse to delete data during a migration.
1332
 * The database is always left in a consistent state, either prior or posterior
1333
 * to migration.
1334
 *
1335
 * Operations on a [class@SparqlConnection] resulting on a
1336
 * `CORRUPT` [error@SparqlError] will have the event recorded
1337
 * persistently through a `.$DB_BASENAME.corrupted` file alongside the database file.
1338
 * If the database is opened without the `READONLY` [flags@SparqlConnectionFlags]
1339
 * flag enabled and the file is found, this constructor will attempt to repair the
1340
 * database. In that situation, this constructor will either return a valid
1341
 * [class@SparqlConnection] if the database was repaired successfully, or
1342
 * raise a `CORRUPT` [error@SparqlError] error if the database remains
1343
 * corrupted.
1344
 *
1345
 * It is considered a developer error to ship ontologies that contain format
1346
 * errors, or that fail at migrations.
1347
 *
1348
 * It is encouraged to use `resource:///` URI locations for @ontology wherever
1349
 * possible, so the triple store structure is tied to the executable binary,
1350
 * and in order to minimize disk seeks during `TrackerSparqlConnection`
1351
 * initialization.
1352
 *
1353
 * Returns: (transfer full): a new `TrackerSparqlConnection`.
1354
 */
1355
TrackerSparqlConnection *
1356
tracker_sparql_connection_new (TrackerSparqlConnectionFlags   flags,
1357
                               GFile                         *store,
1358
                               GFile                         *ontology,
1359
                               GCancellable                  *cancellable,
1360
                               GError                       **error)
1361
1.23k
{
1362
1.23k
  g_return_val_if_fail (!store || G_IS_FILE (store), NULL);
1363
1.23k
  g_return_val_if_fail (!ontology || G_IS_FILE (ontology), NULL);
1364
1.23k
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
1365
1.23k
  g_return_val_if_fail (!error || !*error, NULL);
1366
1367
1.23k
  return tracker_direct_connection_new (flags, store, ontology, error);
1368
1.23k
}
1369
1370
static void
1371
new_async_cb (GObject      *source,
1372
              GAsyncResult *res,
1373
              gpointer      user_data)
1374
0
{
1375
0
  TrackerSparqlConnection *conn;
1376
0
  GTask *task = user_data;
1377
0
  GError *error = NULL;
1378
1379
0
  conn = tracker_direct_connection_new_finish (res, &error);
1380
1381
0
  if (conn)
1382
0
    g_task_return_pointer (task, conn, g_object_unref);
1383
0
  else
1384
0
    g_task_return_error (task, error);
1385
1386
0
  g_object_unref (task);
1387
0
}
1388
1389
/**
1390
 * tracker_sparql_connection_new_async:
1391
 * @flags: Connection flags to define the SPARQL connection behavior
1392
 * @store: (nullable): The database location as a [iface@Gio.File], or %NULL
1393
 * @ontology: (nullable): The directory that contains the database schemas as a [iface@Gio.File], or %NULL
1394
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
1395
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
1396
 *            the asynchronous operation is finished.
1397
 * @user_data: User-defined data to be passed to @callback
1398
 *
1399
 * Creates or opens a process-local database asynchronously.
1400
 *
1401
 * See [ctor@SparqlConnection.new] for more information.
1402
 */
1403
1404
void
1405
tracker_sparql_connection_new_async (TrackerSparqlConnectionFlags  flags,
1406
                                     GFile                        *store,
1407
                                     GFile                        *ontology,
1408
                                     GCancellable                 *cancellable,
1409
                                     GAsyncReadyCallback           callback,
1410
                                     gpointer                      user_data)
1411
0
{
1412
0
  GTask *task;
1413
1414
0
  g_return_if_fail (!store || G_IS_FILE (store));
1415
0
  g_return_if_fail (!ontology || G_IS_FILE (ontology));
1416
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
1417
1418
0
  task = g_task_new (NULL, cancellable, callback, user_data);
1419
0
  g_task_set_source_tag (task, tracker_sparql_connection_new_async);
1420
1421
0
  tracker_direct_connection_new_async (flags, store, ontology, cancellable,
1422
0
                                       new_async_cb, task);
1423
0
}
1424
1425
/**
1426
 * tracker_sparql_connection_new_finish:
1427
 * @result: A [type@Gio.AsyncResult] with the result of the operation
1428
 * @error: Error location
1429
 *
1430
 * Finishes the operation started with [func@SparqlConnection.new_async].
1431
 *
1432
 * Returns: (transfer full): a new `TrackerSparqlConnection`.
1433
 */
1434
TrackerSparqlConnection *
1435
tracker_sparql_connection_new_finish (GAsyncResult  *res,
1436
                                      GError       **error)
1437
0
{
1438
0
  g_return_val_if_fail (G_IS_TASK (res), NULL);
1439
0
  g_return_val_if_fail (g_task_get_source_tag (G_TASK (res)) ==
1440
0
                        tracker_sparql_connection_new_async,
1441
0
                        NULL);
1442
1443
0
  return g_task_propagate_pointer (G_TASK (res), error);
1444
0
}
1445
1446
/**
1447
 * tracker_sparql_connection_new_from_rdf: (constructor):
1448
 * @flags: Connection flags to define the SPARQL connection behavior
1449
 * @store: (nullable): The database location as a [iface@Gio.File], or %NULL
1450
 * @deserialize_flags: Deserialization flags
1451
 * @rdf_format: RDF format of the @rdf_stream argument
1452
 * @rdf_stream: RDF Schema definition of the database format
1453
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
1454
 * @error: Error location
1455
 *
1456
 * Constructor similar to [ctor@SparqlConnection.new], that takes the
1457
 * RDF Schema definitions declaring the database schema as an input stream.
1458
 *
1459
 * Unlike that constructor, databases created this way will not have the
1460
 * RDF Schema data snapshot into the database itself. It will need to be
1461
 * done by the caller as a separate step, e.g. via
1462
 * [method@SparqlConnection.deserialize_async].
1463
 *
1464
 * Returns: (transfer full): a new `TrackerSparqlConnection`.
1465
 *
1466
 * Since: 3.11
1467
 */
1468
TrackerSparqlConnection *
1469
tracker_sparql_connection_new_from_rdf (TrackerSparqlConnectionFlags   flags,
1470
                                        GFile                         *store,
1471
                                        TrackerDeserializeFlags        deserialize_flags,
1472
                                        TrackerRdfFormat               rdf_format,
1473
                                        GInputStream                  *rdf_stream,
1474
                                        GCancellable                  *cancellable,
1475
                                        GError                       **error)
1476
0
{
1477
0
  g_return_val_if_fail (!store || G_IS_FILE (store), NULL);
1478
0
  g_return_val_if_fail (deserialize_flags == TRACKER_DESERIALIZE_FLAGS_NONE, NULL);
1479
0
  g_return_val_if_fail (rdf_format < TRACKER_N_RDF_FORMATS, NULL);
1480
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (rdf_stream), NULL);
1481
0
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
1482
1483
0
  return tracker_direct_connection_new_from_rdf (flags, store,
1484
0
                                                 deserialize_flags,
1485
0
                                                 rdf_format, rdf_stream,
1486
0
                                                 cancellable, error);
1487
0
}
1488
1489
static void
1490
new_from_rdf_async_cb (GObject      *source,
1491
                       GAsyncResult *res,
1492
                       gpointer      user_data)
1493
0
{
1494
0
  TrackerSparqlConnection *conn;
1495
0
  GTask *task = user_data;
1496
0
  GError *error = NULL;
1497
1498
0
  conn = tracker_direct_connection_new_from_rdf_finish (res, &error);
1499
1500
0
  if (conn)
1501
0
    g_task_return_pointer (task, conn, g_object_unref);
1502
0
  else
1503
0
    g_task_return_error (task, error);
1504
1505
0
  g_object_unref (task);
1506
0
}
1507
1508
/**
1509
 * tracker_sparql_connection_new_from_rdf_async:
1510
 * @flags: Connection flags to define the SPARQL connection behavior
1511
 * @store: (nullable): The database location as a [iface@Gio.File], or %NULL
1512
 * @deserialize_flags: Deserialization flags
1513
 * @rdf_format: RDF format of the @rdf_stream argument
1514
 * @rdf_stream: RDF Schema definition of the database format
1515
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
1516
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
1517
 *            the asynchronous operation is finished.
1518
 * @user_data: User-defined data to be passed to @callback
1519
 *
1520
 * Asynchronous version of [ctor@SparqlConnection.new_from_rdf].
1521
 *
1522
 * Since: 3.11
1523
 */
1524
void
1525
tracker_sparql_connection_new_from_rdf_async (TrackerSparqlConnectionFlags  flags,
1526
                                              GFile                        *store,
1527
                                              TrackerDeserializeFlags       deserialize_flags,
1528
                                              TrackerRdfFormat              rdf_format,
1529
                                              GInputStream                 *rdf_stream,
1530
                                              GCancellable                 *cancellable,
1531
                                              GAsyncReadyCallback           callback,
1532
                                              gpointer                      user_data)
1533
0
{
1534
0
  GTask *task;
1535
1536
0
  g_return_if_fail (!store || G_IS_FILE (store));
1537
0
  g_return_if_fail (deserialize_flags == TRACKER_DESERIALIZE_FLAGS_NONE);
1538
0
  g_return_if_fail (rdf_format < TRACKER_N_RDF_FORMATS);
1539
0
  g_return_if_fail (G_IS_INPUT_STREAM (rdf_stream));
1540
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
1541
1542
0
  task = g_task_new (NULL, cancellable, callback, user_data);
1543
0
  g_task_set_source_tag (task, tracker_sparql_connection_new_from_rdf_async);
1544
1545
0
  tracker_direct_connection_new_from_rdf_async (flags, store,
1546
0
                                                deserialize_flags,
1547
0
                                                rdf_format, rdf_stream,
1548
0
                                                cancellable,
1549
0
                                                new_from_rdf_async_cb, task);
1550
0
}
1551
1552
/**
1553
 * tracker_sparql_connection_new_from_rdf_finish: (constructor):
1554
 * @result: A [type@Gio.AsyncResult] with the result of the operation
1555
 * @error: Error location
1556
 *
1557
 * Finishes the operation started with [func@SparqlConnection.new_from_rdf_async].
1558
 *
1559
 * Returns: (transfer full): a new `TrackerSparqlConnection`.
1560
 *
1561
 * Since: 3.11
1562
 */
1563
TrackerSparqlConnection *
1564
tracker_sparql_connection_new_from_rdf_finish (GAsyncResult  *result,
1565
                                               GError       **error)
1566
0
{
1567
0
  g_return_val_if_fail (G_IS_TASK (result), NULL);
1568
0
  g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
1569
0
                        tracker_sparql_connection_new_from_rdf_async,
1570
0
                        NULL);
1571
1572
0
  return g_task_propagate_pointer (G_TASK (result), error);
1573
0
}
1574
1575
/**
1576
 * tracker_sparql_connection_bus_new:
1577
 * @service_name (nullable): The name of the D-Bus service to connect to, or %NULL if not using a message bus.
1578
 * @object_path: (nullable): The path to the object, or %NULL to use the default.
1579
 * @dbus_connection: (nullable): The [type@Gio.DBusConnection] to use, or %NULL to use the session bus
1580
 * @error: Error location
1581
 *
1582
 * Connects to a database owned by another process on the
1583
 * local machine via DBus.
1584
 *
1585
 * When using a message bus (session/system), the @service_name argument will
1586
 * be used to describe the remote endpoint, either by unique or well-known D-Bus
1587
 * names. If not using a message bus (e.g. peer-to-peer D-Bus connections) the
1588
 * @service_name may be %NULL.
1589
 *
1590
 * The D-Bus object path of the remote endpoint will be given through
1591
 * @object_path, %NULL may be used to use the default
1592
 * `/org/freedesktop/Tracker3/Endpoint` path.
1593
 *
1594
 * The D-Bus connection used to set up the connection may be given through
1595
 * the @dbus_connection argument. Using %NULL will resort to the default session
1596
 * bus.
1597
 *
1598
 * Returns: (transfer full): a new `TrackerSparqlConnection`.
1599
 */
1600
TrackerSparqlConnection *
1601
tracker_sparql_connection_bus_new (const gchar      *service,
1602
                                   const gchar      *object_path,
1603
                                   GDBusConnection  *conn,
1604
                                   GError          **error)
1605
0
{
1606
0
  g_return_val_if_fail (!conn || G_IS_DBUS_CONNECTION (conn), NULL);
1607
0
  g_return_val_if_fail (!error || !*error, NULL);
1608
0
  g_return_val_if_fail ((service == NULL && conn &&
1609
0
                         (g_dbus_connection_get_flags (conn) & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) == 0) ||
1610
0
                        (service != NULL && g_dbus_is_name (service)), NULL);
1611
1612
0
  if (!object_path)
1613
0
    object_path = "/org/freedesktop/Tracker3/Endpoint";
1614
1615
0
  return tracker_bus_connection_new (service, object_path, conn, error);
1616
0
}
1617
1618
static void
1619
bus_new_cb (GObject      *source,
1620
            GAsyncResult *res,
1621
            gpointer      user_data)
1622
0
{
1623
0
  TrackerSparqlConnection *conn;
1624
0
  GTask *task = user_data;
1625
0
  GError *error = NULL;
1626
1627
0
  conn = tracker_bus_connection_new_finish (res, &error);
1628
1629
0
  if (conn)
1630
0
    g_task_return_pointer (task, conn, g_object_unref);
1631
0
  else
1632
0
    g_task_return_error (task, error);
1633
1634
0
  g_object_unref (task);
1635
0
}
1636
1637
/**
1638
 * tracker_sparql_connection_bus_new_async:
1639
 * @service_name: The name of the D-Bus service to connect to.
1640
 * @object_path: (nullable): The path to the object, or %NULL to use the default.
1641
 * @dbus_connection: (nullable): The [class@Gio.DBusConnection] to use, or %NULL to use the session bus
1642
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
1643
 * @callback: User-defined [type@Gio.AsyncReadyCallback] to be called when
1644
 *            the asynchronous operation is finished.
1645
 * @user_data: User-defined data to be passed to @callback
1646
 *
1647
 * Connects asynchronously to a database owned by another process on the
1648
 * local machine via DBus.
1649
 *
1650
 * Since: 3.1
1651
 */
1652
void
1653
tracker_sparql_connection_bus_new_async (const gchar         *service,
1654
                                         const gchar         *object_path,
1655
                                         GDBusConnection     *conn,
1656
                                         GCancellable        *cancellable,
1657
                                         GAsyncReadyCallback  callback,
1658
                                         gpointer             user_data)
1659
0
{
1660
0
  GTask *task;
1661
1662
0
  g_return_if_fail (service != NULL);
1663
0
  g_return_if_fail (!conn || G_IS_DBUS_CONNECTION (conn));
1664
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
1665
1666
0
  task = g_task_new (NULL, cancellable, callback, user_data);
1667
0
  g_task_set_source_tag (task, tracker_sparql_connection_bus_new_async);
1668
1669
0
  if (!object_path)
1670
0
    object_path = "/org/freedesktop/Tracker3/Endpoint";
1671
1672
0
  tracker_bus_connection_new_async (service, object_path, conn,
1673
0
                                    cancellable, bus_new_cb,
1674
0
                                    task);
1675
0
}
1676
1677
/**
1678
 * tracker_sparql_connection_bus_new_finish:
1679
 * @result: A [type@Gio.AsyncResult] with the result of the operation
1680
 * @error: Error location
1681
 *
1682
 * Finishes the operation started with [func@SparqlConnection.bus_new_async].
1683
 *
1684
 * Returns: (transfer full): a new `TrackerSparqlConnection`.
1685
 *
1686
 * Since: 3.1
1687
 */
1688
TrackerSparqlConnection *
1689
tracker_sparql_connection_bus_new_finish (GAsyncResult  *result,
1690
                                          GError       **error)
1691
0
{
1692
0
  g_return_val_if_fail (G_IS_TASK (result), NULL);
1693
0
  g_return_val_if_fail (!error || !*error, NULL);
1694
0
  g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
1695
0
                        tracker_sparql_connection_bus_new_async,
1696
0
                        NULL);
1697
1698
0
  return g_task_propagate_pointer (G_TASK (result), error);
1699
0
}