Implement the DB I/O component
authorSung-jae Park <nicesj.park@samsung.com>
Wed, 10 Oct 2012 01:22:44 +0000 (10:22 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Wed, 10 Oct 2012 05:18:55 +0000 (14:18 +0900)
Change-Id: I518e4e323025e9e634e87fd16cddd44e0f876d29

CMakeLists.txt
debian/changelog
include/io.h [new file with mode: 0644]
include/livebox.h
packaging/liblivebox-viewer.spec
src/io.c [new file with mode: 0644]
src/livebox.c

index 7ef0a8e..7e31fad 100644 (file)
@@ -22,6 +22,8 @@ pkg_check_modules(pkgs REQUIRED
        com-core
        x11
        xext
+       sqlite3
+       db-util
 )
 
 FOREACH(flag ${pkgs_CFLAGS})
@@ -48,6 +50,7 @@ ADD_LIBRARY(${PROJECT_NAME} SHARED
        src/master_rpc.c
        src/client.c
        src/critical_log.c
+       src/io.c
 )
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
index c0d4e94..287cd7a 100644 (file)
@@ -1,3 +1,10 @@
+livebox-viewer (0.6.6) unstable; urgency=low
+
+  * Git: slp/pkgs/l/livebox-viewer
+  * Tag: livebox-viewer_0.6.6
+
+ -- Sung-jae Park <nicesj.park@samsung.com>  Wed, 10 Oct 2012 14:18:32 +0900
+
 livebox-viewer (0.6.5) unstable; urgency=low
 
   * Git: slp/pkgs/l/livebox-viewer
diff --git a/include/io.h b/include/io.h
new file mode 100644 (file)
index 0000000..01eab1a
--- /dev/null
@@ -0,0 +1,8 @@
+extern int io_init(void);
+extern int io_fini(void);
+extern char *io_lb_pkgname(const char *pkgname);
+extern char *io_app_pkgname(const char *lbpkg);
+extern int io_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data);
+extern int io_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data);
+
+/* End of a file */
index b9c384c..b7b9aca 100644 (file)
@@ -546,7 +546,7 @@ extern int livebox_unsubscribe_group(const char *cluster, const char *category);
  * \param[in] cb Callback for getting the name(id) list of the cluster, the callback will be called before return from this function.
  * \return int Number of listed items, or negative value(errno) for error
  */
-extern int livebox_enumerate_cluster_list(void (*cb)(const char *cluster));
+extern int livebox_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data);
 
 /*!
  * \brief Get the list of sub-cluster of the "cluster" (SYNC Callback)
@@ -554,7 +554,7 @@ extern int livebox_enumerate_cluster_list(void (*cb)(const char *cluster));
  * \param[in] cb Callback for getting the name(id) list of the category of the "cluster", the callback will be called before return from this function
  * \return int Number of listed items, or negative value(errno) for error
  */
-extern int livebox_enumerate_category_list(const char *cluster, void (*cb)(const char *category));
+extern int livebox_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data);
 
 /*!
  * \brief Refresh the group(cluster/sub-cluser(aka. category))
@@ -637,6 +637,19 @@ extern int livebox_set_visibility(struct livebox *handler, enum livebox_visible_
  */
 extern enum livebox_visible_state livebox_visibility(struct livebox *handler);
 
+/*!
+ * \brief Get the package name of a livebox.
+ * \param[in] pkgname Application package name or the livebox package name
+ * \return pkgname livebox package name or NULL
+ */
+extern char *livebox_lb_pkgname(const char *pkgname);
+
+/*!
+ * \brief Get the application package name of given package name
+ * \param[in] pkgname Livebox package name
+ * \return pkgname Application package name which including the given livebox package.
+ */
+extern char *livebox_app_pkgname(const char *pkgname);
 #ifdef __cplusplus
 }
 #endif
index e2efe80..be72f99 100644 (file)
@@ -1,6 +1,6 @@
 Name: liblivebox-viewer
 Summary: Library for the development of a livebox viewer
-Version: 0.6.5
+Version: 0.6.6
 Release: 1
 Group: main/app
 License: Samsung Proprietary License
@@ -13,6 +13,8 @@ BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(com-core)
 BuildRequires: pkgconfig(x11)
 BuildRequires: pkgconfig(xext)
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(db-util)
 
 %description
 Livebox viewer development library
