Coverage Report

Created: 2026-04-01 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tinysparql/src/libtinysparql/tracker-cursor.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
 * TrackerSparqlCursor:
21
 *
22
 * `TrackerSparqlCursor` provides the methods to iterate the results of a SPARQL query.
23
 *
24
 * Cursors are obtained through e.g. [method@SparqlStatement.execute]
25
 * or [method@SparqlConnection.query] after the SPARQL query has been
26
 * executed.
27
 *
28
 * When created, a cursor does not point to any element, [method@SparqlCursor.next]
29
 * is necessary to iterate one by one to the first (and following) results.
30
 * When the cursor iterated across all rows in the result set, [method@SparqlCursor.next]
31
 * will return %FALSE with no error set.
32
 *
33
 * On each row, it is possible to extract the result values through the
34
 * [method@SparqlCursor.get_integer], [method@SparqlCursor.get_string], etc... family
35
 * of methods. The column index of those functions starts at 0. The number of columns is
36
 * dependent on the SPARQL query issued, but may be checked at runtime through the
37
 * [method@SparqlCursor.get_n_columns] method.
38
 *
39
 * After a cursor is iterated, it is recommended to call [method@SparqlCursor.close]
40
 * explicitly to free up resources for other users of the same [class@SparqlConnection],
41
 * this is especially important in garbage collected languages. These resources
42
 * will be also implicitly freed on cursor object finalization.
43
 *
44
 * It is possible to use a given `TrackerSparqlCursor` in other threads than
45
 * the one it was created from. It must be however used from just one thread
46
 * at any given time.
47
 */
48
#include "config.h"
49
50
#include "tracker-cursor.h"
51
#include "tracker-private.h"
52
53
enum {
54
  PROP_0,
55
  PROP_CONNECTION,
56
  PROP_N_COLUMNS,
57
  N_PROPS
58
};
59
60
static GParamSpec *props[N_PROPS];
61
62
typedef struct {
63
  TrackerSparqlConnection *connection;
64
} TrackerSparqlCursorPrivate;
65
66
24.5k
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (TrackerSparqlCursor, tracker_sparql_cursor,
67
24.5k
                                     G_TYPE_OBJECT)
68
24.5k
69
24.5k
static void
70
24.5k
tracker_sparql_cursor_init (TrackerSparqlCursor *cursor)
71
24.5k
{
72
13
}
73
74
static gboolean
75
tracker_sparql_cursor_real_is_bound (TrackerSparqlCursor *cursor,
76
                                     gint                 column)
77
36
{
78
36
  return tracker_sparql_cursor_get_value_type (cursor, column) != TRACKER_SPARQL_VALUE_TYPE_UNBOUND;
79
36
}
80
81
static gint64
82
tracker_sparql_cursor_real_get_integer (TrackerSparqlCursor *cursor,
83
                                        gint                 column)
84
35
{
85
35
  const gchar *text;
86
87
35
  g_return_val_if_fail (tracker_sparql_cursor_real_is_bound (cursor, column), 0);
88
89
35
  text = tracker_sparql_cursor_get_string (cursor, column, NULL);
90
35
  return g_ascii_strtoll (text, NULL, 10);
91
35
}
92
93
static gdouble
94
tracker_sparql_cursor_real_get_double (TrackerSparqlCursor *cursor,
95
                                       gint                 column)
96
0
{
97
0
  const gchar *text;
98
99
0
  g_return_val_if_fail (tracker_sparql_cursor_real_is_bound (cursor, column), 0);
100
101
0
  text = tracker_sparql_cursor_get_string (cursor, column, NULL);
102
103
0
  return g_ascii_strtod (text, NULL);
104
0
}
105
106
static gboolean
107
tracker_sparql_cursor_real_get_boolean (TrackerSparqlCursor *cursor,
108
                                        gint                 column)
