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