diff --git a/src/io.c b/src/io.c
new file mode 100644 (file)
index 0000000..775cab3
--- /dev/null
+++ b/src/io.c
@@ -0,0 +1,217 @@
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sqlite3.h>
+
+#include <dlog.h>
+#include <db-util.h>
+
+#include "dlist.h"
+#include "util.h"
+#include "debug.h"
+#include "io.h"
+
+static struct {
+       sqlite3 *handle;
+       const char *dbfile;
+} s_info = {
+       .handle = NULL,
+       .dbfile = "/opt/dbspace/.livebox.db",
+};
+
+int io_init(void)
+{
+       int ret;
+
+       if (s_info.handle)
+               return -EALREADY;
+
+       ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Failed to open a DB\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int io_fini(void)
+{
+       if (!s_info.handle)
+               return -EINVAL;
+
+       db_util_close(s_info.handle);
+       s_info.handle = NULL;
+       return 0;
+}
+
+char *io_lb_pkgname(const char *appid)
+{
+       sqlite3_stmt *stmt;
+       char *tmp;
+       int ret;
+       char *pkgname;
+
+       if (!s_info.handle) {
+               ErrPrint("IO is not initialized\n");
+               return NULL;
+       }
+
+       pkgname = NULL;
+       ret = sqlite3_prepare_v2(s_info.handle, "SELECT pkgid FROM pkgmap WHERE (appid = ? AND prime = 1) OR pkgid = ?", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               return NULL;
+       }
+
+       ret = sqlite3_bind_text(stmt, 1, appid, -1, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = sqlite3_bind_text(stmt, 2, appid, -1, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_ROW) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       tmp = (char *)sqlite3_column_text(stmt, 0);
+       if (tmp && strlen(tmp)) {
+               pkgname = strdup(tmp);
+               if (!pkgname)
+                       ErrPrint("Heap: %s\n", strerror(errno));
+       }
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_finalize(stmt);
+       return pkgname;
+}
+
+char *io_app_pkgname(const char *lbpkg)
+{
+       sqlite3_stmt *stmt;
+       char *tmp;
+       int ret;
+       char *pkgname;
+
+       if (!s_info.handle) {
+               ErrPrint("IO is not initialized\n");
+               return NULL;
+       }
+
+       pkgname = NULL;
+       ret = sqlite3_prepare_v2(s_info.handle, "SELECT appid FROM pkgmap WHERE appid = ? OR (pkgid = ? AND prime = 1)", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               return NULL;
+       }
+
+       ret = sqlite3_bind_text(stmt, 1, lbpkg, -1, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = sqlite3_bind_text(stmt, 2, lbpkg, -1, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_ROW) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       tmp = (char *)sqlite3_column_text(stmt, 0);
+       if (tmp && strlen(tmp)) {
+               pkgname = strdup(tmp);
+               if (!pkgname)
+                       ErrPrint("Heap: %s\n", strerror(errno));
+       }
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_finalize(stmt);
+       return pkgname;
+}
+
+int io_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data)
+{
+       sqlite3_stmt *stmt;
+       const char *cluster;
+       int cnt;
+       int ret;
+
+       if (!s_info.handle)
+               return -EIO;
+
+       cnt = 0;
+       ret = sqlite3_prepare_v2(s_info.handle, "SELECT DISTINCT cluster FROM groupinfo", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle)); 
+               return -EIO;
+       }
+
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               cluster = (const char *)sqlite3_column_text(stmt, 0);
+               if (!cluster || !strlen(cluster))
+                       continue;
+
+               if (cb(cluster, data) < 0)
+                       break;
+
+               cnt++;
+       }
+
+       sqlite3_reset(stmt);
+       sqlite3_finalize(stmt);
+       return cnt;
+}
+
+int io_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data)
+{
+       sqlite3_stmt *stmt;
+       const char *category;
+       int cnt;
+       int ret;
+
+       if (!s_info.handle)
+               return -EIO;
+
+       cnt = 0;
+       ret = sqlite3_prepare_v2(s_info.handle, "SELECT DISTINCT category FROM groupinfo WHERE cluster = ?", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               return -EIO;
+       }
+
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               category = (const char *)sqlite3_column_text(stmt, 0);
+               if (!category || !strlen(category))
+                       continue;
+
+               if (cb(cluster, category, data) < 0)
+                       break;
+
+               cnt++;
+       }
+
+       sqlite3_reset(stmt);
+       sqlite3_finalize(stmt);
+       return cnt;
+}
+
+/* End of a file */
index 327d80a..46f3005 100644 (file)
@@ -18,6 +18,7 @@
 #include "master_rpc.h"
 #include "client.h"
 #include "critical_log.h"