109
1
{
110
1
  const gchar *text;
111
112
1
  g_return_val_if_fail (tracker_sparql_cursor_real_is_bound (cursor, column), FALSE);
113
114
1
  text = tracker_sparql_cursor_get_string (cursor, column, NULL);
115
116
1
  return g_ascii_strcasecmp (text, "true") == 0;
117
1
}
118
119
static GDateTime *
120
tracker_sparql_cursor_real_get_datetime (TrackerSparqlCursor *cursor,
121
                                         gint                 column)
122
0
{
123
0
  const gchar *text;
124
0
  GDateTime *date_time;
125
126
0
  g_return_val_if_fail (tracker_sparql_cursor_real_is_bound (cursor, column), NULL);
127
128
0
  text = tracker_sparql_cursor_get_string (cursor, column, NULL);
129
0
  date_time = g_date_time_new_from_iso8601 (text, NULL);
130
131
0
  return date_time;
132
0
}
133
134
static void
135
tracker_sparql_cursor_finalize (GObject *object)
136
12
{
137
12
  TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (object);
138
12
  TrackerSparqlCursorPrivate *priv = tracker_sparql_cursor_get_instance_private (cursor);
139
140
12
  g_clear_object (&priv->connection);
141
12
  G_OBJECT_CLASS (tracker_sparql_cursor_parent_class)->finalize (object);
142
12
}
143
144
static void
145
tracker_sparql_cursor_set_property (GObject      *object,
146
                                    guint         prop_id,
147
                                    const GValue *value,
148
                                    GParamSpec   *pspec)
149
13
{
150
13
  TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (object);
151
13
  TrackerSparqlCursorPrivate *priv = tracker_sparql_cursor_get_instance_private (cursor);
152
153
13
  switch (prop_id) {
154
13
  case PROP_CONNECTION:
155
13
    priv->connection = g_value_dup_object (value);
156
13
    break;
157
0
  default:
158
0
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
159
13
  }
160
13
}
161
162
static void
163
tracker_sparql_cursor_get_property (GObject    *object,
164
                                    guint       prop_id,
165
                                    GValue     *value,
166
                                    GParamSpec *pspec)
167
0
{
168
0
  TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (object);
169
0
  TrackerSparqlCursorPrivate *priv = tracker_sparql_cursor_get_instance_private (cursor);
170
171
0
  switch (prop_id) {
172
0
  case PROP_CONNECTION:
173
0
    g_value_set_object (value, priv->connection);
174
0
    break;
175
0
  case PROP_N_COLUMNS:
176
0
    g_value_set_int (value, tracker_sparql_cursor_get_n_columns (cursor));
177
0
    break;
178
0
  default:
179
0
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
180
0
  }
181
0
}
182
183
static void
184
tracker_sparql_cursor_class_init (TrackerSparqlCursorClass *klass)
185
1
{
186
1
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
187
188
1
  object_class->finalize = tracker_sparql_cursor_finalize;
189
1
  object_class->set_property = tracker_sparql_cursor_set_property;
190
1
  object_class->get_property = tracker_sparql_cursor_get_property;
191
192
1
  klass->get_integer = tracker_sparql_cursor_real_get_integer;
193
1
  klass->get_double = tracker_sparql_cursor_real_get_double;
194
1
  klass->get_boolean = tracker_sparql_cursor_real_get_boolean;
195
1
  klass->get_datetime = tracker_sparql_cursor_real_get_datetime;
196
1
  klass->is_bound = tracker_sparql_cursor_real_is_bound;
197
198
  /**
199
   * TrackerSparqlCursor:connection:
200
   *
201
   * The [class@SparqlConnection] used to retrieve the results.
202
   */
203
1
  props[PROP_CONNECTION] =
204
1
    g_param_spec_object ("connection",
205
1
                         "connection",
206
1
                         "connection",
207
1
                         TRACKER_SPARQL_TYPE_CONNECTION,
208
1
                         G_PARAM_CONSTRUCT_ONLY |
209
1
                         G_PARAM_STATIC_STRINGS |
210
1
                         G_PARAM_READABLE |
211
1
                         G_PARAM_WRITABLE);
212
  /**
213
   * TrackerSparqlCursor:n-columns:
214
   *
215
   * Number of columns available in the result set.
216
   */
217
1
  props[PROP_N_COLUMNS] =
218
1
    g_param_spec_int ("n-columns",
219
1
                      "n-columns",
220
1
                      "n-columns",
221
1
                      G_MININT, G_MAXINT, 0,
222
1
                      G_PARAM_STATIC_STRINGS |
223
1
                      G_PARAM_READABLE);
224
225
1
  g_object_class_install_properties (object_class, N_PROPS, props);
226
1
}
227
228
/**
229
 * tracker_sparql_cursor_get_connection:
230
 * @cursor: a `TrackerSparqlCursor`
231
 *
232
 * Returns the [class@SparqlConnection] associated with this
233
 * `TrackerSparqlCursor`.
234
 *
235
 * Returns: (transfer none): the cursor [class@SparqlConnection]. The
236
 * returned object must not be unreferenced by the caller.
237
 */
