tizen 2.3.1 release
[framework/telephony/libtcore.git] / src / storage.c
1 /*
2  * libtcore
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <glib.h>
26
27 #include "tcore.h"
28 #include "plugin.h"
29 #include "server.h"
30 #include "storage.h"
31
32 struct tcore_storage_type {
33         const char *name;
34         struct storage_operations *ops;
35         GHashTable *callback;
36
37         TcorePlugin *parent_plugin;
38 };
39
40 struct storage_callback_type{
41         TcoreStorageKeyCallback cb_fn;
42         void *user_data;
43 };
44
45 Storage *tcore_storage_new(TcorePlugin *plugin, const char *name,
46                 struct storage_operations *ops)
47 {
48         Storage *strg;
49
50         strg = calloc(1, sizeof(struct tcore_storage_type));
51         if (!strg)
52                 return NULL;
53
54         if (name)
55                 strg->name = strdup(name);
56
57         strg->parent_plugin = plugin;
58         strg->ops = ops;
59         strg->callback = g_hash_table_new_full(g_str_hash,g_str_equal, g_free, NULL);
60
61         tcore_server_add_storage(tcore_plugin_ref_server(plugin), strg);
62
63         return strg;
64 }
65
66 void tcore_storage_free(Storage *strg)
67 {
68         if (!strg)
69                 return;
70
71         if (strg->name)
72                 free((void *)strg->name);
73
74         free(strg);
75 }
76
77 const char *tcore_storage_ref_name(Storage *strg)
78 {
79         if (!strg)
80                 return NULL;
81
82         return strg->name;
83 }
84
85 void *tcore_storage_create_handle(Storage *strg, const char *path)
86 {
87         if (!path)
88                 return NULL;
89
90         if (!strg || !strg->ops || !strg->ops->create_handle) {
91                 return NULL;
92         }
93
94         return strg->ops->create_handle(strg, path);
95 }
96
97 gboolean tcore_storage_remove_handle(Storage *strg, void *handle)
98 {
99         if (!handle)
100                 return FALSE;
101
102         if (!strg || !strg->ops || !strg->ops->remove_handle) {
103                 return FALSE;
104         }
105
106         return strg->ops->remove_handle(strg, handle);
107 }
108
109 gboolean tcore_storage_set_int(Storage *strg, enum tcore_storage_key key,
110                 int value)
111 {
112         if (!strg || !strg->ops || !strg->ops->set_int) {
113                 return FALSE;
114         }
115
116         return strg->ops->set_int(strg, key, value);
117 }
118
119 gboolean tcore_storage_set_string(Storage *strg, enum tcore_storage_key key,
120                 const char *value)
121 {
122         if (!strg || !strg->ops || !strg->ops->set_string) {
123                 return FALSE;
124         }
125
126         return strg->ops->set_string(strg, key, value);
127 }
128
129 gboolean tcore_storage_set_bool(Storage *strg, enum tcore_storage_key key,
130                 gboolean value)
131 {
132         if (!strg || !strg->ops || !strg->ops->set_bool) {
133                 return FALSE;
134         }
135
136         return strg->ops->set_bool(strg, key, value);
137 }
138
139 int tcore_storage_get_int(Storage *strg, enum tcore_storage_key key)
140 {
141         if (!strg || !strg->ops || !strg->ops->get_int) {
142                 return -1;
143         }
144
145         return strg->ops->get_int(strg, key);
146 }
147
148 char *tcore_storage_get_string(Storage *strg, enum tcore_storage_key key)
149 {
150         if (!strg || !strg->ops || !strg->ops->get_string) {
151                 return NULL;
152         }
153
154         return strg->ops->get_string(strg, key);
155 }
156
157 gboolean tcore_storage_get_bool(Storage *strg, enum tcore_storage_key key)
158 {
159         if (!strg || !strg->ops || !strg->ops->get_bool) {
160                 return FALSE;
161         }
162
163         return strg->ops->get_bool(strg, key);
164 }
165
166 static void tcore_storage_vkey_callback_dispatcher(Storage *strg,
167                 enum tcore_storage_key key, void *value)
168 {
169         gchar *key_gen = NULL;
170         GSList *cb_data = NULL;
171         struct storage_callback_type *tmp_cb = NULL;
172
173         key_gen = g_strdup_printf("%d", key);
174         if (!key_gen)
175                 return;
176
177         cb_data = g_hash_table_lookup(strg->callback, key_gen);
178         while (cb_data) {
179                 tmp_cb = cb_data->data;
180                 if (tmp_cb)
181                         if (tmp_cb->cb_fn)
182                                 tmp_cb->cb_fn(key, value, tmp_cb->user_data);
183
184                 cb_data = g_slist_next(cb_data);
185         }
186
187         g_free(key_gen);
188 }
189
190 gboolean tcore_storage_set_key_callback(Storage *strg,
191                 enum tcore_storage_key key, TcoreStorageKeyCallback cb, void *user_data)
192 {
193         gpointer tmp = NULL;
194         gchar *key_gen = NULL;
195         struct storage_callback_type *strg_cb_data = NULL;
196         struct storage_callback_type *tmp_cb = NULL;
197
198         if (!strg || !strg->ops || !strg->ops->set_key_callback)
199         {
200                 return FALSE;
201         }
202
203         strg_cb_data = g_new0(struct storage_callback_type, 1);
204         strg_cb_data->cb_fn = cb;
205         strg_cb_data->user_data = user_data;
206
207         key_gen = g_strdup_printf("%d", key);
208         tmp = g_hash_table_lookup(strg->callback, key_gen);
209         if (tmp != NULL) {
210                 GSList *cb_data = tmp;
211
212                 while (cb_data) {
213                         tmp_cb = cb_data->data;
214                         if (tmp_cb) {
215                                 if ((tmp_cb->cb_fn == cb)
216                                                 && (tmp_cb->user_data == user_data)) {
217                                         g_free(key_gen);
218                                         g_free(strg_cb_data);
219                                         return FALSE;
220                                 }
221                         }
222
223                         cb_data = g_slist_next(cb_data);
224                 }
225
226                 tmp = g_slist_append(tmp, strg_cb_data);
227                 g_hash_table_replace(strg->callback, g_strdup(key_gen), tmp);
228         }
229         else {
230                 GSList *data = NULL;
231                 data = g_slist_append(data, strg_cb_data);
232                 g_hash_table_insert(strg->callback, g_strdup(key_gen), data);
233                 strg->ops->set_key_callback(strg, key, tcore_storage_vkey_callback_dispatcher);
234         }
235
236         g_free(key_gen);
237         return TRUE;
238 }
239
240 gboolean tcore_storage_remove_key_callback(Storage *strg,
241                 enum tcore_storage_key key, TcoreStorageKeyCallback cb)
242 {
243         GSList *tmp = NULL;
244         gchar *key_gen = NULL;
245         GSList *cb_data = NULL;
246         int cb_cnt = 0;
247         struct storage_callback_type *tmp_cb = NULL;
248
249         if (!strg || !strg->ops || !strg->ops->remove_key_callback) {
250                 return FALSE;
251         }
252
253         key_gen = g_strdup_printf("%d", key);
254         tmp = g_hash_table_lookup(strg->callback, key_gen);
255         if (tmp == NULL){
256                 g_free(key_gen);
257                 return FALSE;
258         }
259
260         cb_data = tmp;
261         while (cb_data) {
262                 tmp_cb = cb_data->data;
263                 if (tmp_cb) {
264                         if (tmp_cb->cb_fn == cb) {
265                                 tmp = g_slist_remove(tmp, tmp_cb);
266                                 g_free(tmp_cb);
267                                 break;
268                         }
269                 }
270
271                 cb_data = g_slist_next(cb_data);
272         }
273
274         cb_cnt = g_slist_length(tmp);
275         dbg("glist cnt (%d)", cb_cnt);
276
277         if (cb_cnt == 0) {
278                 g_hash_table_remove(strg->callback, key_gen);
279                 strg->ops->remove_key_callback(strg, key);
280         }
281
282         g_free(key_gen);
283         return TRUE;
284 }
285
286 gboolean tcore_storage_update_query_database(Storage *strg, void *handle,
287                 const char *query, GHashTable *in_param)
288 {
289         if (!strg || !handle || !query)
290                 return FALSE;
291
292         if (!strg->ops || !strg->ops->update_query_database) {
293                 return FALSE;
294         }
295
296         return strg->ops->update_query_database(strg, handle, query, in_param);
297 }
298
299 gboolean tcore_storage_read_query_database(Storage *strg, void *handle,
300                 const char *query, GHashTable *in_param,
301                 GHashTable *out_param, int out_param_cnt)
302 {
303         if (!strg || !handle || !query)
304                 return FALSE;
305
306         if (!strg->ops || !strg->ops->read_query_database) {
307                 return FALSE;
308         }
309
310         return strg->ops->read_query_database(strg, handle, query,
311                         in_param, out_param, out_param_cnt);
312 }
313
314 gboolean tcore_storage_insert_query_database(Storage *strg, void *handle,
315                 const char *query, GHashTable *in_param)
316 {
317         if (!strg || !handle || !query)
318                 return FALSE;
319
320         if (!strg->ops || !strg->ops->insert_query_database) {
321                 return FALSE;
322         }
323
324         return strg->ops->insert_query_database(strg, handle, query, in_param);
325 }
326
327 gboolean tcore_storage_remove_query_database(Storage *strg, void *handle,
328                 const char *query, GHashTable *in_param)
329 {
330         if (!strg || !handle || !query)
331                 return FALSE;
332
333         if (!strg->ops || !strg->ops->remove_query_database) {
334                 return FALSE;
335         }
336
337         return strg->ops->remove_query_database(strg, handle, query, in_param);
338 }