No issues found
1 /*
2 * Copyright (C) 2009, 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 General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 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 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU 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 * Authors:
20 * Philip Van Hoof <philip@codeminded.be>
21 */
22
23 #include "config.h"
24
25 #include <libtracker-data/tracker-data.h>
26
27 #include "tracker-writeback.h"
28
29 typedef struct {
30 GHashTable *allowances;
31 GHashTable *pending_events;
32 GHashTable *ready_events;
33 } WritebackPrivate;
34
35 static WritebackPrivate *private;
36
37 static GArray*
38 rdf_types_to_array (GPtrArray *rdf_types)
39 {
40 GArray *new_types;
41 guint n;
42
43 new_types = g_array_sized_new (FALSE, FALSE, sizeof (gint), rdf_types->len);
44
45 for (n = 0; n < rdf_types->len; n++) {
46 gint id = tracker_class_get_id (rdf_types->pdata[n]);
47 g_array_append_val (new_types, id);
48 }
49
50 return new_types;
51 }
52
53 static void
54 array_free (GArray *array)
55 {
56 g_array_free (array, TRUE);
57 }
58
59 void
60 tracker_writeback_check (gint graph_id,
61 const gchar *graph,
62 gint subject_id,
63 const gchar *subject,
64 gint pred_id,
65 gint object_id,
66 const gchar *object,
67 GPtrArray *rdf_types)
68 {
69 /* When graph is NULL, the graph is the default one. We only do
70 * writeback reporting in the default graph (update queries that
71 * aren't coming from the miner)
72 */
73
74 if (graph != NULL) {
75 /* g_debug ("Not doing writeback check, no graph"); */
76 return;
77 }
78
79 g_return_if_fail (private != NULL);
80
81 if (g_hash_table_lookup (private->allowances, GINT_TO_POINTER (pred_id))) {
82 if (!private->pending_events) {
83 private->pending_events = g_hash_table_new_full (g_direct_hash, g_direct_equal,
84 (GDestroyNotify) NULL,
85 (GDestroyNotify) NULL);
86 }
87
88 g_hash_table_insert (private->pending_events,
89 GINT_TO_POINTER (subject_id),
90 rdf_types_to_array (rdf_types));
91 }
92 }
93
94 void
95 tracker_writeback_reset_pending ()
96 {
97 g_return_if_fail (private != NULL);
98
99 if (private->pending_events) {
100 g_hash_table_remove_all (private->pending_events);
101 }
102 }
103
104 void
105 tracker_writeback_reset_ready ()
106 {
107 g_return_if_fail (private != NULL);
108
109 if (private->ready_events) {
110 g_hash_table_unref (private->ready_events);
111 private->ready_events = NULL;
112 }
113 }
114
115 GHashTable *
116 tracker_writeback_get_ready (void)
117 {
118 g_return_val_if_fail (private != NULL, NULL);
119
120 return private->ready_events;
121 }
122
123 static void
124 free_private (gpointer user_data)
125 {
126 WritebackPrivate *private;
127
128 private = user_data;
129 if (private->ready_events)
130 g_hash_table_unref (private->ready_events);
131 if (private->pending_events)
132 g_hash_table_unref (private->pending_events);
133 g_hash_table_unref (private->allowances);
134 g_free (private);
135 }
136
137 void
138 tracker_writeback_init (TrackerWritebackGetPredicatesFunc func)
139 {
140 GStrv predicates_to_signal;
141 gint i, count;
142
143 g_return_if_fail (private == NULL);
144
145 private = g_new0 (WritebackPrivate, 1);
146
147 private->allowances = g_hash_table_new_full (g_direct_hash,
148 g_direct_equal,
149 NULL,
150 NULL);
151
152 g_message ("Setting up predicates for writeback notification...");
153
154 if (!func) {
155 g_message (" No predicates set, no TrackerWritebackGetPredicatesFunc");
156 return;
157 }
158
159 predicates_to_signal = (*func)();
160
161 if (!predicates_to_signal) {
162 g_message (" No predicates set, none are configured in ontology");
163 return;
164 }
165
166 count = g_strv_length (predicates_to_signal);
167
168 for (i = 0; i < count; i++) {
169 TrackerProperty *predicate = tracker_ontologies_get_property_by_uri (predicates_to_signal[i]);
170 if (predicate) {
171 gint id = tracker_property_get_id (predicate);
172 g_message (" Adding:'%s'", predicates_to_signal[i]);
173 g_hash_table_insert (private->allowances,
174 GINT_TO_POINTER (id),
175 GINT_TO_POINTER (TRUE));
176 }
177 }
178
179 g_strfreev (predicates_to_signal);
180 }
181
182 void
183 tracker_writeback_transact (void)
184 {
185 GHashTableIter iter;
186 gpointer key, value;
187
188 if (!private->pending_events)
189 return;
190
191 if (!private->ready_events) {
192 private->ready_events = g_hash_table_new_full (g_direct_hash, g_direct_equal,
193 (GDestroyNotify) NULL,
194 (GDestroyNotify) array_free);
195 }
196
197 g_hash_table_iter_init (&iter, private->pending_events);
198
199 while (g_hash_table_iter_next (&iter, &key, &value)) {
200 g_hash_table_insert (private->ready_events, key, value);
201 g_hash_table_iter_remove (&iter);
202 }
203 }
204
205 void
206 tracker_writeback_shutdown (void)
207 {
208 g_return_if_fail (private != NULL);
209
210 tracker_writeback_reset_pending ();
211
212 /* Perhaps hurry an emit of the ready events here? We're shutting down,
213 * so I guess we're not required to do that here ... ? */
214 tracker_writeback_reset_ready ();
215
216 free_private (private);
217 private = NULL;
218 }