238
TrackerSparqlConnection *
239
tracker_sparql_cursor_get_connection (TrackerSparqlCursor *cursor)
240
0
{
241
0
  TrackerSparqlCursorPrivate *priv = tracker_sparql_cursor_get_instance_private (cursor);
242
243
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), NULL);
244
245
0
  return priv->connection;
246
0
}
247
248
void
249
tracker_sparql_cursor_set_connection (TrackerSparqlCursor     *cursor,
250
                                      TrackerSparqlConnection *connection)
251
0
{
252
0
  TrackerSparqlCursorPrivate *priv = tracker_sparql_cursor_get_instance_private (cursor);
253
254
0
  g_return_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor));
255
0
  g_return_if_fail (TRACKER_IS_SPARQL_CONNECTION (connection));
256
257
0
  g_set_object (&priv->connection, connection);
258
0
}
259
260
/**
261
 * tracker_sparql_cursor_get_n_columns:
262
 * @cursor: a `TrackerSparqlCursor`
263
 *
264
 * Retrieves the number of columns available in the result set.
265
 *
266
 * This method should only be called after a successful
267
 * [method@SparqlCursor.next], otherwise its return value
268
 * will be undefined.
269
 *
270
 * Returns: The number of columns returned in the result set.
271
 */
272
gint
273
tracker_sparql_cursor_get_n_columns (TrackerSparqlCursor *cursor)
274
0
{
275
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), 0);
276
277
0
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_n_columns (cursor);
278
0
}
279
280
/**
281
 * tracker_sparql_cursor_get_string:
282
 * @cursor: a `TrackerSparqlCursor`
283
 * @column: column number to retrieve (first one is 0)
284
 * @length: (out) (nullable): length of the returned string, or %NULL
285
 *
286
 * Retrieves a string representation of the data in the current
287
 * row in @column.
288
 *
289
 * Any type may be converted to a string. If the value is not bound
290
 * (See [method@SparqlCursor.is_bound]) this method will return %NULL.
291
 *
292
 * Returns: (nullable): a string which must not be freed. %NULL is returned if
293
 * the column is not in the `[0, n_columns]` range, or if the row/column
294
 * refer to a nullable optional value in the result set.
295
 */
296
const gchar *
297
tracker_sparql_cursor_get_string (TrackerSparqlCursor *cursor,
298
                                  gint                 column,
299
                                  glong               *length)
300
5.23k
{
301
5.23k
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), NULL);
302
303
5.23k
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_string (cursor,
304
5.23k
                                                               column,
305
5.23k
                                                               NULL,
306
5.23k
                                                               length);
