Fix app meatadata filter foreach 57/117857/6
authorSangyoon Jang <s89.jang@samsung.com>
Wed, 8 Mar 2017 00:37:27 +0000 (09:37 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Wed, 8 Mar 2017 02:01:04 +0000 (11:01 +0900)
Get app list filtered by OR-ed metadata key-value set.

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

index b8b6c85..4f2171c 100644 (file)
@@ -141,10 +141,6 @@ extern "C" {
 #define        PMINFO_APPINFO_PROP_APP_PACKAGE         "PMINFO_APPINFO_PROP_APP_PACKAGE"
  /** String property for filtering based on app info*/
 #define        PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE               "PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE"
- /** 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"
 
 /** Integer property for filtering app support mode */
 #define        PMINFO_APPINFO_PROP_APP_SUPPORT_MODE            "PMINFO_APPINFO_PROP_APP_SUPPORT_MODE"
index d4c18ba..a25f671 100644 (file)
@@ -91,6 +91,28 @@ static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
                condition = NULL;
        }
 
+       if (filter->list_metadata) {
+               len += strlen(" AND (");
+               strncat(buf, " AND (", MAX_QUERY_LEN - len - 1);
+       }
+       for (list = filter->list_metadata; list; list = list->next) {
+               joined |= __get_metadata_filter_condition(list->data,
+                               &condition, bind_params);
+               if (condition == NULL)
+                       continue;
+               len += strlen(condition);
+               strncat(buf, condition, sizeof(buf) - len - 1);
+               free(condition);
+               condition = NULL;
+
+               len += strlen(" OR ");
+               strncat(buf, " OR ", MAX_QUERY_LEN - len - 1);
+       }
+       if (filter->list_metadata) {
+               len += strlen("1=0)");
+               strncat(buf, "1=0)", MAX_QUERY_LEN - len - 1);
+       }
+
        if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) {
                strncat(tmp_query, join_localized_info, MAX_QUERY_LEN - len - 1);
                len += strlen(join_localized_info);
@@ -3059,23 +3081,30 @@ API int pkgmgrinfo_appinfo_metadata_filter_add(
                pkgmgrinfo_appinfo_metadata_filter_h handle,
                const char *key, const char *value)
 {
-       int ret;
-
-       ret = pkgmgrinfo_appinfo_filter_add_string(handle,
-                       PMINFO_APPINFO_PROP_APP_METADATA_KEY, key);
-       if (ret != PMINFO_R_OK)
-               return ret;
+       pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
+       pkgmgrinfo_metadata_node_x *node;
 
        /* value can be NULL.
         * In that case all apps with specified key should be displayed
         */
-       if (value && strlen(value)) {
-               ret = pkgmgrinfo_appinfo_filter_add_string(handle,
-                               PMINFO_APPINFO_PROP_APP_METADATA_VALUE, value);
-               if (ret != PMINFO_R_OK)
-                       return ret;
+       if (key == NULL) {
+               LOGE("invalid parameter");
+               return PMINFO_R_EINVAL;
        }
 
+       node = calloc(1, sizeof(pkgmgrinfo_metadata_node_x));
+       if (node == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+
+       node->key = strdup(key);
+       if (value && strlen(value))
+               node->value = strdup(value);
+
+       filter->list_metadata = g_slist_append(filter->list_metadata,
+                       (gpointer)node);
+
        return PMINFO_R_OK;
 }
 
index ea64f4b..fe4b52a 100644 (file)
@@ -86,6 +86,16 @@ static void __destroy_each_node(gpointer data, gpointer user_data)
        node = NULL;
 }
 
+static void __destroy_metadata_node(gpointer data)
+{
+       pkgmgrinfo_metadata_node_x *node = (pkgmgrinfo_metadata_node_x *)data;
+       if (node->key)
+               free(node->key);
+       if (node->value)
+               free(node->value);
+       free(node);
+}
+
 static void __cleanup_pkginfo(pkgmgr_pkginfo_x *data)
 {
        ret_if(data == NULL);
@@ -1641,6 +1651,8 @@ API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
                g_slist_free(filter->list);
        }
 
+       g_slist_free_full(filter->list_metadata, __destroy_metadata_node);
+
        free(filter);
 
        return PMINFO_R_OK;
index d2584a1..5f99d1a 100644 (file)
@@ -94,8 +94,6 @@ 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},
        {E_PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE,   PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE}
 };
