Fix pkgmgrinfo_appinfo_metadata_filter_foreach 17/46417/1
authorSangyoon Jang <s89.jang@samsung.com>
Thu, 20 Aug 2015 06:05:28 +0000 (15:05 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Thu, 20 Aug 2015 06:05:28 +0000 (15:05 +0900)
add filter prop for metadata key, value

Change-Id: Ib94612054f5a46c3e362174300e4e09b58a0fca8
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
include/pkgmgr-info.h
include/pkgmgrinfo_private.h
src/pkgmgrinfo_appinfo.c
src/pkgmgrinfo_private.c

index 42f5909..c500956 100644 (file)
@@ -133,6 +133,10 @@ extern "C" {
 #define        PMINFO_APPINFO_PROP_APP_SCREENREADER    "PMINFO_APPINFO_PROP_APP_SCREENREADER"
  /** String property for filtering based on app info*/
 #define        PMINFO_APPINFO_PROP_APP_PACKAGE         "PMINFO_APPINFO_PROP_APP_PACKAGE"
+ /** String property for filtering based on app info*/
+#define        PMINFO_APPINFO_PROP_APP_METADATA_KEY    "PMINFO_APPINFO_PROP_APP_METADATA_KEY"
+ /** String property for filtering based on app info*/
+#define        PMINFO_APPINFO_PROP_APP_METADATA_VALUE  "PMINFO_APPINFO_PROP_APP_METADATA_VALUE"
 
  /** Boolean property for filtering based on app info*/
 #define        PMINFO_APPINFO_PROP_APP_NODISPLAY               "PMINFO_APPINFO_PROP_APP_NODISPLAY"
index a7f8cf9..e661e42 100644 (file)
@@ -123,7 +123,9 @@ typedef enum _pkgmgrinfo_appinfo_filter_prop_str {
        E_PMINFO_APPINFO_PROP_APP_CATEGORY,
        E_PMINFO_APPINFO_PROP_APP_SCREENREADER,
        E_PMINFO_APPINFO_PROP_APP_PACKAGE,
-       E_PMINFO_APPINFO_PROP_APP_MAX_STR = E_PMINFO_APPINFO_PROP_APP_PACKAGE
+       E_PMINFO_APPINFO_PROP_APP_METADATA_KEY,
+       E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE,
+       E_PMINFO_APPINFO_PROP_APP_MAX_STR = E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE
 } pkgmgrinfo_appinfo_filter_prop_str;
 
 /*Boolean properties for filtering based on app info*/
index 678c3b0..148f84d 100644 (file)
@@ -99,7 +99,9 @@ static GSList *_appinfo_get_filtered_list(const char *locale,
                " LEFT OUTER JOIN package_app_app_category"
                "  ON package_app_info.app_id=package_app_app_category.app_id"
                " LEFT OUTER JOIN package_app_app_svc"
-               "  ON package_app_info.app_id=package_app_app_svc.app_id ";
+               "  ON package_app_info.app_id=package_app_app_svc.app_id "
+               " LEFT OUTER JOIN package_app_app_metadata"
+               "  ON package_app_info.app_id=package_app_app_metadata.app_id ";
        int ret;
        char *query;
        char *query_localized;
@@ -1946,183 +1948,49 @@ API int pkgmgrinfo_appinfo_metadata_filter_destroy(pkgmgrinfo_appinfo_metadata_f
        return (pkgmgrinfo_pkginfo_filter_destroy(handle));
 }
 
-API int pkgmgrinfo_appinfo_metadata_filter_add(pkgmgrinfo_appinfo_metadata_filter_h handle,
+API int pkgmgrinfo_appinfo_metadata_filter_add(
+               pkgmgrinfo_appinfo_metadata_filter_h handle,
                const char *key, const char *value)
 {
-       retvm_if(handle == NULL, PMINFO_R_EINVAL, "filter handle is NULL\n");
-       retvm_if(key == NULL, PMINFO_R_EINVAL, "metadata key supplied is NULL\n");
-       /*value can be NULL. In that case all apps with specified key should be displayed*/
-       int ret = 0;
-       char *k = NULL;
-       char *v = NULL;
-       pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x*)handle;
-       pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)calloc(1, sizeof(pkgmgrinfo_node_x));
-       retvm_if(node == NULL, PMINFO_R_ERROR, "Out of Memory!!!\n");
-       k = strdup(key);
-       tryvm_if(k == NULL, ret = PMINFO_R_ERROR, "Out of Memory!!!\n");
-       node->key = k;
-       if (value) {
-               v = strdup(value);
-               tryvm_if(v == NULL, ret = PMINFO_R_ERROR, "Out of Memory!!!\n");
-       }
-       node->value = v;
-       /*If API is called multiple times, we should OR all conditions.*/
-       filter->list = g_slist_append(filter->list, (gpointer)node);
-       /*All memory will be freed in destroy API*/
-       return PMINFO_R_OK;
-catch:
-       if (node) {
-               if (node->key) {
-                       free(node->key);
-                       node->key = NULL;
-               }
-               if (node->value) {
-                       free(node->value);
-                       node->value = NULL;
-               }
-               free(node);
-               node = NULL;
-       }
-       return ret;
-}
-
-static void __get_metadata_filter_condition(gpointer data, char **condition)
-{
-       pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)data;
-       char key[MAX_QUERY_LEN] = {'\0'};
-       char value[MAX_QUERY_LEN] = {'\0'};
-       if (node->key) {
-               snprintf(key, MAX_QUERY_LEN, "(package_app_app_metadata.md_key='%s'", node->key);
-       }
-       if (node->value) {
-               snprintf(value, MAX_QUERY_LEN, " AND package_app_app_metadata.md_value='%s')", node->value);
-               strcat(key, value);
-       } else {
-               strcat(key, ")");
-       }
-       *condition = strdup(key);
-       return;
-}
-
-static char *_get_metadata_filtered_query(const char *query_raw,
-               pkgmgrinfo_filter_x *filter)
-{
-       char buf[MAX_QUERY_LEN] = { 0, };
-       char *condition;
-       size_t len;
-       GSList *list;
-       GSList *head = NULL;
-
-       if (filter)
-               head = filter->list;
-
-       strncat(buf, query_raw, MAX_QUERY_LEN - 1);
-       len = strlen(buf);
-       for (list = head; list; list = list->next) {
-               /* TODO: revise condition getter function */
-               __get_metadata_filter_condition(list->data, &condition);
-               if (condition == NULL)
-                       continue;
-               if (buf[strlen(query_raw)] == '\0') {
-                       len += strlen(" WHERE ");
-                       strncat(buf, " WHERE ", MAX_QUERY_LEN - len - 1);
-               } else {
-                       len += strlen(" AND ");
-                       strncat(buf, " AND ", MAX_QUERY_LEN -len - 1);
-               }
-               len += strlen(condition);
-               strncat(buf, condition, sizeof(buf) - len - 1);
-               free(condition);
-               condition = NULL;
-       }
-
-       return strdup(buf);
-}
-
-static GSList *_appinfo_get_metadata_filtered_list(pkgmgrinfo_filter_x *filter)
-{
-       static const char query_raw[] =
-               "SELECT app_id FROM package_app_app_metadata";
        int ret;
-       char *query;
-       sqlite3_stmt *stmt;
-       GSList *list = NULL;
-       char *appid;
 
-       query = _get_metadata_filtered_query(query_raw, filter);
-       if (query == NULL) {
-               LOGE("out of memory");
-               return NULL;
-       }
+       ret = pkgmgrinfo_appinfo_filter_add_string(handle,
+                       PMINFO_APPINFO_PROP_APP_METADATA_KEY, key);
+       if (ret != PMINFO_R_OK)
+               return ret;
 
-       ret = sqlite3_prepare_v2(GET_DB(manifest_db), query, strlen(query),
-                       &stmt, NULL);
-       free(query);
-       if (ret != SQLITE_OK) {
-               LOGE("prepare failed: %s", sqlite3_errmsg(GET_DB(manifest_db)));
-               return NULL;
-       }
-
-       while (sqlite3_step(stmt) == SQLITE_ROW) {
-               _save_column_str(stmt, 0, (const char **)&appid);
-               list = g_slist_append(list, appid);
+       /* value can be NULL.
+        * In that case all apps with specified key should be displayed
+        */
+       if (value) {
+               ret = pkgmgrinfo_appinfo_filter_add_string(handle,
+                               PMINFO_APPINFO_PROP_APP_METADATA_VALUE, value);
+               if (ret != PMINFO_R_OK)
+                       return ret;
        }
 
-       sqlite3_finalize(stmt);
-
-       return list;
+       return PMINFO_R_OK;
 }
 
 API int pkgmgrinfo_appinfo_usr_metadata_filter_foreach(
                pkgmgrinfo_appinfo_metadata_filter_h handle,
                pkgmgrinfo_app_list_cb app_cb, void *user_data, uid_t uid)
 {
-       GSList *list;
-       GSList *tmp;
-       char *appid;
-       pkgmgrinfo_appinfo_h info;
-       int stop = 0;
-
        if (handle == NULL || app_cb == NULL) {
                LOGE("invalid parameter");
                return PMINFO_R_EINVAL;
        }
 
-       if (__open_manifest_db(uid, true) < 0)
-               return PMINFO_R_ERROR;
-
-       list = _appinfo_get_metadata_filtered_list(handle);
-       if (list == NULL) {
-               LOGE("no result");
-               __close_manifest_db();
-               return PMINFO_R_OK;
-       }
-
-       for (tmp = list; tmp; tmp = tmp->next) {
-               appid = (char *)tmp->data;
-               if (stop == 0) {
-                       if (pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid,
-                                               &info)) {
-                               free(appid);
-                               continue;
-                       }
-                       if (app_cb(info, user_data) < 0)
-                               stop = 1;
-                       pkgmgrinfo_appinfo_destroy_appinfo(info);
-               }
-               free(appid);
-       }
-
-       g_slist_free(list);
-       __close_manifest_db();
-
-       return PMINFO_R_OK;
+       return _appinfo_get_filtered_foreach_appinfo(uid, handle, app_cb,
+                       user_data);
 }
 
-API int pkgmgrinfo_appinfo_metadata_filter_foreach(pkgmgrinfo_appinfo_metadata_filter_h handle,
+API int pkgmgrinfo_appinfo_metadata_filter_foreach(
+               pkgmgrinfo_appinfo_metadata_filter_h handle,
                pkgmgrinfo_app_list_cb app_cb, void *user_data)
 {
-       return pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle, app_cb, user_data, GLOBAL_USER);
+       return pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle, app_cb,
+                       user_data, GLOBAL_USER);
 }
 
 API int pkgmgrinfo_appinfo_is_guestmode_visibility(pkgmgrinfo_appinfo_h handle, bool *status)