307
5.23k
}
308
309
/**
310
 * tracker_sparql_cursor_get_langstring:
311
 * @cursor: a `TrackerSparqlCursor`
312
 * @column: column number to retrieve
313
 * @langtag: (out): language tag of the returned string, or %NULL if the
314
 *   string has no language tag
315
 * @length: (out) (nullable): length of the returned string
316
 *
317
 * Retrieves a string representation of the data in the current
318
 * row in @column. If the string has language information (i.e. it is
319
 * a `rdf:langString`](rdf-ontology.html#rdf:langString)), the language
320
 * tag will be returned in the location provided through @langtag. This
321
 * language tag will typically be in a format conforming
322
 * [RFC 5646](https://www.rfc-editor.org/rfc/rfc5646.html).
323
 *
324
 * Returns: (nullable): a string which must not be freed. %NULL is returned if
325
 * the column is not in the `[0, n_columns]` range, or if the row/column
326
 * refer to a nullable optional value in the result set.
327
 *
328
 * Since: 3.7
329
 **/
330
const gchar *
331
tracker_sparql_cursor_get_langstring (TrackerSparqlCursor  *cursor,
332
                                      gint                  column,
333
                                      const gchar         **langtag,
334
                                      glong                *length)
335
930
{
336
930
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), NULL);
337
930
  g_return_val_if_fail (langtag != NULL, NULL);
338
339
930
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_string (cursor,
340
930
                                                               column,
341
930
                                                               langtag,
342
930
                                                               length);
343
930
}
344
345
/**
346
 * tracker_sparql_cursor_get_boolean:
347
 * @cursor: a `TrackerSparqlCursor`
348
 * @column: column number to retrieve (first one is 0)
349
 *
350
 * Retrieve a boolean for the current row in @column.
351
 *
352
 * If the row/column do not have a boolean value, the result is
353
 * undefined, see [method@SparqlCursor.get_value_type].
354
 *
355
 * Returns: a boolean value.
356
 */
357
gboolean
358
tracker_sparql_cursor_get_boolean (TrackerSparqlCursor *cursor,
359
                                   gint                 column)
360
1
{
361
1
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), FALSE);
362
363
1
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_boolean (cursor,
364
1
                                                                column);
365
1
}
366
367
/**
368
 * tracker_sparql_cursor_get_double:
369
 * @cursor: a `TrackerSparqlCursor`
370
 * @column: column number to retrieve (first one is 0)
371
 *
372
 * Retrieve a double for the current row in @column.
373
 *
374
 * If the row/column do not have a integer or double value, the result is
375
 * undefined, see [method@SparqlCursor.get_value_type].
376
 *
377
 * Returns: a double value.
378
 */
379
gdouble
380
tracker_sparql_cursor_get_double (TrackerSparqlCursor *cursor,
381
                                  gint                 column)
382
0
{
383
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), -1);
384
385
0
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_double (cursor,
386
0
                                                               column);
387
0
}
388
389
/**
390
 * tracker_sparql_cursor_get_integer:
391
 * @cursor: a `TrackerSparqlCursor`
392
 * @column: column number to retrieve (first one is 0)
393
 *
394
 * Retrieve an integer for the current row in @column.
395
 *
396
 * If the row/column do not have an integer value, the result is
397
 * undefined, see [method@SparqlCursor.get_value_type].
398
 *
399
 * Returns: a 64-bit integer value.
400
 */
401
gint64
402
tracker_sparql_cursor_get_integer (TrackerSparqlCursor *cursor,
403
                                   gint                 column)
404
35
{
405
35
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), -1);
406
407
35
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_integer (cursor,
408
35
                                                                column);
409
35
}
410
411
/**
412
 * tracker_sparql_cursor_get_value_type:
413
 * @cursor: a `TrackerSparqlCursor`
414
 * @column: column number to retrieve (first one is 0)
415
 *
416
 * Returns the data type bound to the current row and the given @column.
417
 *
418
 * If the column is unbound, the value will be %TRACKER_SPARQL_VALUE_TYPE_UNBOUND.
419
 * See also [method@SparqlCursor.is_bound].
420
 *
421
 * Values of type #TRACKER_SPARQL_VALUE_TYPE_RESOURCE and
422
 * #TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE can be considered equivalent, the
423
 * difference is the resource being referenced as a named IRI or a blank
424
 * node.
425
 *
426
 * All other [enum@SparqlValueType] value types refer to literal values.
427
 *
428
 * Returns: a [enum@SparqlValueType] expressing the content type of
429
 *   the given column for the current row.
430
 */
