Fix svace issue
[platform/core/telephony/tel-plugin-database.git] / src / database_main.c
index fe328b1..0b21d2e 100644 (file)
 #include <strings.h>
 
 #include <glib.h>
-#include <db-util.h>
+#include <sqlite3.h>
+#include <unistd.h>
 
 #include <tcore.h>
+#include <server.h>
 #include <plugin.h>
 #include <storage.h>
 
 #define PLUGIN_VERSION 1
 #endif
 
-static void *create_handle(Storage *strg, const char *path)
-{
-       int rv = 0;
-       sqlite3 *handle = NULL;
+#define BUSY_WAITING_USEC 50000 /* 0.05 sec */
+#define BUSY_WAITING_MAX 20 /* wait for max 1 sec */
 
-       rv = db_util_open(path, &handle, 0);
-       if (rv != SQLITE_OK) {
-               err("fail to connect database err(%d)", rv);
-               return NULL;
-       }
-
-       dbg("connected to %s", path);
-       return handle;
-}
 
-static gboolean remove_handle(Storage *strg, void *handle)
-{
-       if (!handle)
-               return FALSE;
-
-       db_util_close(handle);
-
-       dbg("disconnected from database");
-       return TRUE;
-}
-
-static gboolean update_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
+static gboolean __update_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
 {
        int rv = 0;
        sqlite3_stmt *stmt = NULL;
@@ -97,11 +77,16 @@ static gboolean update_query_database(Storage *strg, void *handle, const char *q
 
                        if (rv != SQLITE_OK) {
                                dbg("fail to bind data (%d)", rv);
-                               return FALSE;
+                               break;
                        }
                }
        }
 
+       if (rv != SQLITE_OK) {
+               sqlite3_finalize(stmt);
+               return FALSE;
+       }
+
        rv = sqlite3_step(stmt);
        dbg("update query executed (%d)", rv);
        sqlite3_finalize(stmt);
@@ -112,6 +97,73 @@ static gboolean update_query_database(Storage *strg, void *handle, const char *q
        return TRUE;
 }
 
+static int _busy_handler(void *pData, int count)
+{
+        if (count < BUSY_WAITING_MAX) {
+               usleep(BUSY_WAITING_USEC);
+               return 1;
+       }
+
+       dbg("Busy Handler will be returned SQLITE_BUSY error\n");
+       return 0;
+}
+
+static void *create_handle(Storage *strg, const char *path)
+{
+       int rv = 0;
+       sqlite3 *handle = NULL;
+
+       if (path == NULL) {
+               err("Invalid input param error");
+               return NULL;
+       }
+
+       rv = sqlite3_open(path, &handle);
+       if (rv != SQLITE_OK) {
+               err("fail to connect database err(%d), errmsg(%s)", rv, sqlite3_errmsg(handle));
+               return NULL;
+       }
+
+       rv = sqlite3_busy_handler(handle, _busy_handler, NULL);
+       if (rv != SQLITE_OK) {
+               err("fail to register busy handler err(%d), errmsg(%s)", rv, sqlite3_errmsg(handle));
+               sqlite3_close(handle);
+               return NULL;
+       }
+
+       dbg("connected to %s", path);
+       return handle;
+}
+
+static gboolean remove_handle(Storage *strg, void *handle)
+{
+       int rv = 0;
+
+       if (!handle)
+               return FALSE;
+
+       rv = sqlite3_close(handle);
+       if (rv != SQLITE_OK) {
+               err("fail to close database err(%d)", rv);
+               handle = NULL;
+               return FALSE;
+       }
+
+       dbg("disconnected from database");
+       return TRUE;
+}
+
+static gboolean update_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
+{
+       gboolean ret = TRUE;
+
+       dbg("update query");
+
+       ret = __update_query_database(strg, handle, query, in_param);
+
+       return ret;
+}
+
 static gboolean _read_query_database_internal(Storage *strg, void *handle, const char *query, GHashTable *in_param,
                gpointer out_param, int out_param_cnt, gboolean in_order)
 {
@@ -149,11 +201,16 @@ static gboolean _read_query_database_internal(Storage *strg, void *handle, const
 
                        if (rv != SQLITE_OK) {
                                dbg("fail to bind data (%d)", rv);
-                               return FALSE;
+                               break;
                        }
                }
        }
 
+       if (rv != SQLITE_OK) {
+               sqlite3_finalize(stmt);
+               return FALSE;
+       }
+
        rv = sqlite3_step(stmt);
        dbg("read query executed (%d), in_order (%d)", rv, in_order);
 