+#include "io.h"
 
 #define EAPI __attribute__((visibility("default")))
 
@@ -504,6 +505,7 @@ static int send_mouse_event(struct livebox *handler, const char *event, double x
 EAPI int livebox_init(void *disp)
 {
        const char *env;
+
        env = getenv("LIVE_EVENT_INTERVAL");
        if (env && sscanf(env, "%lf", &s_info.event_interval) == 1)
                ErrPrint("Allowed event interval is updated to %lf\n", s_info.event_interval);
@@ -515,8 +517,9 @@ EAPI int livebox_init(void *disp)
        if (!__file_log_fp)
                __file_log_fp = fdopen(1, "w+t");
 #endif
-       fb_init(disp);
        critical_log_init();
+       io_init();
+       fb_init(disp);
 
        client_init();
        return 0;
@@ -526,9 +529,37 @@ EAPI int livebox_fini(void)
 {
        client_fini();
        fb_fini();
+       io_fini();
+       critical_log_fini();
        return 0;
 }
 
+static inline char *lb_pkgname(const char *pkgname)
+{
+       char *lb;
+
+       lb = io_lb_pkgname(pkgname);
+       if (!lb) {
+               if (util_validate_livebox_package(pkgname) == 0)
+                       return strdup(pkgname);
+       }
+
+       return lb;
+}
+
+static inline char *app_pkgname(const char *pkgname)
+{
+       char *app;
+
+       app = io_app_pkgname(pkgname);
+       if (!app) {
+               if (util_validate_livebox_package(pkgname) == 0)
+                       return strdup(app);
+       }
+
+       return app;
+}
+
 EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, ret_cb_t cb, void *data)
 {
        struct livebox *handler;
@@ -547,7 +578,7 @@ EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const
                return NULL;
        }
 
-       handler->pkgname = strdup(pkgname);
+       handler->pkgname = lb_pkgname(pkgname);
        if (!handler->pkgname) {
                ErrPrint("Error: %s\n", strerror(errno));
                free(handler);
@@ -1808,7 +1839,30 @@ EAPI void *livebox_get_data(struct livebox *handler)
 
 EAPI int livebox_is_exists(const char *pkgname)
 {
-       return util_validate_livebox_package(pkgname) == 0;
+       char *lb;
+
+       lb = io_lb_pkgname(pkgname);
+       if (!lb)
+               return util_validate_livebox_package(pkgname) == 0;
+
+       free(lb);
+       return 1;
+}
+
+EAPI char *livebox_lb_pkgname(const char *pkgname)
+{
+       if (!pkgname)
+               return NULL;
+
+       return lb_pkgname(pkgname);
+}
+
+EAPI char *livebox_app_pkgname(const char *pkgname)
+{
+       if (!pkgname)
+               return NULL;
+
+       return app_pkgname(pkgname);
 }
 
 EAPI const char *livebox_content(struct livebox *handler)
@@ -1871,6 +1925,12 @@ EAPI int livebox_subscribe_group(const char *cluster, const char *category)
 {
        struct packet *packet;
 
+       /*!
+        * \TODO
+        * Validate the group info using DB
+        * If the group info is not valid, do not send this request
+        */
+
        packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
        if (!packet) {
                ErrPrint("Failed to create a packet\n");
@@ -1884,6 +1944,13 @@ EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
 {
        struct packet *packet;
 
+       /*!
+        * \TODO
+        * Validate the group info using DB
+        * If the group info is not valid, do not send this request
+        * AND Check the subscribed or not too
+        */
+
        packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
        if (!packet) {
                ErrPrint("Failed to create a packet\n");
@@ -1893,18 +1960,20 @@ EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
        return master_rpc_request_only(NULL, packet);
 }
 
-EAPI int livebox_enumerate_cluster_list(void (*cb)(const char *cluster))
+EAPI int livebox_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data)
 {
-       DbgPrint("Not implemented\n");
-       /* Use the DB for this */
-       return -ENOSYS;
+       if (!cb)
+               return -EINVAL;
+
+       return io_enumerate_cluster_list(cb, data);
 }
 
-EAPI int livebox_enumerate_category_list(const char *cluster, void (*cb)(const char *category))
+EAPI int livebox_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data)
 {
-       DbgPrint("Not implemented\n");
-       /* Use the DB for this */
-       return -ENOSYS;
+       if (!cluster || !cb)
+               return -EINVAL;
+
+       return io_enumerate_category_list(cluster, cb, data);
 }
 
 EAPI int livebox_refresh_group(const char *cluster, const char *category)