Sync from SPIN branch
[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                                 return FALSE;
101                         }
102                 }
103         }
104
105         rv = sqlite3_step(stmt);
106         dbg("update query executed (%d)", rv);
107         sqlite3_finalize(stmt);
108
109         if (rv != SQLITE_DONE)
110                 return FALSE;
111
112         return TRUE;
113 }
114
115 static gboolean _read_query_database_internal(Storage *strg, void *handle, const char *query, GHashTable *in_param,
116                 gpointer out_param, int out_param_cnt, gboolean in_order)
117 {
118         int rv = 0, local_index = 0, outter_index = 0;
119         sqlite3_stmt *stmt = NULL;
120         char szQuery[5000+1];   /* +1 is for NULL Termination Character '\0' */
121
122         GHashTableIter iter;
123         gpointer key, value;
124
125         dbg("read query");
126
127         memset(szQuery, '\0', 5001);
128         strncpy(szQuery, query, 5000);
129
130         rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
131         if (rv != SQLITE_OK) {
132                 err("fail to connect to table (%d)", rv);
133                 return FALSE;
134         }
135
136         if (in_param) {
137                 g_hash_table_iter_init(&iter, in_param);
138                 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
139                         dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
140
141                         if (!value || g_strcmp0((const char *)value, "") == 0) {
142                                 dbg("bind null");
143                                 rv = sqlite3_bind_null(stmt, atoi((const char *)key));
144                         } else {
145                                 dbg("bind value");
146                                 rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
147                                                 SQLITE_STATIC);
148                         }
149
150                         if (rv != SQLITE_OK) {
151                                 dbg("fail to bind data (%d)", rv);
152                                 return FALSE;
153                         }
154                 }
155         }
156
157         rv = sqlite3_step(stmt);
158         dbg("read query executed (%d), in_order (%d)", rv, in_order);
159
160         while (rv == SQLITE_ROW) {
161                 GHashTable *out_param_data;
162
163                 out_param_data = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
164
165                 for (local_index = 0; local_index < out_param_cnt; local_index++) {
166                         char tmp_key[10];
167                         const unsigned char *tmp;
168                         tmp = sqlite3_column_text(stmt, local_index);
169                         snprintf(tmp_key, sizeof(tmp_key), "%d", local_index);
170                         g_hash_table_insert(out_param_data, g_strdup(tmp_key), g_strdup((const char *)tmp));
171                 }
172
173                 if (in_order) {
174                         GSList **temp = out_param;
175                         *temp = g_slist_append(*temp, out_param_data);
176                 } else {
177                         char tmp_key_outter[10];
178                         snprintf(tmp_key_outter, sizeof(tmp_key_outter), "%d", outter_index);
179                         g_hash_table_insert((GHashTable*)out_param, g_strdup(tmp_key_outter), out_param_data);
180                 }
181                 outter_index++;
182                 rv = sqlite3_step(stmt);
183         }
184
185         sqlite3_finalize(stmt);
186         return TRUE;
187 }
188
189 static gboolean read_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param,
190                 GHashTable *out_param, int out_param_cnt)
191 {
192         _read_query_database_internal(strg, handle, query, in_param, out_param, out_param_cnt, FALSE);
193         return TRUE;
194 }
195
196 static gboolean read_query_database_in_order(Storage *strg, void *handle, const char *query, GHashTable *in_param,
197                 GSList **out_param, int out_param_cnt)
198 {
199         _read_query_database_internal(strg, handle, query, in_param, out_param, out_param_cnt, TRUE);
200         return TRUE;
201 }
202
203 static gboolean insert_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
204 {
205         int rv = 0;
206         sqlite3_stmt *stmt = NULL;
207         char szQuery[5000+1];   /* +1 is for NULL Termination Character '\0' */
208
209         GHashTableIter iter;
210         gpointer key, value;
211         dbg("insert query");
212
213         memset(szQuery, '\0', 5001);
214         strncpy(szQuery, query, 5000);
215
216         rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
217         if (rv != SQLITE_OK) {
218                 err("fail to connect to table (%d)", rv);
219                 return FALSE;
220         }
221
222         if (in_param) {
223                 g_hash_table_iter_init(&iter, in_param);
224                 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
225                         dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
226
227                         if (!value || g_strcmp0((const char *)value, "") == 0) {
228                                 dbg("bind null");
229                                 rv = sqlite3_bind_null(stmt, atoi((const char *)key));
230                         } else {
231                                 dbg("bind value");
232                                 rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
233                                                 SQLITE_STATIC);
234                         }
235
236                         if (rv != SQLITE_OK) {
237                                 dbg("fail to bind data (%d)", rv);
238                                 return FALSE;
239                         }
240                 }
241         }
242
243         rv = sqlite3_step(stmt);
244         dbg("insert query executed (%d)", rv);
245         sqlite3_finalize(stmt);
246
247         if (rv != SQLITE_DONE)
248                 return FALSE;
249
250         return TRUE;
251 }
252
253 static gboolean remove_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
254 {
255         int rv = 0;
256         sqlite3_stmt *stmt = NULL;
257         char szQuery[1000+1];   /* +1 is for NULL Termination Character '\0' */
258
259         GHashTableIter iter;
260         gpointer key, value;
261         dbg("remove query");
262
263         memset(szQuery, '\0', 1001);
264         strncpy(szQuery, query, 1000);
265
266         rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
267         if (rv != SQLITE_OK) {
268                 err("fail to connect to table (%d)", rv);
269                 return FALSE;
270         }
271
272         if (in_param) {
273                 g_hash_table_iter_init(&iter, in_param);
274                 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
275                         dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
276
277                         if (!value || g_strcmp0((const char *)value, "") == 0) {
278                                 dbg("bind null");
279                                 rv = sqlite3_bind_null(stmt, atoi((const char *)key));
280                         } else {
281                                 dbg("bind value");
282                                 rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
283                                                 SQLITE_STATIC);
284                         }
285
286                         if (rv != SQLITE_OK) {
287                                 dbg("fail to bind data (%d)", rv);
288                                 return FALSE;
289                         }
290                 }
291         }
292
293         rv = sqlite3_step(stmt);
294         dbg("remove query executed (%d)", rv);
295         sqlite3_finalize(stmt);
296
297         if (rv != SQLITE_DONE)
298                 return FALSE;
299
300         return TRUE;
301 }
302
303 static struct storage_operations ops = {
304         .create_handle = create_handle,
305         .remove_handle = remove_handle,
306         .update_query_database = update_query_database,
307         .read_query_database = read_query_database,
308         .read_query_database_in_order = read_query_database_in_order,
309         .insert_query_database = insert_query_database,
310         .remove_query_database = remove_query_database,
311 };
312
313 static gboolean on_load()
314 {
315         dbg("i'm load!");
316         return TRUE;
317 }
318
319 static gboolean on_init(TcorePlugin *p)
320 {
321         if (!p)
322                 return FALSE;
323
324         tcore_storage_new(p, "database", &ops);
325
326         dbg("finish to initialize database plug-in");
327         return TRUE;
328 }
329
330 static void on_unload(TcorePlugin *p)
331 {
332         dbg("i'm unload!");
333         return;
334 }
335
336 EXPORT_API struct tcore_plugin_define_desc plugin_define_desc = {
337         .name = "DATABASE",
338         .priority = TCORE_PLUGIN_PRIORITY_HIGH - 1,
339         .version = PLUGIN_VERSION,
340         .load = on_load,
341         .init = on_init,
342         .unload = on_unload
343 };