@@ -163,7 +220,7 @@ static gboolean _read_query_database_internal(Storage *strg, void *handle, const
                out_param_data = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 
                for (local_index = 0; local_index < out_param_cnt; local_index++) {
-                       char tmp_key[10];
+                       char tmp_key[32];
                        const unsigned char *tmp;
                        tmp = sqlite3_column_text(stmt, local_index);
                        snprintf(tmp_key, sizeof(tmp_key), "%d", local_index);
@@ -174,7 +231,7 @@ static gboolean _read_query_database_internal(Storage *strg, void *handle, const
                        GSList **temp = out_param;
                        *temp = g_slist_append(*temp, out_param_data);
                } else {
-                       char tmp_key_outter[10];
+                       char tmp_key_outter[32];
                        snprintf(tmp_key_outter, sizeof(tmp_key_outter), "%d", outter_index);
                        g_hash_table_insert((GHashTable*)out_param, g_strdup(tmp_key_outter), out_param_data);
                }
@@ -187,16 +244,34 @@ static gboolean _read_query_database_internal(Storage *strg, void *handle, const
 }
 
 static gboolean read_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param,
-               GHashTable *out_param, int out_param_cnt)
+               GHashTable **out_param, int out_param_cnt)
 {
-       _read_query_database_internal(strg, handle, query, in_param, out_param, out_param_cnt, FALSE);
+       GHashTable *out_hash_table;
+
+       if (out_param == NULL)
+               return FALSE;
+
+       out_hash_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+                       g_free, (GDestroyNotify)g_hash_table_destroy);
+
+       if (_read_query_database_internal(strg,
+                       handle, query, in_param, out_hash_table, out_param_cnt, FALSE) == FALSE) {
+               g_hash_table_destroy(out_hash_table);
+               return FALSE;
+       }
+
+       *out_param = out_hash_table;
+
        return TRUE;
 }
 
 static gboolean read_query_database_in_order(Storage *strg, void *handle, const char *query, GHashTable *in_param,
                GSList **out_param, int out_param_cnt)
 {
-       _read_query_database_internal(strg, handle, query, in_param, out_param, out_param_cnt, TRUE);
+       if (_read_query_database_internal(strg,
+                       handle, query, in_param, out_param, out_param_cnt, TRUE) == FALSE)
+               return FALSE;
+
        return TRUE;
 }
 
@@ -235,11 +310,16 @@ static gboolean insert_query_database(Storage *strg, void *handle, const char *q
 
                        if (rv != SQLITE_OK) {
                                dbg("fail to bind data (%d)", rv);
-                               return FALSE;
+                               break;
                        }
                }
        }
 
+       if (rv != SQLITE_OK) {
+               sqlite3_finalize(stmt);
+               return FALSE;
+       }
+
        rv = sqlite3_step(stmt);
        dbg("insert query executed (%d)", rv);
        sqlite3_finalize(stmt);
@@ -252,52 +332,13 @@ static gboolean insert_query_database(Storage *strg, void *handle, const char *q
 
 static gboolean remove_query_database(Storage *strg, void *handle, const char *query, GHashTable *in_param)
 {
-       int rv = 0;
-       sqlite3_stmt *stmt = NULL;
-       char szQuery[1000+1];   /* +1 is for NULL Termination Character '\0' */
+       gboolean ret = TRUE;
 
-       GHashTableIter iter;
-       gpointer key, value;
        dbg("remove query");
 
-       memset(szQuery, '\0', 1001);
-       strncpy(szQuery, query, 1000);
+       ret = __update_query_database(strg, handle, query, in_param);
 
-       rv = sqlite3_prepare_v2(handle, szQuery, strlen(szQuery), &stmt, NULL);
-       if (rv != SQLITE_OK) {
-               err("fail to connect to table (%d)", rv);
-               return FALSE;
-       }
-
-       if (in_param) {
-               g_hash_table_iter_init(&iter, in_param);
-               while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
-                       dbg("key(%s), value(%s)", (const char *)key, (const char *)value);
-
-                       if (!value || g_strcmp0((const char *)value, "") == 0) {
-                               dbg("bind null");
-                               rv = sqlite3_bind_null(stmt, atoi((const char *)key));
-                       } else {
-                               dbg("bind value");
-                               rv = sqlite3_bind_text(stmt, atoi((const char *)key), (const char *)value, strlen((const char *)value),
-                                               SQLITE_STATIC);
-                       }
-
-                       if (rv != SQLITE_OK) {
-                               dbg("fail to bind data (%d)", rv);
-                               return FALSE;
-                       }
-               }
-       }
-
-       rv = sqlite3_step(stmt);
-       dbg("remove query executed (%d)", rv);
-       sqlite3_finalize(stmt);
-
-       if (rv != SQLITE_DONE)
-               return FALSE;
-
-       return TRUE;
+       return ret;
 }
 
 static struct storage_operations ops = {
@@ -329,8 +370,20 @@ static gboolean on_init(TcorePlugin *p)
 
 static void on_unload(TcorePlugin *p)
 {
+       Storage *strg;
+
+       if (!p)
+               return;
+
        dbg("i'm unload!");
+
+       strg = tcore_server_find_storage(tcore_plugin_ref_server(p), "database");
+       if (!strg)
+               return;
+
+       tcore_storage_free(strg);
        return;
+
 }
 
 EXPORT_API struct tcore_plugin_define_desc plugin_define_desc = {