431
TrackerSparqlValueType
432
tracker_sparql_cursor_get_value_type (TrackerSparqlCursor *cursor,
433
                                      gint                 column)
434
108
{
435
108
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor),
436
108
                        TRACKER_SPARQL_VALUE_TYPE_UNBOUND);
437
438
108
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_value_type (cursor,
439
108
                                                                   column);
440
108
}
441
442
/**
443
 * tracker_sparql_cursor_get_variable_name:
444
 * @cursor: a `TrackerSparqlCursor`
445
 * @column: column number to retrieve (first one is 0)
446
 *
447
 * Retrieves the name of the given @column.
448
 *
449
 * This name will be defined at the SPARQL query, either
450
 * implicitly from the names of the variables returned in
451
 * the resultset, or explicitly through the `AS ?var` SPARQL
452
 * syntax.
453
 *
454
 * Returns: (nullable): The name of the given column.
455
 */
456
const gchar *
457
tracker_sparql_cursor_get_variable_name (TrackerSparqlCursor *cursor,
458
                                         gint                 column)
459
0
{
460
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), NULL);
461
462
0
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_variable_name (cursor,
463
0
                                                                      column);
464
0
}
465
466
/**
467
 * tracker_sparql_cursor_get_datetime:
468
 * @cursor: a `TrackerSparqlCursor`
469
 * @column: Column number to retrieve (first one is 0)
470
 *
471
 * Retrieves a [type@GLib.DateTime] pointer for the current row in @column.
472
 *
473
 * Returns: (transfer full) (nullable): [type@GLib.DateTime] object, or %NULL if the given column does not
474
 *   contain a [xsd:date](xsd-ontology.html#xsd:date) or [xsd:dateTime](xsd-ontology.html#xsd:dateTime).
475
 *
476
 * Since: 3.2
477
 */
478
GDateTime *
479
tracker_sparql_cursor_get_datetime (TrackerSparqlCursor *cursor,
480
                                    gint                 column)
481
0
{
482
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), NULL);
483
484
0
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->get_datetime (cursor,
485
0
                                                                 column);
486
0
}
487
488
/**
489
 * tracker_sparql_cursor_close:
490
 * @cursor: a `TrackerSparqlCursor`
491
 *
492
 * Closes the cursor. The object can only be freed after this call.
493
 */
494
void
495
tracker_sparql_cursor_close (TrackerSparqlCursor *cursor)
496
8
{
497
8
  g_return_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor));
498
499
8
  TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->close (cursor);
500
8
}
501
502
/**
503
 * tracker_sparql_cursor_is_bound:
504
 * @cursor: a `TrackerSparqlCursor`
505
 * @column: column number to retrieve (first one is 0)
506
 *
507
 * Returns whether the given @column has a bound value in the current row.
508
 *
509
 * This may not be the case through e.g. the `OPTIONAL { }` SPARQL syntax.
510
 *
511
 * Returns: a %TRUE or %FALSE.
512
 */
513
gboolean
514
tracker_sparql_cursor_is_bound (TrackerSparqlCursor *cursor,
515
                                gint                 column)
516
0
{
517
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), FALSE);
518
519
0
  return TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->is_bound (cursor, column);
520
0
}
521
522
/**
523
 * tracker_sparql_cursor_next:
524
 * @cursor: a `TrackerSparqlCursor`
525
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
526
 * @error: Error location
527
 *
528
 * Iterates the cursor to the next result.
529
 *
530
 * If the cursor was not started, it will point to the first result after
531
 * this call. This operation is completely synchronous and it may block,
532
 * see [method@SparqlCursor.next_async] for an asynchronous variant.
533
 *
534
 * Returns: %FALSE if there are no more results or if an error is found, otherwise %TRUE.
535
 */