index 9c1cd11..5f70ed7 100644 (file)
@@ -91,6 +91,8 @@ static struct _appinfo_str_map_t appinfo_str_prop_map[] = {
        {E_PMINFO_APPINFO_PROP_APP_CATEGORY,    PMINFO_APPINFO_PROP_APP_CATEGORY},
        {E_PMINFO_APPINFO_PROP_APP_HWACCELERATION,      PMINFO_APPINFO_PROP_APP_HWACCELERATION},
        {E_PMINFO_APPINFO_PROP_APP_SCREENREADER,        PMINFO_APPINFO_PROP_APP_SCREENREADER},
+       {E_PMINFO_APPINFO_PROP_APP_METADATA_KEY,        PMINFO_APPINFO_PROP_APP_METADATA_KEY},
+       {E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE,      PMINFO_APPINFO_PROP_APP_METADATA_VALUE},
        {E_PMINFO_APPINFO_PROP_APP_PACKAGE,     PMINFO_APPINFO_PROP_APP_PACKAGE}
 };
 
@@ -229,118 +231,124 @@ inline pkgmgrinfo_appinfo_filter_prop_bool _pminfo_appinfo_convert_to_prop_bool(
 void __get_filter_condition(gpointer data, char **condition)
 {
        pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)data;
-       char buf[MAX_QUERY_LEN + 1] = {'\0'};
+       char buf[MAX_QUERY_LEN] = {'\0'};
        char temp[PKG_STRING_LEN_MAX] = {'\0'};
        switch (node->prop) {
        case E_PMINFO_PKGINFO_PROP_PACKAGE_ID:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_TYPE:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_type='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_type='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_VERSION:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_version='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_version='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_INSTALL_LOCATION:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.install_location='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.install_location='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_INSTALLED_STORAGE:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.installed_storage='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.installed_storage='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_NAME:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.author_name='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.author_name='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_HREF:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.author_href='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.author_href='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_EMAIL:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.author_email='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.author_email='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE:
-               snprintf(buf, MAX_QUERY_LEN, "package_privilege_info.privilege='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_privilege_info.privilege='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_SIZE:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_size='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_size='%s'", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_REMOVABLE:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_removable IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_removable IN %s", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_PRELOAD:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_preload IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_preload IN %s", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_READONLY:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_readonly IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_readonly IN %s", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_UPDATE:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_update IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_update IN %s", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_APPSETTING:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_appsetting IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_appsetting IN %s", node->value);
                break;
        case E_PMINFO_PKGINFO_PROP_PACKAGE_NODISPLAY_SETTING:
-               snprintf(buf, MAX_QUERY_LEN, "package_info.package_nodisplay IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_info.package_nodisplay IN %s", node->value);
                break;
 
        case E_PMINFO_APPINFO_PROP_APP_ID:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_id='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_id='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_COMPONENT:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_component='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_component='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_EXEC:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_exec='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_exec='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_ICON:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_localized_info.app_icon='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_localized_info.app_icon='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_TYPE:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_type='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_type='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_OPERATION:
-               snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value);
-               snprintf(buf, MAX_QUERY_LEN, "package_app_app_svc.operation IN %s", temp);
+               snprintf(temp, sizeof(temp), "(%s)", node->value);
+               snprintf(buf, sizeof(buf), "package_app_app_svc.operation IN %s", temp);
                break;
        case E_PMINFO_APPINFO_PROP_APP_URI:
-               snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value);
-               snprintf(buf, MAX_QUERY_LEN, "package_app_app_svc.uri_scheme IN %s", temp);
+               snprintf(temp, sizeof(temp), "(%s)", node->value);
+               snprintf(buf, sizeof(buf), "package_app_app_svc.uri_scheme IN %s", temp);
                break;
        case E_PMINFO_APPINFO_PROP_APP_MIME:
-               snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value);
-               snprintf(buf, MAX_QUERY_LEN, "package_app_app_svc.mime_type IN %s", temp);
+               snprintf(temp, sizeof(temp), "(%s)", node->value);
+               snprintf(buf, sizeof(buf), "package_app_app_svc.mime_type IN %s", temp);
                break;
        case E_PMINFO_APPINFO_PROP_APP_CATEGORY:
