Fix coverity issue (CID 863700)
[platform/core/telephony/tel-plugin-database.git] / src / database_main.c
1 /*
2  * tel-plugin-database
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: DongHoo Park <donghoo.park@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
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <strings.h>
26
27 #include <glib.h>
28 #include <db-util.h>
29
30 #include <tcore.h>
31 #include <server.h>
32 #include <plugin.h>
33 #include <storage.h>
34
35 #ifndef PLUGIN_VERSION
36 #define PLUGIN_VERSION 1
37 #endif
38
39 static void *create_handle(Storage *strg, const char *path)
40 {
41         int rv = 0;
42         sqlite3 *handle = NULL;
43
44         rv = db_util_open(path, &handle, 0);
45         if (rv != SQLITE_OK) {
46                 err("fail to connect database err(%d)", rv);
47                 return NULL;
48         }
49
50         dbg("connected to %s", path);
51         return handle;
52 }
53
54 static gboolean remove_handle(Storage *strg, void *handle)
55 {
56         int rv = 0;
57
58         if (!handle)
59                 return FALSE;
60
61         rv = db_util_close(handle);
62         if (rv != SQLITE_OK) {
63                 err("fail to close database err(%d)", rv);
64                 handle = NULL;
65                 return FALSE;
66         }
67
68         dbg("disconnected from database");
69         return TRUE;
70 }
71
72 static gboolean update_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
73 {
74         int rv = 0;
75         sqlite3_stmt *stmt = NULL;
76         char szQuery[1000+1];   /* +1 is for NULL Termination Character '\0' */
77
78         GHashTableIter iter;
79         gpointer key, value;
80
81         dbg("update query");
82
83         memset(szQuery, '\0', 1001);
84         strncpy(szQuery, query, 1000);
85
86         rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
87         if (rv != SQLITE_OK) {
88                 err("fail to connect to table (%d)", rv);
89                 return FALSE;
90         }
91
92         if (in_param) {
93                 g_hash_table_iter_init(&iter, in_param);
94                 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
95                         dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
96
97                         if (!value || g_strcmp0((const char *)value, "") == 0) {
98                                 dbg("bind null");
99                                 rv = sqlite3_bind_null(stmt, atoi((const char *)key));
100                         } else {
101                                 dbg("bind value");
102                                 rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
103                                                 SQLITE_STATIC);
104                         }
105
106                         if (rv != SQLITE_OK) {
107                                 dbg("fail to bind data (%d)", rv);
108                                 break;
109                         }
110                 }
111         }
112
113         if (rv != SQLITE_OK) {
114                 sqlite3_finalize(stmt);
115                 return FALSE;
116         }
117
118         rv = sqlite3_step(stmt);
119         dbg("update query executed (%d)", rv);
120         sqlite3_finalize(stmt);
121
122         if (rv != SQLITE_DONE)
123                 return FALSE;
124
125         return TRUE;
126 }
127
128 static gboolean _read_query_database_internal(Storage *strg, void *handle, const char *query, GHashTable *in_param,
129                 gpointer out_param, int out_param_cnt, gboolean in_order)
130 {
131         int rv = 0, local_index = 0, outter_index = 0;
132         sqlite3_stmt *stmt = NULL;
133         char szQuery[5000+1];   /* +1 is for NULL Termination Character '\0' */
134
135         GHashTableIter iter;
136         gpointer key, value;
137
138         dbg("read query");
139
140         memset(szQuery, '\0', 5001);
141         strncpy(szQuery, query, 5000);
142
143         rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
144         if (rv != SQLITE_OK) {
145                 err("fail to connect to table (%d)", rv);
146                 return FALSE;
147         }
148
149         if (in_param) {
150                 g_hash_table_iter_init(&iter, in_param);
151                 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
152                         dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
153
154                         if (!value || g_strcmp0((const char *)value, "") == 0) {
155                                 dbg("bind null");
156                                 rv = sqlite3_bind_null(stmt, atoi((const char *)key));
157                         } else {
158                                 dbg("bind value");
159                                 rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
160                                                 SQLITE_STATIC);
161                         }
162
163                         if (rv != SQLITE_OK) {
164                                 dbg("fail to bind data (%d)", rv);
165                                 break;
166                         }
167                 }
168         }
169
170         if (rv != SQLITE_OK) {
171                 sqlite3_finalize(stmt);
172                 return FALSE;
173         }
174
175         rv = sqlite3_step(stmt);
176         dbg("read query executed (%d), in_order (%d)", rv, in_order);
177
178         while (rv == SQLITE_ROW) {
179                 GHashTable *out_param_data;
180
181                 out_param_data = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
182
183                 for (local_index = 0; local_index < out_param_cnt; local_index++) {
184                         char tmp_key[10];
185                         const unsigned char *tmp;
186                         tmp = sqlite3_column_text(stmt, local_index);
187                         snprintf(tmp_key, sizeof(tmp_key), "%d", local_index);
188                         g_hash_table_insert(out_param_data, g_strdup(tmp_key), g_strdup((const char *)tmp));
189                 }
190
191                 if (in_order) {
192                         GSList **temp = out_param;
193                         *temp = g_slist_append(*temp, out_param_data);
194                 } else {
195                         char tmp_key_outter[10];
196                         snprintf(tmp_key_outter, sizeof(tmp_key_outter), "%d", outter_index);
197                         g_hash_table_insert((GHashTable*)out_param, g_strdup(tmp_key_outter), out_param_data);
198                 }
199                 outter_index++;
200                 rv = sqlite3_step(stmt);
201         }
202
203         sqlite3_finalize(stmt);
204         return TRUE;
205 }
206
207 static gboolean read_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param,
208                 GHashTable **out_param, int out_param_cnt)
209 {
210         GHashTable *out_hash_table;
211
212         if (out_param == NULL)
213                 return FALSE;
214
215         out_hash_table = g_hash_table_new_full(g_str_hash, g_str_equal,
216                         g_free, (GDestroyNotify)g_hash_table_destroy);
217
218         if (_read_query_database_internal(strg,
219                         handle, query, in_param, out_hash_table, out_param_cnt, FALSE) == FALSE) {
220                 g_hash_table_destroy(out_hash_table);
221                 return FALSE;
222         }
223
224         *out_param = out_hash_table;
225
226         return TRUE;
227 }
228
229 static gboolean read_query_database_in_order(Storage *strg, void *handle, const char *query, GHashTable *in_param,
230                 GSList **out_param, int out_param_cnt)
231 {
232         if (_read_query_database_internal(strg,
233                         handle, query, in_param, out_param, out_param_cnt, TRUE) == FALSE)
234                 return FALSE;
235
236         return TRUE;
237 }
238
239 static gboolean insert_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
240 {
241         int rv = 0;
242         sqlite3_stmt *stmt = NULL;
243         char szQuery[5000+1];   /* +1 is for NULL Termination Character '\0' */
244
245         GHashTableIter iter;
246         gpointer key, value;
247         dbg("insert query");
248
249         memset(szQuery, '\0', 5001);
250         strncpy(szQuery, query, 5000);
251
252         rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
253         if (rv != SQLITE_OK) {
254                 err("fail to connect to table (%d)", rv);
255                 return FALSE;
256         }
257
258         if (in_param) {
259                 g_hash_table_iter_init(&iter, in_param);
260                 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
261                         dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
262
263                         if (!value || g_strcmp0((const char *)value, "") == 0) {
264                                 dbg("bind null");
265                                 rv = sqlite3_bind_null(stmt, atoi((const char *)key));
266                         } else {
267                                 dbg("bind value");
268                                 rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
269                                                 SQLITE_STATIC);
270                         }
271
272                         if (rv != SQLITE_OK) {
273                                 dbg("fail to bind data (%d)", rv);
274                                 break;
275                         }
276                 }
277         }
278
279         if (rv != SQLITE_OK) {
280                 sqlite3_finalize(stmt);
281                 return FALSE;
282         }
283
284         rv = sqlite3_step(stmt);
285         dbg("insert query executed (%d)", rv);
286         sqlite3_finalize(stmt);
287
288         if (rv != SQLITE_DONE)
289                 return FALSE;
290
291         return TRUE;
292 }
293
294 static gboolean remove_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
295 {
296         int rv = 0;
297         sqlite3_stmt *stmt = NULL;
298         char szQuery[1000+1];   /* +1 is for NULL Termination Character '\0' */
299
300         GHashTableIter iter;
301         gpointer key, value;
302         dbg("remove query");
303
304         memset(szQuery, '\0', 1001);
305         strncpy(szQuery, query, 1000);
306
307         rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
308         if (rv != SQLITE_OK) {
309                 err("fail to connect to table (%d)", rv);
310                 return FALSE;
311         }
312
313         if (in_param) {
314                 g_hash_table_iter_init(&iter, in_param);
315                 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
316                         dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
317
318                         if (!value || g_strcmp0((const char *)value, "") == 0) {
319                                 dbg("bind null");
320                                 rv = sqlite3_bind_null(stmt, atoi((const char *)key));
321                         } else {
322                                 dbg("bind value");
323                                 rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
324                                                 SQLITE_STATIC);
325                         }
326
327                         if (rv != SQLITE_OK) {
328                                 dbg("fail to bind data (%d)", rv);
329                                 break;
330                         }
331                 }
332         }
333
334         if (rv != SQLITE_OK) {
335                 sqlite3_finalize(stmt);
336                 return FALSE;
337         }
338
339         rv = sqlite3_step(stmt);
340         dbg("remove query executed (%d)", rv);
341         sqlite3_finalize(stmt);
342
343         if (rv != SQLITE_DONE)
344                 return FALSE;
345
346         return TRUE;
347 }
348
349 static struct storage_operations ops = {
350         .create_handle = create_handle,
351         .remove_handle = remove_handle,
352         .update_query_database = update_query_database,
353         .read_query_database = read_query_database,
354         .read_query_database_in_order = read_query_database_in_order,
355         .insert_query_database = insert_query_database,
356         .remove_query_database = remove_query_database,
357 };
358
359 static gboolean on_load()
360 {
361         dbg("i'm load!");
362         return TRUE;
363 }
364
365 static gboolean on_init(TcorePlugin *p)
366 {
367         if (!p)
368                 return FALSE;
369
370         tcore_storage_new(p, "database", &ops);
371
372         dbg("finish to initialize database plug-in");
373         return TRUE;
374 }
375
376 static void on_unload(TcorePlugin *p)
377 {
378         Storage *strg;
379
380         if (!p)
381                 return;
382
383         dbg("i'm unload!");
384
385         strg = tcore_server_find_storage(tcore_plugin_ref_server(p), "database");
386         if (!strg)
387                 return;
388
389         tcore_storage_free(strg);
390         return;
391
392 }
393
394 EXPORT_API struct tcore_plugin_define_desc plugin_define_desc = {
395         .name = "DATABASE",
396         .priority = TCORE_PLUGIN_PRIORITY_HIGH - 1,
397         .version = PLUGIN_VERSION,
398         .load = on_load,
399         .init = on_init,
400         .unload = on_unload
401 };