536
gboolean
537
tracker_sparql_cursor_next (TrackerSparqlCursor  *cursor,
538
                            GCancellable         *cancellable,
539
                            GError              **error)
540
1.87k
{
541
1.87k
  GError *inner_error = NULL;
542
1.87k
  gboolean success;
543
544
1.87k
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), FALSE);
545
1.87k
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
546
1.87k
  g_return_val_if_fail (!error || !*error, FALSE);
547
548
1.87k
  success = TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->next (cursor,
549
1.87k
                                                            cancellable,
550
1.87k
                                                            &inner_error);
551
552
1.87k
  if (inner_error)
553
0
    g_propagate_error (error, _translate_internal_error (inner_error));
554
555
1.87k
  return success;
556
1.87k
}
557
558
/**
559
 * tracker_sparql_cursor_next_async:
560
 * @cursor: a `TrackerSparqlCursor`
561
 * @cancellable: (nullable): Optional [type@Gio.Cancellable]
562
 * @callback: user-defined [type@Gio.AsyncReadyCallback] to be called when
563
 *            asynchronous operation is finished.
564
 * @user_data: user-defined data to be passed to @callback
565
 *
566
 * Iterates the cursor asyncronously to the next result.
567
 *
568
 * If the cursor was not started, it will point to the first result after
569
 * this operation completes.
570
 *
571
 * In the period between this call and the corresponding
572
 * [method@SparqlCursor.next_finish] call, the other cursor methods
573
 * should not be used, nor their results trusted. The cursor should only
574
 * be iterated once at a time.
575
 */
576
void
577
tracker_sparql_cursor_next_async (TrackerSparqlCursor  *cursor,
578
                                  GCancellable         *cancellable,
579
                                  GAsyncReadyCallback   callback,
580
                                  gpointer              user_data)
581
0
{
582
0
  g_return_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor));
583
0
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
584
585
0
  TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->next_async (cursor,
586
0
                                                        cancellable,
587
0
                                                        callback,
588
0
                                                        user_data);
589
0
}
590
591
/**
592
 * tracker_sparql_cursor_next_finish:
593
 * @cursor: a `TrackerSparqlCursor`
594
 * @res: a [type@Gio.AsyncResult] with the result of the operation
595
 * @error: Error location
596
 *
597
 * Finishes the asynchronous iteration to the next result started with
598
 * [method@SparqlCursor.next_async].
599
 *
600
 * Returns: %FALSE if there are no more results or if an error is found, otherwise %TRUE.
601
 */
602
gboolean
603
tracker_sparql_cursor_next_finish (TrackerSparqlCursor  *cursor,
604
                                   GAsyncResult         *res,
605
                                   GError              **error)
606
0
{
607
0
  GError *inner_error = NULL;
608
0
  gboolean success;
609
610
0
  g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), FALSE);
611
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
612
0
  g_return_val_if_fail (!error || !*error, FALSE);
613
614
0
  success = TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->next_finish (cursor,
615
0
                                                                   res,
616
0
                                                                   &inner_error);
617
618
0
  if (inner_error)
619
0
    g_propagate_error (error, _translate_internal_error (inner_error));
620
621
0
  return success;
622
0
}
623
624
/**
625
 * tracker_sparql_cursor_rewind:
626
 * @cursor: a `TrackerSparqlCursor`
627
 *
628
 * Resets the iterator to point back to the first result.
629
 *
630
 * Deprecated: 3.5: This function only works on cursors
631
 * from direct [class@SparqlConnection] objects and cannot work
632
 * reliably across all cursor types. Issue a different query to
633
 * obtain a new cursor.
634
 */
635
void
636
tracker_sparql_cursor_rewind (TrackerSparqlCursor *cursor)
637
0
{
638
0
  g_return_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor));
639
640
0
  if (TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->rewind)
641
0
    TRACKER_SPARQL_CURSOR_GET_CLASS (cursor)->rewind (cursor);
642
0
  else
643
0
    g_warning ("Rewind not implemented for cursor type %s", G_OBJECT_TYPE_NAME (cursor));
644
0
}