Add aggregation suggestion 71/56371/26
authorJongkyu Koo <jk.koo@samsung.com>
Thu, 7 Jan 2016 06:05:56 +0000 (15:05 +0900)
committerJongkyu Koo <jk.koo@samsung.com>
Fri, 12 Feb 2016 06:55:49 +0000 (15:55 +0900)
Change-Id: I14d6d557bfcd80ba1e94d6bb766fa38b19eaf39c
Signed-off-by: Jongkyu Koo <jk.koo@samsung.com>
16 files changed:
client/ctsvc_client_activity_helper.c
client/ctsvc_client_db_helper.c
client/ctsvc_client_group_helper.c
client/ctsvc_client_person.c
client/ctsvc_client_person_helper.c
client/ctsvc_client_person_helper.h
client/ctsvc_client_phonelog_helper.c
client/ctsvc_client_setting.c
common/ipc/ctsvc_ipc_define.h
common/ipc/ctsvc_ipc_marshal.c
include/contacts_person.h
server/ctsvc_ipc_server2.c
server/ctsvc_ipc_server2.h
server/ctsvc_server.c
server/ctsvc_server_person.c
server/ctsvc_server_person.h

index 28e5643..13b0f53 100644 (file)
@@ -45,8 +45,7 @@ int ctsvc_client_activity_delete_by_contact_id(contacts_h contact, int contact_i
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -111,8 +110,7 @@ int ctsvc_client_activity_delete_by_account_id(contacts_h contact, int account_i
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
index 239ced8..1b188ae 100644 (file)
@@ -51,9 +51,9 @@ int ctsvc_client_db_insert_record(contacts_h contact, contacts_record_h record,
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
        if (ret != CONTACTS_ERROR_NONE) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
@@ -123,8 +123,7 @@ int ctsvc_client_db_get_record(contacts_h contact, const char *view_uri, int id,
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -187,8 +186,7 @@ int ctsvc_client_db_update_record(contacts_h contact, contacts_record_h record)
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -248,8 +246,7 @@ int ctsvc_client_db_delete_record(contacts_h contact, const char *view_uri, int
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -316,8 +313,7 @@ int ctsvc_client_db_replace_record(contacts_h contact, contacts_record_h record,
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -386,8 +382,7 @@ int ctsvc_client_db_get_all_records(contacts_h contact, const char *view_uri, in
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -459,8 +454,7 @@ int ctsvc_client_db_get_records_with_query(contacts_h contact, contacts_query_h
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -535,8 +529,7 @@ int ctsvc_client_db_get_count(contacts_h contact, const char *view_uri, int *out
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -598,9 +591,9 @@ int ctsvc_client_db_get_count_with_query(contacts_h contact, contacts_query_h qu
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
        if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
@@ -661,9 +654,9 @@ int ctsvc_client_db_insert_records(contacts_h contact, contacts_list_h list, int
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
        if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
@@ -750,8 +743,7 @@ int ctsvc_client_db_update_records(contacts_h contact, contacts_list_h list)
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -813,8 +805,7 @@ int ctsvc_client_db_delete_records(contacts_h contact, const char *view_uri, int
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -895,8 +886,7 @@ int ctsvc_client_db_replace_records(contacts_h contact, contacts_list_h list, in
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -976,8 +966,7 @@ int ctsvc_client_db_get_changes_by_version(contacts_h contact, const char *view_
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -1055,8 +1044,7 @@ int ctsvc_client_db_get_current_version(contacts_h contact, int *contacts_db_ver
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -1110,9 +1098,9 @@ int ctsvc_client_db_search_records(contacts_h contact, const char *view_uri, con
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
        if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
@@ -1272,9 +1260,9 @@ int ctsvc_client_db_search_records_with_query(contacts_h contact, contacts_query
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
        if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
@@ -1403,8 +1391,7 @@ int ctsvc_client_db_get_status(contacts_h contact, contacts_db_status_e *status)
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
index 5ee2b25..c2101f7 100644 (file)
@@ -44,8 +44,7 @@ int ctsvc_client_group_add_contact(contacts_h contact, int group_id, int contact
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -114,9 +113,9 @@ int ctsvc_client_group_remove_contact(contacts_h contact, int group_id, int cont
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
        if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
@@ -184,9 +183,9 @@ int ctsvc_client_group_set_group_order(contacts_h contact, int group_id, int pre
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
        if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
index 2eedf19..61daeb5 100644 (file)
@@ -106,3 +106,15 @@ API int contacts_person_get_default_property(contacts_person_property_e property
        return ret;
 }
 
+API int contacts_person_get_aggregation_suggestions(int person_id, int limit, contacts_list_h *out_list)
+{
+       int ret;
+       contacts_h contact = NULL;
+
+       ret = ctsvc_client_handle_get_p(&contact);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_client_handle_get_p() Fail(%d)", ret);
+
+       ret = ctsvc_client_person_get_aggregation_suggestions(contact, person_id, limit, out_list);
+
+       return ret;
+}
index 7c0749f..b6c5bf9 100644 (file)
@@ -43,12 +43,12 @@ int ctsvc_client_person_link_person(contacts_h contact, int base_person_id,
 
        /* make indata */
        indata = pims_ipc_data_create(0);
-       if (indata == NULL) {
+       if (NULL == indata) {
                ERR("pims_ipc_data_create() Fail");
                return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
        ret = ctsvc_ipc_marshal_handle(contact, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
@@ -72,12 +72,12 @@ int ctsvc_client_person_link_person(contacts_h contact, int base_person_id,
 
        /*
           ret = ctsvc_ipc_marshal_int(base_person_id, indata);
-          if (ret != CONTACTS_ERROR_NONE) {
+          if (CONTACTS_ERROR_NONE != ret) {
           ERR("marshal fail");
           return ret;
           }
           ret = ctsvc_ipc_marshal_int(person_id, indata);
-          if (ret != CONTACTS_ERROR_NONE) {
+          if (CONTACTS_ERROR_NONE != ret) {
           ERR("marshal fail");
           return ret;
           }
@@ -133,26 +133,26 @@ int ctsvc_client_person_unlink_contact(contacts_h contact, int person_id, int co
 
        /* make indata */
        indata = pims_ipc_data_create(0);
-       if (indata == NULL) {
+       if (NULL == indata) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
 
        ret = ctsvc_ipc_marshal_int(person_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
        ret = ctsvc_ipc_marshal_int(contact_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
@@ -213,13 +213,13 @@ int ctsvc_client_person_reset_usage(contacts_h contact, int person_id,
 
        /* make indata */
        indata = pims_ipc_data_create(0);
-       if (indata == NULL) {
+       if (NULL == indata) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
@@ -227,13 +227,13 @@ int ctsvc_client_person_reset_usage(contacts_h contact, int person_id,
 
 
        ret = ctsvc_ipc_marshal_int(person_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
        ret = ctsvc_ipc_marshal_int((int)type, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
@@ -286,32 +286,32 @@ int ctsvc_client_person_set_favorite_order(contacts_h contact, int person_id,
 
        /* make indata */
        indata = pims_ipc_data_create(0);
-       if (indata == NULL) {
+       if (NULL == indata) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
+
        ret = ctsvc_ipc_marshal_handle(contact, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
 
        ret = ctsvc_ipc_marshal_int(person_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
        ret = ctsvc_ipc_marshal_int(previous_person_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
        ret = ctsvc_ipc_marshal_int(next_person_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
@@ -366,33 +366,32 @@ int ctsvc_client_person_set_default_property(contacts_h contact,
 
        /* make indata */
        indata = pims_ipc_data_create(0);
-       if (indata == NULL) {
+       if (NULL == indata) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
 
        ret = ctsvc_ipc_marshal_int(person_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
        ret = ctsvc_ipc_marshal_unsigned_int(property, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_unsigned_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
        ret = ctsvc_ipc_marshal_int(id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
@@ -444,28 +443,27 @@ int ctsvc_client_person_get_default_property(contacts_h contact,
 
        /* make indata */
        indata = pims_ipc_data_create(0);
-       if (indata == NULL) {
+       if (NULL == indata) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_handle() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
 
        ret = ctsvc_ipc_marshal_int(person_id, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
        }
 
        ret = ctsvc_ipc_marshal_unsigned_int(property, indata);
-       if (ret != CONTACTS_ERROR_NONE) {
+       if (CONTACTS_ERROR_NONE != ret) {
                ERR("ctsvc_ipc_marshal_unsigned_int() Fail(%d)", ret);
                pims_ipc_data_destroy(indata);
                return ret;
@@ -500,3 +498,73 @@ int ctsvc_client_person_get_default_property(contacts_h contact,
        return ret;
 }
 
+int ctsvc_client_person_get_aggregation_suggestions(contacts_h contact,
+               int person_id, int limit, contacts_list_h *out_list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int ret_val = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETV_IF(NULL == contact, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(person_id <= 0 ||NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       /* make indata */
+       indata = pims_ipc_data_create(0);
+       if (NULL == indata) {
+               ERR("pims_ipc_data_create() Fail");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = ctsvc_ipc_marshal_handle(contact, indata);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ERR("ctsvc_ipc_marshal_handle Fail(%d)", ret);
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(person_id, indata);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(limit, indata);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ERR("ctsvc_ipc_marshal_int() Fail(%d)", ret);
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       /* ipc call */
+       ret = ctsvc_ipc_call(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_GET_AGGREGATION_SUGGESTIONS,
+                       indata, &outdata);
+       pims_ipc_data_destroy(indata);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ERR("ctsvc_ipc_call() Fail(%d)", ret);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       if (outdata) {
+               ret = ctsvc_ipc_unmarshal_int(outdata, &ret_val);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       ERR("ctsvc_ipc_unmarshal_int() Fail(%d)", ret);
+                       pims_ipc_data_destroy(outdata);
+                       return CONTACTS_ERROR_IPC;
+               }
+
+               if (CONTACTS_ERROR_NONE == ret_val) {
+                       ret = ctsvc_ipc_unmarshal_list(outdata, out_list);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               ERR("ctsvc_ipc_unmarshal_list() Fail(%d)");
+                               pims_ipc_data_destroy(outdata);
+                               return CONTACTS_ERROR_IPC;
+                       }
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret_val;
+}
index 6cab85b..b25d34e 100644 (file)
@@ -28,5 +28,5 @@ int ctsvc_client_person_reset_usage(contacts_h contact, int person_id, contacts_
 int ctsvc_client_person_set_favorite_order(contacts_h contact, int person_id, int previous_person_id, int next_person_id);
 int ctsvc_client_person_set_default_property(contacts_h contact, contacts_person_property_e property, int person_id, int id);
 int ctsvc_client_person_get_default_property(contacts_h contact, contacts_person_property_e property, int person_id, int *id);
-
+int ctsvc_client_person_get_aggregation_suggestions(contacts_h contact, int person_id, int limit, contacts_list_h *out_list);
 #endif /* __CTSVC_CLIENT_PERSON_HELPER_H__ */
\ No newline at end of file
index 28153c4..8c27a72 100644 (file)
@@ -48,8 +48,7 @@ int ctsvc_client_phone_log_reset_statistics(contacts_h contact)
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
@@ -112,9 +111,7 @@ int ctsvc_client_phone_log_delete(contacts_h contact, contacts_phone_log_delete_
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               pims_ipc_data_destroy(indata);
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_handle(contact, indata);
index e2d5540..3ad2eaa 100644 (file)
@@ -124,8 +124,7 @@ API int contacts_setting_set_name_display_order(
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_int(name_display_order, indata);
@@ -170,8 +169,7 @@ API int contacts_setting_set_name_sorting_order(
        indata = pims_ipc_data_create(0);
        if (indata == NULL) {
                ERR("pims_ipc_data_create() Fail");
-               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-               return ret;
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
 
        ret = ctsvc_ipc_marshal_int(name_sorint_order, indata);
index 7d03797..6d5ac77 100644 (file)
@@ -74,6 +74,7 @@
 #define CTSVC_IPC_SERVER_PERSON_SET_FAVORITE_ORDER       "person_set_favorite_order"
 #define CTSVC_IPC_SERVER_PERSON_SET_DEFAULT_PROPERTY      "person_set_default_property"
 #define CTSVC_IPC_SERVER_PERSON_GET_DEFAULT_PROPERTY      "person_get_default_property"
+#define CTSVC_IPC_SERVER_PERSON_GET_AGGREGATION_SUGGESTIONS    "person_get_aggregation_suggestions"
 
 #define CTSVC_IPC_SERVER_PHONELOG_RESET_STATISTICS    "phonelog_reset_statistics"
 #define CTSVC_IPC_SERVER_PHONELOG_DELETE    "phonelog_delete"
index fb6a1de..6284f05 100644 (file)
@@ -637,26 +637,22 @@ int ctsvc_ipc_unmarshal_record_common(const pims_ipc_data_h ipc_data, ctsvc_reco
 
 int ctsvc_ipc_marshal_string(const char *bufchar, pims_ipc_data_h ipc_data)
 {
-       int ret = CONTACTS_ERROR_NONE;
-
        RETV_IF(NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER);
 
        if (bufchar) {
                int length = strlen(bufchar);
                if (pims_ipc_data_put(ipc_data, (void*)&length, sizeof(int)) != 0)
-                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
 
-               if (pims_ipc_data_put(ipc_data, (void*)bufchar, length+1) != 0) {
-                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
-                       return ret;
-               }
+               if (pims_ipc_data_put(ipc_data, (void*)bufchar, length+1) != 0)
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
        } else {
                int length = -1;
 
                if (pims_ipc_data_put(ipc_data, (void*)&length, sizeof(int)) != 0)
-                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
        }
-       return ret;
+       return CONTACTS_ERROR_NONE;
 }
 
 int ctsvc_ipc_marshal_int(const int in, pims_ipc_data_h ipc_data)
index 96edac5..e264c58 100644 (file)
@@ -235,6 +235,37 @@ int contacts_person_get_default_property(contacts_person_property_e property, in
         int *id);
 
 /**
+ * @brief Gets aggregation suggestions.
+ *
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+
+ * @remarks You must release @a record_list using contacts_list_destroy().
+ * @remarks This may take a long time. if you need to use it in bulk, make sure the user experience is acceptable  while running it.
+ *
+ * @param[in]   person_id               The person ID
+ * @param[in]   limit           The number to limit results(value 0 is used for get all records)
+ * @param[out]  record_list             The list of person records
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_person_get_aggregation_suggestions(int person_id, int limit, contacts_list_h *record_list);
+/**
  * @}
  */
 
index 1b45181..de047f8 100644 (file)
@@ -790,6 +790,81 @@ DATA_FREE:
        return;
 }
 
+void ctsvc_ipc_person_get_aggregation_suggestions(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int person_id = 0;
+       int limit = 0;
+       contacts_list_h list = NULL;
+       contacts_h contact = NULL;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_handle(indata, &contact);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       ERR("ctsvc_ipc_unmarshal_handle Fail(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &person_id);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       ERR("ctsvc_ipc_unmarshal_int() Fail(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &limit);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       ERR("ctsvc_ipc_unmarshal_int() Fail(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               ERR("ctsvc_ipc_person_get_aggregation_suggestions() Fail");
+               goto ERROR_RETURN;
+       }
+
+       if (!ctsvc_have_permission(ipc, CTSVC_PERMISSION_CONTACT_READ)) {
+               ret = CONTACTS_ERROR_PERMISSION_DENIED;
+               goto ERROR_RETURN;
+       }
+
+       ret = ctsvc_person_get_aggregation_suggestions(person_id, limit, &list);
+
+ERROR_RETURN:
+
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (NULL == *outdata) {
+                       ERR("pims_ipc_data_create() Fail");
+                       goto DATA_FREE;
+               }
+               if (CONTACTS_ERROR_NONE != ctsvc_ipc_marshal_int(ret, *outdata)) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       ERR("ctsvc_ipc_marshal_int() Fail");
+                       goto DATA_FREE;
+               }
+
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       DBG("no data");
+               }
+               else if (CONTACTS_ERROR_NONE == ret) {
+                       ret = ctsvc_ipc_marshal_list(list, *outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE) {
+                               ERR("ctsvc_ipc_marshal_list() Fail(%d)", ret);
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else {
+               ERR("outdata is NULL");
+       }
+DATA_FREE:
+       ctsvc_handle_destroy(contact);
+       contacts_list_destroy(list,true);
+       ctsvc_server_start_timeout();
+       return;
+}
+
 #ifdef ENABLE_LOG_FEATURE
 void ctsvc_ipc_phone_log_reset_statistics(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
 {
index 91716c5..c2a6aba 100644 (file)
@@ -35,6 +35,7 @@ void ctsvc_ipc_person_reset_usage(pims_ipc_h ipc, pims_ipc_data_h indata, pims_i
 void ctsvc_ipc_person_set_favorite_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
 void ctsvc_ipc_person_set_default_property(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
 void ctsvc_ipc_person_get_default_property(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_person_get_aggregation_suggestions(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
 
 #ifdef ENABLE_LOG_FEATURE
 void ctsvc_ipc_phone_log_reset_statistics(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
index ae541bf..7004132 100644 (file)
@@ -100,6 +100,7 @@ static int __server_main(void)
                if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_SET_FAVORITE_ORDER, ctsvc_ipc_person_set_favorite_order, NULL) != 0) break;
                if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_SET_DEFAULT_PROPERTY, ctsvc_ipc_person_set_default_property, NULL) != 0) break;
                if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_GET_DEFAULT_PROPERTY, ctsvc_ipc_person_get_default_property, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_GET_AGGREGATION_SUGGESTIONS, ctsvc_ipc_person_get_aggregation_suggestions, NULL) != 0) break;
 
 #ifdef ENABLE_LOG_FEATURE
                if (pims_ipc_svc_register(CTSVC_IPC_PHONELOG_MODULE, CTSVC_IPC_SERVER_PHONELOG_RESET_STATISTICS, ctsvc_ipc_phone_log_reset_statistics, NULL) != 0) break;
index 642d70d..7a504ec 100644 (file)
 #include "ctsvc_db_plugin_contact_helper.h"
 #include "ctsvc_db_access_control.h"
 #include "ctsvc_notify.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_server_setting.h"
+#include "ctsvc_list.h"
+#include "ctsvc_localize.h"
 
 #ifdef ENABLE_LOG_FEATURE
 #include "ctsvc_server_phonelog.h"
@@ -37,6 +41,9 @@
 #include "ctsvc_server_change_subject.h"
 #endif
 
+#define CTSVC_COMP_NAME_LEN 4
+#define CTSVC_AGGREGATION_SUGGESTION_SCORE 2
+
 enum {
        CTSVC_GET_PERSON_DEFAULT_NUMBER_VALUE,
        CTSVC_GET_PERSON_DEFAULT_EMAIL_VALUE,
@@ -1479,3 +1486,405 @@ int ctsvc_person_get_default_property(contacts_person_property_e property, int p
        return ret;
 }
 
+static void __ctsvc_collate_numbers(contacts_record_h record, GSList **nums)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       GList *cursor = NULL;
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       ctsvc_number_s *number_data;
+
+       if (NULL == contact->numbers) {
+               DBG("NULL == contact->numbers");
+               return;
+       }
+
+       for (cursor = contact->numbers->records; cursor; cursor = cursor->next) {
+               number_data = cursor->data;
+               if (number_data && number_data->normalized && number_data->normalized[0]) {
+                       char minmatch[strlen(number_data->normalized) + 1];
+                       ret = ctsvc_get_minmatch_number(number_data->normalized, minmatch, sizeof(minmatch),
+                                       ctsvc_get_phonenumber_min_match_digit());
+
+                       if (CONTACTS_ERROR_NONE != ret)
+                               continue;
+
+                       if (NULL == *nums || NULL == g_slist_find(*nums, minmatch))
+                               *nums = g_slist_append(*nums, strdup(minmatch));
+               }
+       }
+
+}
+
+static void __ctsvc_collate_emails(contacts_record_h record, GSList **emails)
+{
+       GList *cursor = NULL;
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       ctsvc_email_s *email_data;
+       int local_part_len = 0;
+       char local_part[256] = {0};
+
+       if (NULL == contact->emails) {
+               DBG("NULL == contact->emails");
+               return;
+       }
+
+       for (cursor = contact->emails->records; cursor; cursor = cursor->next) {
+               email_data = cursor->data;
+               if (email_data && email_data->email_addr && email_data->email_addr[0]) {
+                       local_part_len = strcspn(email_data->email_addr, "@");
+                       if (local_part_len <= 0 || strlen(email_data->email_addr) <= local_part_len)
+                               continue;
+
+                       strncpy(local_part, email_data->email_addr, local_part_len + 1);
+
+                       if (NULL == *emails || NULL == g_slist_find(*emails, local_part))
+                               *emails = g_slist_append(*emails, strdup(local_part));
+               }
+       }
+}
+
+static void __ctsvc_collate_names(contacts_record_h record, GSList **names)
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       int comp_name_len = CTSVC_COMP_NAME_LEN;
+       char comp_name[256] = {0};
+       char *name = NULL;
+
+       if (CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME == contact->display_source_type)
+               name = contact->reverse_sort_name;
+
+       if (name && comp_name_len <= strlen(name)) {
+               if (CTSVC_SORT_KOREAN == contact->display_name_language) { /*compare first name*/
+                       strncpy(comp_name, name + (strlen(name) -comp_name_len),
+                                               comp_name_len);
+                } else {  /*compare last name*/
+                       comp_name_len = strcspn(name, ", ");
+                       strncpy(comp_name, name, comp_name_len);
+                }
+
+               if (NULL == *names || NULL == g_slist_find(*names, comp_name))
+                       *names = g_slist_append(*names, strdup(comp_name));
+       }
+}
+
+
+static int __ctsvc_get_person_info_by_person_id(int person_id, GSList **nums, GSList **emails, GSList **names)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       GSList *contact_ids = NULL;
+       GSList *cursor = NULL;
+
+       char query[CTS_SQL_MIN_LEN] = {0};
+       cts_stmt stmt;
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                       "WHERE deleted = 0 AND person_id = %d", person_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
+
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               int contact_id = 0;
+
+               if (1 != ret) {
+                       ERR("ctsvc_stmt_step() Fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       return ret;
+               }
+               contact_id = ctsvc_stmt_get_int(stmt, 0);
+
+               contact_ids = g_slist_append(contact_ids, GINT_TO_POINTER(contact_id));
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       if (NULL == contact_ids) {
+               ERR("Fail to get contacts by person_id");
+               return CONTACTS_ERROR_DB;
+       }
+
+       for (cursor = contact_ids; cursor; cursor = cursor->next) {
+               contacts_record_h record = NULL;
+
+               int contact_id = GPOINTER_TO_INT(cursor->data);
+               ret = ctsvc_db_contact_get(contact_id, &record);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       WARN("ctsvc_db_contact_get() Fail(%d), contact_id = %d", ret, contact_id);
+                       continue;
+               }
+
+               __ctsvc_collate_numbers(record, nums);
+               __ctsvc_collate_emails(record, emails);
+               __ctsvc_collate_names(record, names);
+
+               contacts_record_destroy(record, true);
+       }
+
+       g_slist_free(contact_ids);
+
+       return ret;
+}
+
+static void __ctsvc_make_sub_query_by_num(GSList *nums, int person_id,
+               char **sub_query, int *sub_size, int *sub_len)
+{
+       GSList *cursor = NULL;
+       char temp_query[CTS_SQL_MIN_LEN] = {0};
+
+       /* Add 2 points whenever a number is matched */
+       snprintf(temp_query, CTS_SQL_MIN_LEN,
+                       "SELECT C.person_id, 2 score FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+                       "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 "
+                       "AND C.person_id <> %d AND D.is_my_profile = 0 "
+                       "WHERE D.data4 = '",
+                       CTSVC_DATA_NUMBER, person_id);
+
+       for (cursor = nums; cursor; cursor = cursor->next)
+       {
+               char *minmatch = cursor->data;
+               if (NULL == minmatch)
+                       continue;
+
+               if (*sub_len)
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, " UNION ALL ");
+
+               *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, temp_query);
+               *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, minmatch);
+               *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, "'");
+       }
+}
+
+static void __ctsvc_make_sub_query_by_email(GSList *emails, int person_id,
+               char **sub_query, int *sub_size, int *sub_len)
+{
+       GSList *cursor = NULL;
+       char temp_query[CTS_SQL_MIN_LEN] = {0};
+
+       /* Add 2 points whenever a email id is matched */
+       snprintf(temp_query, CTS_SQL_MIN_LEN,
+                       "SELECT C.person_id, 2 score FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+                       "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 "
+                       "AND C.person_id <> %d AND D.is_my_profile = 0 "
+                       "WHERE D.data3 LIKE '",
+                       CTSVC_DATA_EMAIL, person_id);
+
+       for (cursor = emails; cursor; cursor = cursor->next)
+       {
+               char *local_part = cursor->data;
+               if (NULL == local_part)
+                       continue;
+
+               if (*sub_len)
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, " UNION ALL ");
+
+               *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, temp_query);
+               *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, local_part);
+               *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, "%'");
+       }
+}
+
+static void __ctsvc_make_sub_query_by_name(GSList *names, int person_id,
+               char **sub_query, int *sub_size, int *sub_len)
+{
+       GSList *cursor = NULL;
+       char temp_query[CTS_SQL_MIN_LEN] = {0};
+
+       /* Add 1 point whenever last name is matched (first name in case of Korean) */
+       snprintf(temp_query, CTS_SQL_MIN_LEN,
+                       "SELECT person_id, 1 score FROM "CTS_TABLE_CONTACTS" "
+                       "WHERE person_id <> %d AND display_name_source=%d "
+                       "AND reverse_sort_name LIKE '",
+                       person_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
+
+       for (cursor = names; cursor; cursor = cursor->next)
+       {
+               char *name = cursor->data;
+               if (NULL == name)
+                       continue;
+
+               int sort_type = ctsvc_get_name_sort_type(name);
+
+               if (*sub_len)
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, " UNION ALL ");
+
+               *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, temp_query);
+               if (CTSVC_SORT_KOREAN == sort_type) {  /*compare first name*/
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, "%");
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, name);
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, "'");
+               } else {  /*compare last name*/
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, name);
+                       *sub_len += SAFE_SNPRINTF(sub_query, sub_size, *sub_len, "%'");
+               }
+       }
+}
+
+int ctsvc_person_get_aggregation_suggestions(int person_id, int limit, contacts_list_h *out_list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int id = 0;
+       int cnt = 0;
+       int score = 0;
+       GSList *nums = NULL;
+       GSList *emails = NULL;
+       GSList *names = NULL;
+       char *query = NULL;
+       char *sub_query = NULL;
+       int query_size = 0;
+       int sub_len = 0;
+       int sub_size = CTS_SQL_MAX_LEN;
+       contacts_list_h list = NULL;
+       cts_stmt stmt = NULL;
+
+       RETV_IF(person_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       CTS_FN_CALL;
+
+       ret = __ctsvc_get_person_info_by_person_id(person_id, &nums, &emails, &names);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ERR("__ctsvc_get_person_info_by_person_id() Fail(%d)", ret);
+               return ret;
+       }
+
+       sub_query = calloc(1, sub_size);
+       if (NULL == sub_query) {
+               ERR("calloc() Fail");
+               g_slist_free_full(nums, free);
+               g_slist_free_full(emails, free);
+               g_slist_free_full(names, free);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       if (nums) {
+                __ctsvc_make_sub_query_by_num(nums, person_id, &sub_query, &sub_size, &sub_len);
+                g_slist_free_full(nums, free);
+       }
+
+       if (emails) {
+               __ctsvc_make_sub_query_by_email(emails, person_id, &sub_query, &sub_size, &sub_len);
+               g_slist_free_full(emails, free);
+       }
+
+       if (names) {
+               __ctsvc_make_sub_query_by_name(names, person_id, &sub_query, &sub_size, &sub_len);
+               g_slist_free_full(names, free);
+       }
+
+       if (0 == sub_len) {
+               *out_list = NULL;
+               WARN("no numbers, emails, names for query");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       query_size = CTS_SQL_MIN_LEN + sub_len;
+       query = calloc(1, query_size);
+       if (NULL == query) {
+               ERR("calloc() Fail");
+               free(sub_query);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       snprintf(query, query_size,
+                       "SELECT person_id, sum(score) FROM (%s) "
+                       "GROUP BY person_id ORDER BY score DESC",
+                       sub_query);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               ERR("ctsvc_query_prepare fail(%d)", ret);
+               free(sub_query);
+               free(query);
+               return ret;
+       }
+
+       sub_len = 0;
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 != ret) {
+                       ERR("ctsvc_stmt_step() Fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       free(sub_query);
+                       free(query);
+                       return ret;
+               }
+               id = ctsvc_stmt_get_int(stmt, 0);
+               score = ctsvc_stmt_get_int(stmt, 1);
+               DBG("person_id : %d, score : %d", id, score);
+
+               /* Add 2 points whenever a email id or a number is matched */
+               /* and 1 point whenever some part of name is matched */
+               /* Aggregation suggestions: the persons who get more than 2 points */
+               if (CTSVC_AGGREGATION_SUGGESTION_SCORE <= score
+                       && (0 == limit || cnt < limit))
+               {
+                       cnt++;
+                       if (sub_len)
+                               sub_len += snprintf(sub_query + sub_len, sub_size -sub_len, ", %d", id);
+                       else
+                               sub_len += snprintf(sub_query + sub_len, sub_size -sub_len, "%d", id);
+               }
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       if (0 == sub_len) {
+               *out_list = NULL;
+               WARN("no person_id for aggregation suggestions");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       snprintf(query, query_size,
+                       "SELECT DISTINCT persons.person_id, "
+                       "%s, "
+                       "_NORMALIZE_INDEX_(%s), "
+                       "name_contact_id, "
+                       "persons.image_thumbnail_path, "
+                       "persons.ringtone_path, "
+                       "persons.vibration, "
+                       "persons.message_alert, "
+                       "status, "
+                       "link_count, "
+                       "addressbook_ids, "
+                       "persons.has_phonenumber, "
+                       "persons.has_email, "
+                       "EXISTS(SELECT person_id FROM "CTS_TABLE_FAVORITES" WHERE person_id=persons.person_id) is_favorite "
+                       "FROM "CTS_TABLE_PERSONS" "
+                       "LEFT JOIN "CTS_TABLE_CONTACTS" "
+                       "ON (name_contact_id = contacts.contact_id AND contacts.deleted = 0) "
+                       "WHERE persons.person_id IN (%s)",
+                       ctsvc_get_display_column(), ctsvc_get_sort_name_column(), sub_query);
+
+       free(sub_query);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       free(query);
+       if (NULL == stmt) {
+               ERR("ctsvc_query_prepare fail(%d)", ret);
+               return ret;
+       }
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       ERR("ctsvc_stmt_step() Fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ret = ctsvc_db_person_create_record_from_stmt(stmt, &record);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       ERR("ctsvc_db_person_create_record_from_stmt() Fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+
+       return ret;
+}
+
index 9951de7..084668b 100644 (file)
@@ -31,5 +31,5 @@ int ctsvc_person_reset_usage(int person_id, contacts_usage_type_e type);
 int ctsvc_person_set_favorite_order(int person_id, int front_person_id, int back_person_id);
 int ctsvc_person_set_default_property(contacts_person_property_e property, int person_id, int id);
 int ctsvc_person_get_default_property(contacts_person_property_e property, int person_id, int *id);
-
+int ctsvc_person_get_aggregation_suggestions(int person_id, int limit, contacts_list_h *out_list );
 #endif /* __CTSVC_SERVER_PERSON_H__ */