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