Describe implication of upstream ICU-22610
[samba.git] / source3 / utils / async-tracker.c
blob7b6c2c0198681a53d8ef6a22dfc33d22b622f5e8
1 /*
2 * Copyright (C) 2011, Nokia <ivan.frade@nokia.com>
3 * Copyright (C) 2015, Noel Power <nopower@suse.com>
4 * Copyright (C) 2016, Ralph Boehme <slow@samba.org.>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include "includes.h"
23 #include "lib/util/debug.h"
24 #include "lib/cmdline/cmdline.h"
25 #include "param.h"
27 * glib uses TRUE and FALSE which was redefined by "includes.h" to be
28 * unusable, undefine so glib can establish its own working
29 * replacement.
31 #undef TRUE
32 #undef FALSE
33 #include <glib.h>
34 #include <libtracker-sparql/tracker-sparql.h>
35 #include "lib/tevent_glib_glue.h"
37 enum loop_type {TEVENT_LOOP, GLIB_LOOP};
39 struct test_state {
40 enum loop_type loop_type;
41 TrackerSparqlConnection *connection;
42 GCancellable *cancellable;
43 GTimer *timer;
44 GMainLoop *loop;
45 struct tevent_context *ev;
46 struct tevent_glib_glue *glue;
49 static void cleanup(struct test_state *state)
51 g_cancellable_cancel(state->cancellable);
52 g_object_unref(state->cancellable);
53 g_timer_destroy(state->timer);
54 if (state->connection != NULL) {
55 g_object_unref(state->connection);
56 state->connection = NULL;
58 if (state->loop_type == GLIB_LOOP) {
59 g_main_loop_quit(state->loop);
60 } else {
61 samba_tevent_glib_glue_quit(state->glue);
65 static void cursor_cb(GObject *object,
66 GAsyncResult *res,
67 gpointer user_data)
69 struct test_state *state = talloc_get_type_abort(
70 user_data, struct test_state);
71 TrackerSparqlCursor *cursor = NULL;
72 GError *error = NULL;
73 gboolean more_results;
74 static gint i = 0;
76 cursor = TRACKER_SPARQL_CURSOR(object);
77 more_results = tracker_sparql_cursor_next_finish(cursor,
78 res,
79 &error);
80 if (error) {
81 g_critical("Could not run cursor next: %s", error->message);
83 if (cursor != NULL) {
84 g_object_unref(cursor);
87 g_error_free(error);
88 cleanup(state);
89 return;
92 if (!more_results) {
93 g_print("\n");
94 g_print("\nAsync cursor next took: %.6f (for all %d results)\n",
95 g_timer_elapsed (state->timer, NULL), i);
97 g_object_unref(cursor);
98 cleanup(state);
99 return;
102 if (i++ < 5) {
103 int num_cols = tracker_sparql_cursor_get_n_columns(cursor);
104 int col;
106 if (i == 1) {
107 g_print("Printing first 5 results:\n");
109 for (col = 0; col < num_cols; col++) {
110 g_print(" %s ", tracker_sparql_cursor_get_string(
111 cursor, col, NULL));
112 if (col == num_cols -1 ) {
113 g_print("\n");
117 if (i == 5) {
118 g_print(" ...\n");
119 g_print(" Printing nothing for remaining results\n");
123 tracker_sparql_cursor_next_async(cursor,
124 state->cancellable,
125 cursor_cb,
126 state);
129 static void query_cb(GObject *object,
130 GAsyncResult *res,
131 gpointer user_data)
133 struct test_state *state = talloc_get_type_abort(
134 user_data, struct test_state);
135 TrackerSparqlCursor *cursor = NULL;
136 GError *error = NULL;
138 g_print("Async query took: %.6f\n", g_timer_elapsed(state->timer, NULL));
140 cursor = tracker_sparql_connection_query_finish(
141 TRACKER_SPARQL_CONNECTION(object),
142 res,
143 &error);
144 if (error) {
145 g_critical("Could not run query: %s", error->message);
147 if (cursor) {
148 g_object_unref(cursor);
151 g_error_free(error);
152 cleanup(state);
153 return;
156 g_timer_start(state->timer);
158 tracker_sparql_cursor_next_async(cursor,
159 state->cancellable,
160 cursor_cb,
161 state);
164 static void connection_cb(GObject *object,
165 GAsyncResult *res,
166 gpointer user_data)
168 struct test_state *state = talloc_get_type_abort(
169 user_data, struct test_state);
170 GError *error = NULL;
172 g_print("Async connection took: %.6f\n",
173 g_timer_elapsed(state->timer, NULL));
175 state->connection = tracker_sparql_connection_get_finish(res, &error);
176 if (error) {
177 g_critical("Could not connect: %s", error->message);
178 g_error_free(error);
179 cleanup(state);
180 return;
183 g_timer_start(state->timer);
185 tracker_sparql_connection_query_async(
186 state->connection,
187 "SELECT ?name nie:mimeType(?s) nfo:fileName(?s) "
188 "WHERE { {?s nie:url ?name}}",
189 state->cancellable,
190 query_cb,
191 state);
194 static void debug_fn(void *private_data,
195 enum tevent_debug_level level,
196 const char *fmt,
197 va_list ap)
199 dbgtext_va(fmt, ap);
202 int main(int argc, const char **argv)
204 TALLOC_CTX *mem_ctx = NULL;
205 struct test_state *state = NULL;
206 int c;
207 poptContext pc;
208 bool ok;
209 struct poptOption long_options[] = {
210 POPT_AUTOHELP
212 .longName = "tevent",
213 .shortName = 't',
214 .argInfo = POPT_ARG_NONE,
215 .val = 'v',
216 .descrip = "Use tevent loop",
219 .longName = "glib",
220 .shortName = 'g',
221 .argInfo = POPT_ARG_NONE,
222 .val = 'g',
223 .descrip = "Use glib loop",
225 POPT_COMMON_SAMBA
226 POPT_COMMON_VERSION
227 POPT_TABLEEND
230 mem_ctx = talloc_new(NULL);
231 if (mem_ctx == NULL) {
232 exit(1);
235 state = talloc_zero(mem_ctx, struct test_state);
236 if (state == NULL) {
237 exit(1);
240 state->loop_type = TEVENT_LOOP;
242 smb_init_locale();
244 ok = samba_cmdline_init(mem_ctx,
245 SAMBA_CMDLINE_CONFIG_CLIENT,
246 true /* require_smbconf */);
247 if (!ok) {
248 TALLOC_FREE(mem_ctx);
249 exit(1);
252 pc = samba_popt_get_context(getprogname(),
253 argc,
254 argv,
255 long_options,
256 POPT_CONTEXT_KEEP_FIRST);
257 if (pc == NULL) {
258 TALLOC_FREE(mem_ctx);
259 exit(1);
262 while ((c = poptGetNextOpt(pc)) != -1) {
263 switch (c) {
264 case 'g':
265 state->loop_type = GLIB_LOOP;
266 break;
267 case 't':
268 state->loop_type = TEVENT_LOOP;
269 break;
270 case POPT_ERROR_BADOPT:
271 fprintf(stderr, "\nInvalid option %s: %s\n\n",
272 poptBadOption(pc, 0), poptStrerror(c));
273 poptPrintUsage(pc, stderr, 0);
274 exit(1);
278 if (state->loop_type == GLIB_LOOP) {
279 state->loop = g_main_loop_new(NULL, false);
280 } else {
281 state->ev = tevent_context_init(mem_ctx);
282 if (CHECK_DEBUGLVL(10)) {
283 tevent_set_debug(state->ev, debug_fn, NULL);
285 state->glue = samba_tevent_glib_glue_create(
286 mem_ctx, state->ev, g_main_context_default());
287 if (state->glue == NULL) {
288 printf("tevent_glib_glue_create failed\n");
289 exit(1);
293 state->timer = g_timer_new();
294 state->cancellable = g_cancellable_new();
296 tracker_sparql_connection_get_async(state->cancellable,
297 connection_cb,
298 state);
300 if (state->loop_type == GLIB_LOOP) {
301 printf("entering g_main_loop_run\n");
302 g_main_loop_run(state->loop);
303 } else {
304 printf("entering tevent_loop_wait\n");
305 tevent_loop_wait(state->ev);
307 TALLOC_FREE(state->glue);
308 TALLOC_FREE(state->ev);
311 TALLOC_FREE(mem_ctx);
312 poptFreeContext(pc);
314 return 0;