@@ -377,14 +375,6 @@ int __get_filter_condition(gpointer data, uid_t uid, char **condition, GList **p
        case E_PMINFO_APPINFO_PROP_APP_UI_GADGET:
                snprintf(buf, sizeof(buf), "ai.app_ui_gadget=? COLLATE NOCASE");
                break;
-       case E_PMINFO_APPINFO_PROP_APP_METADATA_KEY:
-               snprintf(buf, sizeof(buf), "package_app_app_metadata.md_key=?");
-               flag = E_PMINFO_APPINFO_JOIN_METADATA;
-               break;
-       case E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE:
-               snprintf(buf, sizeof(buf), "package_app_app_metadata.md_value=?");
-               flag = E_PMINFO_APPINFO_JOIN_METADATA;
-               break;
        case E_PMINFO_APPINFO_PROP_APP_DISABLE:
                if (strcasecmp(node->value, "true") == 0)
                        snprintf(buf, MAX_QUERY_LEN, "(ai.app_disable=? COLLATE NOCASE OR "
@@ -416,6 +406,31 @@ int __get_filter_condition(gpointer data, uid_t uid, char **condition, GList **p
        return flag;
 }
 
+int __get_metadata_filter_condition(gpointer data, char **condition,
+               GList **params)
+{
+       pkgmgrinfo_metadata_node_x *node = (pkgmgrinfo_metadata_node_x *)data;
+       char buf[MAX_QUERY_LEN];
+       size_t len = 0;
+
+       len += strlen("(package_app_app_metadata.md_key=?");
+       snprintf(buf, sizeof(buf), "(package_app_app_metadata.md_key=?");
+       if (node->value) {
+               len += strlen(" AND package_app_app_metadata.md_value=?");
+               strncat(buf, " AND package_app_app_metadata.md_value=?",
+                               sizeof(buf) - len - 1);
+       }
+       len += strlen(")");
+       strncat(buf, ")", sizeof(buf) - len - 1);
+
+       *condition = strdup(buf);
+       *params = g_list_append(*params, strdup(node->key));
+       if (node->value)
+               *params = g_list_append(*params, strdup(node->value));
+
+       return E_PMINFO_APPINFO_JOIN_METADATA;
+}
+
 int _add_icon_info_into_list(const char *locale, char *value, GList **icon)
 {
        icon_x *info;
index c0822be..5229f32 100644 (file)
@@ -196,6 +196,7 @@ typedef struct _pkgmgr_appinfo_x {
 typedef struct _pkgmgrinfo_filter_x {
        uid_t uid;
        GSList *list;
+       GSList *list_metadata;
 } pkgmgrinfo_filter_x;
 
 typedef struct _pkgmgrinfo_node_x {
@@ -204,6 +205,11 @@ typedef struct _pkgmgrinfo_node_x {
        char *value;
 } pkgmgrinfo_node_x;
 
+typedef struct _pkgmgrinfo_metadata_node_x {
+       char *key;
+       char *value;
+} pkgmgrinfo_metadata_node_x;
+
 typedef struct _pkgmgrinfo_appcontrol_x {
        int operation_count;
        int uri_count;
@@ -242,6 +248,7 @@ void _save_column_int(sqlite3_stmt *stmt, int idx, int *i);
 void _save_column_str(sqlite3_stmt *stmt, int idx, char **str);
 char *_get_system_locale(void);
 int __get_filter_condition(gpointer data, uid_t uid, char **condition, GList **param);
+int __get_metadata_filter_condition(gpointer data, char **condition, GList **param);
 int _add_icon_info_into_list(const char *locale, char *value, GList **icon);
 int _add_label_info_into_list(const char *locale, char *value, GList **label);
 int __pkginfo_check_installed_storage(package_x *pkginfo);