Coverage Report

Created: 2026-04-12 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tinysparql/src/libtinysparql/remote/tracker-remote-namespaces.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2021, Red Hat Inc.
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
 * Author: Carlos Garnacho <carlosg@gnome.org>
20
 */
21
22
#include "config.h"
23
24
#include "remote/tracker-remote-namespaces.h"
25
26
#include "tracker-deserializer.h"
27
#include "tracker-private.h"
28
29
struct _TrackerRemoteNamespaceManager {
30
  TrackerNamespaceManager parent_instance;
31
  TrackerSparqlConnection *conn;
32
};
33
34
typedef struct {
35
  TrackerNamespaceManager *manager;
36
  GMainLoop *main_loop;
37
  GError *error;
38
} SerializeSyncData;
39
40
enum {
41
  PROP_0,
42
  PROP_CONNECTION,
43
  N_PROPS
44
};
45
46
static GParamSpec *props[N_PROPS];
47
48
static void
49
tracker_remote_namespace_manager_async_initable_iface_init (GAsyncInitableIface *iface);
50
static void
51
tracker_remote_namespace_manager_initable_iface_init (GInitableIface *iface);
52
53
0
G_DEFINE_TYPE_WITH_CODE (TrackerRemoteNamespaceManager,
54
0
                         tracker_remote_namespace_manager,
55
0
                         TRACKER_TYPE_NAMESPACE_MANAGER,
56
0
       G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
57
0
            tracker_remote_namespace_manager_initable_iface_init)
58
0
                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
59
0
                                                tracker_remote_namespace_manager_async_initable_iface_init))
60
0
61
0
static gboolean
62
0
initialize_namespaces_from_rdf (TrackerNamespaceManager  *manager,
63
0
                                GInputStream             *istream,
64
0
                                GError                  **error)
65
0
{
66
0
  TrackerSparqlCursor *deserializer;
67
0
  GError *inner_error = NULL;
68
69
0
  deserializer = tracker_deserializer_new (istream, manager, TRACKER_SERIALIZER_FORMAT_TTL);
70
71
  /* We don't care much about the content, just to have the
72
   * prefixes parsed.
73
   */
74
0
  if (tracker_sparql_cursor_next (deserializer, NULL, &inner_error))
75
0
    g_warning ("The remote endpoint replied with unexpected data");
76
0
  g_object_unref (deserializer);
77
78
0
  if (inner_error) {
79
0
    g_propagate_error (error, inner_error);
80
0
    return FALSE;
81
0
  }
82
83
0
  return TRUE;
84
0
}
85
86
static void
87
serialize_cb (GObject      *source,
88
              GAsyncResult *res,
89
              gpointer      user_data)
90
0
{
91
0
  GTask *task = user_data;
92
0
  TrackerNamespaceManager *manager =
93
0
    TRACKER_NAMESPACE_MANAGER (g_task_get_source_object (task));
94
0
  TrackerRemoteNamespaceManager *remote_manager =
95
0
    TRACKER_REMOTE_NAMESPACE_MANAGER (manager);
96
0
  GInputStream *istream;
97
0
  GError *error = NULL;
98
99
0
  istream = tracker_sparql_connection_serialize_finish (remote_manager->conn,
100
0
                                                        res,
101
0
                                                        &error);
102
0
  if (istream)
103
0
    initialize_namespaces_from_rdf (manager, istream, &error);
104
105
0
  if (error)
106
0
    g_task_return_error (task, error);
107
0
  else
108
0
    g_task_return_boolean (task, TRUE);
109
110
0
  g_object_unref (task);
111
0
}
112
113
static void
114
tracker_remote_namespace_manager_init_async (GAsyncInitable      *initable,
115
                                             int                  io_priority,
116
                                             GCancellable        *cancellable,
117
                                             GAsyncReadyCallback  callback,
118
                                             gpointer             user_data)
119
0
{
120
0
  TrackerRemoteNamespaceManager *manager =
121
0
    TRACKER_REMOTE_NAMESPACE_MANAGER (initable);
122
0
  GTask *task;
123
124
0
  task = g_task_new (manager, NULL, callback, user_data);
125
126
  /* Make a query for an empty URI, we only want the namespaces */
127
0
  tracker_sparql_connection_serialize_async (manager->conn,
128
0
                                             TRACKER_SERIALIZE_FLAGS_NONE,
129
0
                                             TRACKER_RDF_FORMAT_TURTLE,
130
0
                                             "DESCRIBE <>",
131
0
                                             NULL,
132
0
                                             serialize_cb,
133
0
                                             task);
134
0
}
135
136
static gboolean
137
tracker_remote_namespace_manager_init_finish (GAsyncInitable  *initable,
138
                                              GAsyncResult    *res,
139
                                              GError         **error)