-               snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value);
-               snprintf(buf, MAX_QUERY_LEN, "package_app_app_category.category IN %s", temp);
+               snprintf(temp, sizeof(temp), "(%s)", node->value);
+               snprintf(buf, sizeof(buf), "package_app_app_category.category IN %s", temp);
                break;
        case E_PMINFO_APPINFO_PROP_APP_NODISPLAY:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_nodisplay IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_nodisplay IN %s", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_MULTIPLE:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_multiple IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_multiple IN %s", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_ONBOOT:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_onboot IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_onboot IN %s", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_AUTORESTART:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_autorestart IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_autorestart IN %s", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_TASKMANAGE:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_taskmanage IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_taskmanage IN %s", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_HWACCELERATION:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_hwacceleration='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_hwacceleration='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_SCREENREADER:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_screenreader='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_screenreader='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_LAUNCHCONDITION:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_launchcondition IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_launchcondition IN %s", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_PACKAGE:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.package='%s'", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.package='%s'", node->value);
                break;
        case E_PMINFO_APPINFO_PROP_APP_UI_GADGET:
-               snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_ui_gadget IN %s", node->value);
+               snprintf(buf, sizeof(buf), "package_app_info.app_ui_gadget IN %s", node->value);
+               break;
+       case E_PMINFO_APPINFO_PROP_APP_METADATA_KEY:
+               snprintf(buf, sizeof(buf), "package_app_app_metadata.md_key='%s'", node->value);
+               break;
+       case E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE:
+               snprintf(buf, sizeof(buf), "package_app_app_metadata.md_value='%s'", node->value);
                break;
        default:
                _LOGE("Invalid Property Type\n");