140
0
{
141
0
  return g_task_propagate_boolean (G_TASK (res), error);
142
0
}
143
144
static void
145
serialize_sync_cb (GObject      *source,
146
       GAsyncResult *res,
147
       gpointer      user_data)
148
0
{
149
0
  SerializeSyncData *data = user_data;
150
151
0
  g_async_initable_init_finish (G_ASYNC_INITABLE (source), res, &data->error);
152
0
  g_main_loop_quit (data->main_loop);
153
0
}
154
155
static gboolean
156
tracker_remote_namespace_manager_initable_init (GInitable     *initable,
157
            GCancellable  *cancellable,
158
            GError       **error)
159
0
{
160
0
  TrackerRemoteNamespaceManager *manager =
161
0
    TRACKER_REMOTE_NAMESPACE_MANAGER (initable);
162
0
  SerializeSyncData data = { 0 };
163
164
0
  data.manager = TRACKER_NAMESPACE_MANAGER (manager);
165
0
  data.main_loop = g_main_loop_new (g_main_context_get_thread_default (), TRUE);
166
0
  g_async_initable_init_async (G_ASYNC_INITABLE (initable),
167
0
             G_PRIORITY_DEFAULT,
168
0
             cancellable,
169
0
             serialize_sync_cb,
170
0
             &data);
171
172
0
  g_main_loop_run (data.main_loop);
173
0
  g_main_loop_unref (data.main_loop);
174
175
0
  if (data.error) {
176
0
    g_propagate_error (error, data.error);
177
0
    return FALSE;
178
0
  }
179
180
0
  return TRUE;
181
0
}
182
183
static void
184
tracker_remote_namespace_manager_async_initable_iface_init (GAsyncInitableIface *iface)
185
0
{
186
0
  iface->init_async = tracker_remote_namespace_manager_init_async;
187
0
  iface->init_finish = tracker_remote_namespace_manager_init_finish;
188
0
}
189
190
static void
191
tracker_remote_namespace_manager_initable_iface_init (GInitableIface *iface)
192
0
{
193
0
  iface->init = tracker_remote_namespace_manager_initable_init;
194
0
}
195
196
static void
197
tracker_remote_namespace_manager_set_property (GObject      *object,
198
                                               guint         prop_id,
199
                                               const GValue *value,
200
                                               GParamSpec   *pspec)
201
0
{
202
0
  TrackerRemoteNamespaceManager *manager =
203
0
    TRACKER_REMOTE_NAMESPACE_MANAGER (object);
204
205
0
  switch (prop_id) {
206
0
  case PROP_CONNECTION:
207
0
    manager->conn = g_value_get_object (value);
208
0
    break;
209
0
  default:
210
0
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
211
0
    break;
212
0
  }
213
0
}
214
215
static void
216
tracker_remote_namespace_manager_class_init (TrackerRemoteNamespaceManagerClass *klass)
217
0
{
218
0
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
219
220
0
  object_class->set_property = tracker_remote_namespace_manager_set_property;
221
222
0
  props[PROP_CONNECTION] =
223
0
    g_param_spec_object ("connection",
224
0
                         "Connection",
225
0
                         "Connection",
226
0
                         TRACKER_TYPE_SPARQL_CONNECTION,
227
0
                         G_PARAM_WRITABLE |
228
0
                         G_PARAM_CONSTRUCT_ONLY);
229
230
0
  g_object_class_install_properties (object_class, N_PROPS, props);
231
232
0
}
233
234
static void
235
tracker_remote_namespace_manager_init (TrackerRemoteNamespaceManager *manager)
236
0
{
237
0
}
238
239
TrackerNamespaceManager *
240
tracker_remote_namespace_manager_new (TrackerSparqlConnection *conn)
241
0
{
242
0
  return g_initable_new (TRACKER_TYPE_REMOTE_NAMESPACE_MANAGER,
243
0
             NULL, NULL,
244
0
             "connection", conn,
245
             NULL);
246
0
}